76

A PDF output is obtained by compiling the following code.

\documentclass{article}
\usepackage{xcolor}
\usepackage{listings}

\lstset { language={[LaTeX]TeX}, numbers=left, numbersep=1em, numberstyle=\tiny, frame=single, framesep=\fboxsep, framerule=\fboxrule, rulecolor=\color{red}, xleftmargin=\dimexpr\fboxsep+\fboxrule\relax, xrightmargin=\dimexpr\fboxsep+\fboxrule\relax, breaklines=true, basicstyle=\small\tt, keywordstyle=\color{blue}, commentstyle=\color[rgb]{0.13,0.54,0.13}, backgroundcolor=\color{yellow!10}, tabsize=2, columns=flexible, morekeywords={maketitle}, }

\begin{document}

\begin{lstlisting} \documentclass{article} \usepackage{listings} \title{Sample Document} \author{John Smith} \date{\today} \begin{document} \maketitle Hello World! % This is a comment. \end{document} \end{lstlisting}

\end{document}

I attempted to copy the code only inside Acrobat Reader. Unfortunately, the line numbers also got copied as shown on the following screen shot.

enter image description here

The line numbers are useful, but readers want not to copy them.

Is there a LaTeX trick to prevent a PDF viewer from copying the line number?

4 Answers4

66

This solution is very similar to that contained in How to make text copy in PDF previewers ignore lineno line numbers? \protecting the accsupp is the only requirement, perhaps due to the nature in which listings treats everything:

enter image description here

\documentclass{article}
\usepackage{xcolor}% http://ctan.org/pkg/xcolor
\usepackage{listings}% http://ctan.org/pkg/listings
\usepackage{accsupp}% http://ctan.org/pkg/accsupp
\renewcommand{\thelstnumber}{% Line number printing mechanism
  \protect\BeginAccSupp{ActualText={}}\arabic{lstnumber}\protect\EndAccSupp{}%
}
\lstset
{
    language={[LaTeX]TeX},
        numbers=left,
        numbersep=1em,
        numberstyle=\tiny,
    frame=single,
    framesep=\fboxsep,
    framerule=\fboxrule,
    rulecolor=\color{red},
    xleftmargin=\dimexpr\fboxsep+\fboxrule\relax,
    xrightmargin=\dimexpr\fboxsep+\fboxrule\relax,
    breaklines=true,
    basicstyle=\small\tt,
    keywordstyle=\color{blue},
    commentstyle=\color[rgb]{0.13,0.54,0.13},
    backgroundcolor=\color{yellow!10},
    tabsize=2,
    columns=flexible,
    morekeywords={maketitle},
}

\begin{document}

\begin{lstlisting}
\documentclass{article}
\usepackage{listings}
\title{Sample Document}
\author{John Smith}
\date{\today}
\begin{document}
\maketitle
Hello World!
% This is a comment.
\end{document}
\end{lstlisting}

\end{document}
Werner
  • 603,163
35

Due to problems that came to light in the first answer when loading also the hyperref package, a related question was asked (How do I prevent conflicts between accsupp and hyperref?). The following solution is based on Ulrike Fischer's answer to that question, and illustrates one other advantage of this solution (as pointed out by Heiko Oberdiek) even if hyperref package is not involved: line numbers in references can be copied.

\documentclass{article}
\usepackage{xcolor}% http://ctan.org/pkg/xcolor

\usepackage{accsupp}% http://ctan.org/pkg/accsupp
\newcommand{\emptyaccsupp}[1]{\BeginAccSupp{ActualText={}}#1\EndAccSupp{}}

\usepackage{listings}% http://ctan.org/pkg/listings
\lstset
{
    language={[LaTeX]TeX},
    numbers=left,
    numbersep=1em,
    numberstyle=\tiny\emptyaccsupp,
    frame=single,
    framesep=\fboxsep,
    framerule=\fboxrule,
    rulecolor=\color{red},
    xleftmargin=\dimexpr\fboxsep+\fboxrule\relax,
    xrightmargin=\dimexpr\fboxsep+\fboxrule\relax,
    breaklines=true,
    basicstyle=\small\tt,
    keywordstyle=\color{blue},
    commentstyle=\color[rgb]{0.13,0.54,0.13},
    backgroundcolor=\color{yellow!10},
    tabsize=2,
    columns=flexible,
    morekeywords={maketitle},
    escapeinside={\%LISTING:}{\^^M},
}

\usepackage{hyperref}

\begin{document}

\begin{lstlisting}
\documentclass{article}
\usepackage{listings}
\title{Sample Document}
\author{John Smith}
\date{\today}
\begin{document}
\maketitle %LISTING:\label{title}
Hello World!
% This is a comment.
\end{document}
\end{lstlisting}

Line \ref{title} shows the title.

\end{document}

Output of the listing showing selection

I deliberately set this answer to community wiki to prevent me from getting reputation points.

  • In the production, I use this answer because hyperref can be loaded with no problem. – kiss my armpit May 24 '12 at 09:47
  • I took the liberty of editing your CW answer to make the advantages of this solution more obvious without having to click through to the follow up question. Hope you don't mind. – cyberSingularity Dec 15 '12 at 11:33
  • This method (as well as the accepted answer) does not seem to work on Google Chrome, but it does work like a charm on Adobe Acrobat. – Francisco Escobar Oct 19 '18 at 18:44
  • 1
    Worth noting that while \tiny can be anywhere (as it takes no argument), \emptyaccsupp must be at the end of \numberstyle. – user202729 Mar 24 '23 at 12:54
11

This answer only deals with latex/dvips/ps2pdf.

Package accsupp works well with dvips. The generated PostScript file contains the right pdfmark operators. However ghostscript (version 9.05) has not implemented these tags, from the source file gdevpdfm.c:

/* [ tag propdict /BDC pdfmark */
static int
pdfmark_BDC(gx_device_pdf *pdev, gs_param_string *pairs, uint count,
            const gs_matrix *pctm, const gs_param_string *objname)
{
    return 0;                   /****** NOT IMPLEMENTED YET ******/
}

/* [ /EMC pdfmark / static int pdfmark_EMC(gx_device_pdf pdev, gs_param_string pairs, uint count, const gs_matrix pctm, const gs_param_string objname) { return 0; /***** NOT IMPLEMENTED YET ******/ }

Solution sketch:

If the line number is not text, then it cannot be copied. Thus a solution would be to use bitmap images. For each digit and variant (color, size, …) a bitmap needs to be generated. As image format BMP can be used, that is supported by dvips. Then \thelstnumber is redefined to use these images for its digits.

Heiko Oberdiek
  • 271,626
1

This is an alternative. Numbers are still typesetted as usual, but instead of typesetting it before each line is typesetted, all line numbers are typesetted after the whole code block is typesetted.

If the PDF viewer respect the "text order" in the PDF, it should work fine.

Needs 2 compilation passes.

\documentclass{article}
\usepackage{xcolor}
\usepackage{tikz}
\usepackage{etoolbox}
\usepackage{listings}
\usepackage{hyperref}

\begin{document}

\NewDocumentCommand\fakeTypesetLineNumber{m}{% \tikz[remember picture] \coordinate (line\the\value{lstnumber});% remember this location % -- \tiny\phantom{#1}% leave space equal to the line number itself % \tiny must be outside any group so that it applies to the following \kern % -- \xappto\typesetPendingLineNumbers{\actualTypesetLineNumber{\the\value{lstnumber}}}% remember to typeset it later }

% this command must be robust because it's used inside \xappto \NewDocumentCommand\actualTypesetLineNumber{m}{% \node [anchor=south west, inner sep=0pt] at (line#1){\normalfont\tiny#1};% actually typeset it now, need to copy the \tiny here }

\AddToHook{env/lstlisting/begin}{% \gdef\typesetPendingLineNumbers{}% }

\AddToHook{env/lstlisting/end}{% \begin{tikzpicture}[remember picture, overlay]% \typesetPendingLineNumbers \end{tikzpicture}% }

\lstset { language={[LaTeX]TeX}, numbers=left, numbersep=1em, numberstyle=\fakeTypesetLineNumber, frame=single, framesep=\fboxsep, framerule=\fboxrule, rulecolor=\color{red}, xleftmargin=\dimexpr\fboxsep+\fboxrule\relax, xrightmargin=\dimexpr\fboxsep+\fboxrule\relax, breaklines=true, basicstyle=\small\tt, keywordstyle=\color{blue}, commentstyle=\color[rgb]{0.13,0.54,0.13}, backgroundcolor=\color{yellow!10}, tabsize=2, columns=flexible, morekeywords={maketitle}, escapeinside={%LISTING:}{^^M}, }

\begin{lstlisting} \documentclass{article} \usepackage{listings} \title{Sample Document} \author{John Smith} \date{\today} \begin{document} \maketitle %LISTING:\label{title} Hello World! % This is a comment. \end{document} \end{lstlisting} Line \ref{title} shows the title.

\lstset{ numberstyle=\tiny }

\begin{lstlisting} \documentclass{article} \usepackage{listings} \title{Sample Document} \author{John Smith} \date{\today} \begin{document} \maketitle %LISTING:\label{title2} Hello World! % This is a comment. \end{document} \end{lstlisting}

\end{document}

Of course, this will fail silently for code blocks that span across more than one page.

user202729
  • 7,143