51

I was just wonder if it would be possible to have a "Copy to Clipboard Button" next to each listing which would just copy the verbatim content of the lstlistings environment to the clipboard.

An acroread-only solution would suffice for my purposes.

arney
  • 2,023
  • This would be amazing, and I'm sure it can be done, too, using some pdfTeX-foo. – Sean Allred Jun 05 '13 at 19:19
  • 2
    What I have done in the past is to make the line numbers not selectable in pdf, so that you can select/cut/paste the code only. if this is an acceptable solution I can provide an answer – ArTourter Jun 05 '13 at 20:05
  • 3
    @ArTourter That solution is here already. It's neat, but still the user has to ensure that he selected everything and you know how it goes: One false move and your three pages from where you started... – arney Jun 06 '13 at 06:29
  • Wonderful. I was going to ask this today and see that you asked same today! – Real Dreams Jun 06 '13 at 07:29
  • 7
    Another way of doing it is using the attachfile package. in that case the user would be able to save the source to file as opposed to copy it to the clipboard. Note that the text to be attached has to come from a separate file though. – ArTourter Jun 06 '13 at 12:31
  • It seems that the set of actions that a pdf button can achieve is limited, unless you use Javascript (which the user must enable on a document-wise basis). The best list I could find is rather short, and it appears that you will need to work with JavaScript to achieve your goal. – Bruno Le Floch Jul 09 '13 at 03:50
  • @BrunoLeFloch Yes, I tried a little at that and would encorage anyone to propose code snipets here. Still, the collect@body problem needs ro be solved, i.e. make TeX read the content of the environement into a temporary variable. The latter is a brainfuck everytime you need it, especially respecting encodings and linebreaks. – arney Jul 10 '13 at 11:30
  • Does listings offer any means to get at the verbatim content of the environment? I just skimmed the code and didn't find any obvious place where a line of code is stored before processing (or whatever unit listings is reading the code in). – Stephan Lehmke Nov 18 '13 at 15:56
  • @StephanLehmke That's not the biggy: I would suggest to use external files and then just adjust the ´\lstinputlisting{filename}´ command. Also, one could try to manipulate the environment using environ or reading along with a Lua callback. – arney Nov 18 '13 at 21:56

1 Answers1

27

Ok, here are two approaches, both of which not perfect, both of which not 100% what was requested. But maybe together we can optimise them :-)

\documentclass{article}

\usepackage{listings}
\usepackage{attachfile}
\usepackage{accsupp}
\usepackage{verbatim}
\usepackage{color}
\usepackage[misc]{ifsym}

\definecolor{lstbgcolor}{rgb}{0.9,0.9,0.9} 

\makeatletter
\lst@RequireAspects{writefile}

% Use \attachfile command to add listing content as paperclip.
\lstnewenvironment{attachedlisting}{%
  \lst@BeginAlsoWriteFile{\jobname.lsttmp}%
}
{%
  \lst@EndWriteFile
  \marginpar{\attachfile[appearance=false,icon=Paperclip,mimetype=text/tex]{\jobname.lsttmp}}
}

% Use accsupp package to add listing content as copyable text.
\lstnewenvironment{copyablelisting}{%
  \lst@BeginAlsoWriteFile{\jobname.lsttmp}%
}
{%
  \lst@EndWriteFile
  \let\verbatim@processline\add@lstline
  \global\let\lstfile\empty
  \verbatiminput{\jobname.lsttmp}%
  \marginpar{(\BeginAccSupp{method=escape,ActualText={\lstfile}}\PaperPortrait\EndAccSupp{})}
}
\def\add@lstline
{\xdef\lstfile{\unexpanded\expandafter{\lstfile}\the\verbatim@line\string^^J}}
\makeatother

\begin{document}

  \lstset{breakatwhitespace=true,breaklines=true,language=[LaTeX]TeX,basicstyle=\small\ttfamily,flexiblecolumns,backgroundcolor=\color{lstbgcolor}}

  \begin{attachedlisting}
    \documentclass{article}
    \title{Cartesian closed categories and the price of eggs}
    \author{Jane Doe}
    \date{September 1994}
    \begin{document}
      \maketitle
      Hello world!
    \end{document}
  \end{attachedlisting}

  \begin{copyablelisting}
    \documentclass{article}
    \title{Cartesian closed categories and the price of eggs}
    \author{Jane Doe}
    \date{September 1994}
    \begin{document}
      \maketitle
      Hello world!
    \end{document}
  \end{copyablelisting}

\end{document}

enter image description here

The first environment, attachedlisting displays a paper clip which allows to open the listing contents in an editor (or save to file).

The second environment, copyablelisting displays a symbol which, when copied, will paste to the listing contents.

Open Issues

  1. Placement of symbols: As the listings environment needs to be ended before the file is completely written, the placement of the "target symbol" is a problem. To get it to the top, probably two runs would be neccessary.
  2. Copy Symbol: I wasn't able to make a single character which will paste to the listing content. Somehow this trick won't work if the "copy symbol" is not surrounded by at least one "normal" character on both sides and those are also copied. Hence, at the moment, you'll get two superfluous characters before and after the listing text. I also wasn't able to make them "invisible" somehow.

So this is as good as I can make it for the time being. I'm open to suggestions of course.

  • Well, kudos to you for digging deep – arney Nov 26 '13 at 23:41
  • 1
    What about if you already have the file, include it using \lstinputlisting but want to include the possibility for coping the text like the copyablelisting example, how can I do that? – Jens Boldsen Aug 31 '17 at 10:14