Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I need to include a couple of Python code listings, where the indentation of the lines (using some number of spaces) is significant. I would like for the code listings to be copyable, so the spaces at the beginning of the line need to be be copied along with the text.

This question has been asked in various ways before (e.g. How to make listings code correct copyable from PDF and with hyperlink, or How can I make source code included with minted copyable?). Those questions focus on making line numbers uncopyable, though.

Making the spaces at the beginning of a line copyable seems to be harder: "I am not sure it is possible to specify in the PDF (at least in a viewer-independent way) that the indentation should be copied too" (CyberSingularity). At How to make listings code indentation remain unchanged when copied from PDF?, Philippe Goutet suggests a solution (turning the spaces into visible spaces, and coloring them in the background color so that they appear invisible) that works using Acrobat Reader, but not all readers. He says "It works under Acrobat Reader and it's extremely pleasant to be able to quickly copy/paste code without problem (perhaps the problem can be circumvented by writing direct PDF code to tell that it's a space, I've never had the time to try)".

Is it possible to produce a PDF with a code listing with copyable real spaces at the beginning of a line?

Minimal example: The line return x should start with four spaces.

\documentclass{article}

\begin{document}
\begin{verbatim}
def myfunction(x):
    return x
\end{verbatim}
\end{document}

I know that I could attach the code to the PDF as a file, but that's not what I want.

share|improve this question
1  
To add an example, my experiments have shown that simply converting to text using pdftotext produces a non-linear relationship between the number of spaces at the start of a line that TeX says there are and the number of spaces produced after pdftotext. It can also vary depending on the indentation of surrounding lines. When I looked at the PDF produced by TeX it appeared that spaces are not characters but are literally gaps so it is up to the viewer to interpret them as a given number of characters. –  Loop Space Dec 3 '13 at 12:40
1  
This seems to be a viewer issue rather than pdf itself, I find if I cut your example from xpdf the spaces are preserved, but they go from acrobat. I think basically you need to use \char32 rather than ` ` so that TeX puts in a character rather than its inter-word skip then you need a character from some font (any font) that looks white but that acrobat doesn't drop. I failed in that last bit, without using explicit color, any I either see a visible character or actobat drops it on copy. \makeatletter\def\@xobeysp{\textcolor{white}{\char32}}\makeatother works for me in xpdf and acrobat –  David Carlisle Dec 3 '13 at 15:02
1  
@DavidCarlisle If I use your trick on Jake's example, compile the code, copy the output from Mac Preview, and then paste it in MacVim, I get visible-space characters instead of spaces. –  Jubobs Dec 3 '13 at 17:42
    
I typically just attach the code as an attachment. I use ConTeXt, but I believe that there are LaTeX packages for attachment, and it should be possible to interface them with the verbatim environment –  Aditya Dec 3 '13 at 18:35
1  
As a (discouraging) side note, I just tried to copy some code from some Adobe API manual. Same problem: indentation is lost :-( So if they can't get it right, maybe nobody can? (same on Lunix and Windows with acrobat professional) –  Stephan Lehmke Dec 6 '13 at 11:57
show 7 more comments

2 Answers

(it seems this works everywhere apart from acrobat reader)

This is based on the example by @DavidCarlisle.

The cmtt visible space character seems to be labelled differently in different cmtt variants. For cm-super (which is loaded here when I use \usepackage[T1]{fontenc}), the respective character is named uni2423 which seems to cause problems with evince when copying that character.

So I rigorously defined everything which looks like space to a non-break space.

You might want to restrict this to verbatim ;-)

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{color}
\input{glyphtounicode}
\pdfglyphtounicode{visiblespace}{A0}
\pdfglyphtounicode{blank}{A0}
\pdfglyphtounicode{visualspace}{A0}
\pdfglyphtounicode{uni2423}{A0}
\pdfgentounicode=1
\begin{document}\showoutput
\makeatletter
\def\@xobeysp{\textcolor{white}{\char32}}
\makeatother
\begin{verbatim}
def myfunction(x):
    return x
\end{verbatim}
\end{document}

I am inclined to consider the fact that apparently no (consecutive or beginning-of-line) spaces can be copied from Acrobat a bug.

Or is this specified anywhere?

At least it's completely the same with official Adobe documents like the PDF Reference.

So I consider this answer valid no matter what :-)

share|improve this answer
    
Ah, that looks great, but unfortunately, Acrobat Reader seems to copy the actual U+3000 instead of U+0020, which breaks the copied code... –  Jake Dec 6 '13 at 10:49
    
@Jake That's a pity. In that case I'm out of ideas, as using 20 or A0 leads to nothing at all being copied :-( –  Stephan Lehmke Dec 6 '13 at 10:50
1  
for me xpdf drops all spaces and acrobat reader puts in U+3000 so it looks OK but doesn't work in code. –  David Carlisle Dec 6 '13 at 10:51
1  
This is really tough. acroread seems to strictly refuse to copy anything which is even remotely a space character :-( –  Stephan Lehmke Dec 6 '13 at 11:43
2  
@Jubobs This shouldn't be much of a problem. verbatim puts \null in a blank line; one would only need to add some character here. But it's incredible acroread can't be convinced to copy spaces at all :-( –  Stephan Lehmke Dec 6 '13 at 11:45
show 5 more comments

The following doesn't work in evince, see the discussion in comments below

As noted in comments I suspect using colour is the most reliable way:

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{color}
\begin{document}\showoutput
\makeatletter
\def\@xobeysp{\textcolor{white}{\char32}}
\makeatother
\begin{verbatim}
def myfunction(x):
    return x
\end{verbatim}
\end{document}

If I process with pdflatex and cut from acrobat I get:

def myfunction(x):
    return x
share|improve this answer
    
For me, that works with Acrobat, but not with Evince. Evince gives me instead of spaces... –  Jake Dec 4 '13 at 8:06
    
@Jake surprising. The interesting question though (which I asked in the comments on the question without reply) is is it U+0020 and your editor has "helpfully" put the text in cmtt which has a _ glyph in the space slot, or is it U+2423 in which case something has added a mapping to that character (presumably in the font itself, since cmap package not loaded, but in any case it could be tracked down if you could say what it is. From acrobat and xpdf I get space characters U+0020 for the indentation. –  David Carlisle Dec 4 '13 at 10:01
2  
@Jake I installed evince on windows and can confirm I give up I can't make it work in evince. Other readers don't see the unicode mapping in the font so add a real space, so it works, evince is too clever for its own good. If you give it a character with a real space but from a font without the map to U+2423, it drops it on copy, if you give it a non space character coloured white, it drops the colour on copy. I could delete my answer as basically it is just what you said didn't work, but perhaps it's best to leave it in case anyone wants to have any better ideas. I'll make it cw as no answer –  David Carlisle Dec 4 '13 at 15:00
1  
btw, I see this as caused by the \usepackage[T1]{fontenc} above. For me, that loads cm super fonts, and if I open the tt font in fontforge, I get that character labeled as "uni2423", so possibly that's where evince is taking it from... Funnily, if I say \pdfgentounicode=1, then acroread also copies to U+2423 –  Stephan Lehmke Dec 6 '13 at 10:35
1  
@Jubobs from okular too (on an old Fedora 13) the pasted character in emacs is the U+2423 –  jfbu May 15 at 16:35
show 10 more comments

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.