Tell me more ×
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.

After rendering a document containing this code block

\begin{verbatim}
if [ ! -d .git ]; then git init; fi         # Initialises a new Git repository, if doesn't already exist.
if [ ! -f README.md ]; touch README.md; fi  # Creates an empty README.md file,  if doesn't already exist.
git add -A                                  # Stages any files/directories present, in preparation to commit them to local Git repo.
git commit -m 'first commit'                # Commits the staged files/dirs to the local Git repo.
git remote add origin GIT_REMOTE_URL        # Adds the GitHub repo created above as a "Git remote" with the alias "origin".
\end{verbatim}

to PDF using pdflatex, and viewing the PDF in Apple's Preview application, the rendered code block looked exactly as expected:

if [ ! -d .git ]; then git init; fi         # Initialises a new Git repository, if doesn't already exist.
if [ ! -f README.md ]; touch README.md; fi  # Creates an empty README.md file,  if doesn't already exist.
git add -A                                  # Stages any files/directories present, in preparation to commit them to local Git repo.
git commit -m 'first commit'                # Commits the staged files/dirs to the local Git repo.
git remote add origin GIT_REMOTE_URL        # Adds the GitHub repo created above as a "Git remote" with the alias "origin".

However, I then tried copying and pasting the rendered code block from the PDF into a text file. I had been expecting the result to be exactly like the original, but instead it was as follows:

if[!-d.git];thengitinit;fi if [ ! -f README.md ]; touch README.md; fi git add -A git commit -m 'first commit' git remote add origin GIT_REMOTE_URL
# Initialises a # Creates an em # Stages any fi # Commits the s # Adds the GitH

Obviously, this is rather different to the original!

Using Acrobat Professional 8, the result is also wrong, but in a different way:

if [ ! -d .git ]; then git init; fi # Initialises a if [ ! -f README.md ]; touch README.md; fi # Creates an emgit add -A # Stages any figit commit -m 'first commit' # Commits the sgit remote add origin GIT_REMOTE_URL # Adds the GitHEN

My question is: is there a way to ensure that the original contents of every \begin{verbatim}...\end{verbatim} environment is preserved in the PDF output, not only as seen by the eye but also as "seen" by the text selection tools in PDF viewing software?

share|improve this question
It seems the "listings" package is similarly flawed. – sampablokuper Jul 4 '12 at 22:47
Apparently even with diligent attention to settings, the "listings" package still does not preserve all whitespace via copy/paste! Obviously I'm concerned with the "verbatim" environment rather than "listings", but if the latter can't do it then I wonder what hope there is for the less sophisticated former. – sampablokuper Jul 4 '12 at 23:38
Note once again the answers show the problem is essentially external to the code you showed, it depends on the current font size and page width. Please always provide full documents when posting a question. – David Carlisle Jul 5 '12 at 8:38
@DavidCarlisle, interesting point, and adds to my increasingly strong conviction that the "verbatim" environment is utterly misnamed! – sampablokuper Jul 5 '12 at 10:08
In that case the truncation of long lines is not done by verbatim, or even by tex, it is a feature of the viewer you are using not letting you select text that us in the pdf but outside the page area – David Carlisle Jul 5 '12 at 10:13
show 12 more comments

2 Answers

The contents of the verbatim environment is to wide for the page and the lines are truncated before the cr/lf. In the pdf file it ends up as one paragraph. Try the following with shorter lines and you will see that it is just fine

\documentclass{article}
\usepackage{verbatim}
\begin{document}
\begin{verbatim}
if [ ! -d .git ]; then git init; fi         #
if [ ! -f README.md ]; touch README.md; fi  #
git add -A                                  #
git commit -m 'first commit'                #
git remote add origin GIT_REMOTE_URL        #
\end{verbatim}
\end{document}

Another problem that is often overlooked when copying and pasting verbatim code is that the minus symbol "-" is sometimes not a character but a rule (depending on the font). To ensure that it is the right character, use the definition of the verbatim package to define your own verbfont for listings

\makeatletter
\newcommand*\verbfont{\normalfont\ttfamily
    \hyphenchar\font\m@ne
    \@noligs}
\makeatother

\usepackage{listings}
\lstset{basicstyle  = \verbfont}
share|improve this answer
Shortening the lines as you suggested doesn't solve the problem. As copied from Preview, the code ends up all on one line; and as copied from Acrobat Pro, newlines are preserved but every other bit of whitespace is replaced with a single space. I'm afraid I don't understand the relevance of your second point, since I'm not using the "listings" package. – sampablokuper Jul 5 '12 at 10:20
@sampablokuper: As far as I know does TeX not output a space character for spacing in pdf (or dvi?) but position words according to a coordinate. Therefor space chars are not available for copying. Regarding the second point about the \verbfont command; if you do not load the verbatim package your "-" chars can also dissapear during copying. In your original question (before editing it) you also mentioned "listings" – Danie Els Jul 5 '12 at 11:36
Danie Els, thanks, but unless I'm mistaken, I only mentioned "listings" in the comments below my question. As for the positioning, surely verbatim ought only to position the first character of the block by co-ordinates. To do anything else would be buggy and not "verbatim" at all. – sampablokuper Jul 5 '12 at 12:34
1  
@StephanLehmke my point is that other than using a monospaced font, LaTeX does not seem to be typesetting verbatim environments correctly. I.e. it is treating them as though various normal typesetting rules apply, when in fact they don't. My question can be restated as: is there a way to tell LaTeX to apply only appropriate typesetting rules to verbatim environments? – sampablokuper Jul 5 '12 at 17:39
1  
@DanieEls if I already knew how to do all that, I wouldn't be here asking how to do it :) – sampablokuper Jul 5 '12 at 19:02
show 4 more comments

Since you mentioned that page on on using the listings package with PDF tagging, I thought I'd mention that I'd had a little bit more luck with getting the spacing to work -- see my PDF. As others pointed out, you still need to make sure it doesn't break the hboxes (line length). In this case I've split up the comments and made the page landscape. The method below also works with file inclusion by using \lstinputlisting{script.txt} instead of \begin{lstlisting}.

Since I am still an amateur at this kind of LaTeX voodoo, it may be that someone can make some more improvements, but I've made sure this method works with all printable ASCII characters. There are a couple of things which are not perfect, but they may not be much of a problem, or they may not be particularly difficult to fix (by someone more experienced):

  • I didn't test it with the vast number of possible listings options, so I don't know if it plays nicely or not.
  • I went to quite some effort to ensure that all special printable ASCII characters were handled properly, but I can't make any promises.
  • Handling spacing was really painful, and in the end all I could do to get it working was to replace every two spaces with a small dot from textcomp which is displayed in the PDF (it still copies as space though!) and hope that it's not too distracting. It may be possible to put some colour formatting in there to make it vanish; I don't really know. The thing is, you're only really ever likely to see this for indented code; normal text doesn't tend to have two spaces in a row.
  • I hear you ask: Since it only replaces two spaces in a row, what happens to the other spaces? Well, since it replaces two spaces at a time, even numbers of spaces are no problem. What about single spaces though? Most single spaces are not replaced but are preserved fine in the output. The two cases they are not preserved are at the very end or beginning of a line. That is, a line which ends with an odd number of spaces will lose one at the end, and a line that begins with a single space (followed immediately by a printable character) will lose one at the start.
  • Edit: Oh, I forgot to mention; I didn't figure out a way to make it copy blank lines. It's still a lot better than no copy & paste though.

\documentclass{article}
\usepackage[landscape]{geometry}
\usepackage{listings}
\usepackage{textcomp}
\usepackage[space=true]{accsupp}

\newcommand{\pdfactualhex}[3]{\newcommand{#1}{%
\BeginAccSupp{method=hex,ActualText=#2}#3\EndAccSupp{}}}

\pdfactualhex{\pdfactualdspace}{2020}{\textperiodcentered\textperiodcentered}
\pdfactualhex{\pdfactualsquote}{27}{'}
\pdfactualhex{\pdfactualbtick}{60}{`}

\lstset{tabsize=4,basicstyle=\ttfamily,columns=flexible,emptylines=10000}
\lstset{literate={'}{\pdfactualsquote}1
                 {`}{\pdfactualbtick}1
                 {\ \ }{\pdfactualdspace}2
}

\begin{document}
\begin{lstlisting}
if [ ! -d .git ]; then git init; fi         # Initialises a new Git repository,
                                            # if doesn't already exist.

if [ ! -f README.md ]; touch README.md; fi  # Creates an empty README.md file,
                                            # if doesn't already exist.

git add -A                                  # Stages any files/directories
                                            # present, in preparation to commit
                                            # them to local Git repo.

git commit -m 'first commit'                # Commits the staged files/dirs
                                            # to the local Git repo.

git remote add origin GIT_REMOTE_URL        # Adds the GitHub repo created
                                            # above as a "Git remote" with the
                                            # alias "origin".
\end{lstlisting}
\end{document}

Here's a link to my PDF output: http://goo.gl/9Ds75

share|improve this answer
Thanks. This doesn't really answer my question, but it might help people who are using the "listings" package. – sampablokuper Jul 5 '12 at 12:37
The options I set above should make it pretty much exactly the same as the default verbatim package. – codebeard Jul 5 '12 at 12:40
One way or another, you're going to need to include some other packages if you want to make this work. – codebeard Jul 5 '12 at 12:42
Copying and pasting from your PDF (as viewed in Safari 5) to TextEdit yields a completely unusable result, I'm afraid. – sampablokuper Jul 5 '12 at 15:11
Works fine in my PDF viewer... How does it fare in Adobe? Do you have an example of a typeset code block which does copy and paste properly? – codebeard Jul 5 '12 at 21:50
show 1 more comment

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.