Copy-pastable listings in PDF from LaTeX

by Martin Monperrus
This document presents how to obtain copy-pastable listings from LaTeX. It uses the listings and accsupp packages (recent version).

The technique relies on:
* the listings option columns=fullflexible in order not to insert superfluous spaces
* the listings option literate to map characters to their exact ASCII counterparts.
* the package accsupp to get some magic done between Unicode and ASCII spaces in order to preserve indentation (this is essential in some cases, for instance to copy-paste Python code)

Here is a simple ASCII example that is completely copyable with Ctrl-C in a PDF viewer (evince, xpdf, acrobat reader, etc.) or with pdftotext. The resulting copied string is equal to the one in LaTeX source:

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{textcomp}
\usepackage{listings}
\lstset{ 
upquote=true,
columns=fullflexible,
basicstyle=\ttfamily,
literate={*}{{\char42}}1
         {-}{{\char45}}1
         {\ }{{\copyablespace}}1
}

\usepackage[space=true]{accsupp}
\newcommand{\copyablespace}{\BeginAccSupp{method=hex,unicode,ActualText=00A0}\hphantom{x}\EndAccSupp{}}

\begin{document} 

\pagestyle{empty}
\begin{lstlisting}
# 0123456789abcdefghijklmnopqrstuvwxyz
# ABCDEFGHIJKLMNOPQRSTUVWXYZ!"#$%&\'()*+,-./:;<=>?@[]^_`{|}~
# 
for i in range(1,2):
  print(i)
\end{lstlisting}

\end{document}

 

Readers

With pdftotext, this results in a perfectly preserved output (preserved space, preserved indentation, using option `-layout`: `pdftotext -layout input.pdf -`

For some readers, this solution does not preserve indentation on Sep 2020, see https://tex.stackexchange.com/questions/563803/how-make-a-latex-document-that-generates-a-pdf-from-which-copy-paste-works-corre and https://github.com/ho-tex/accsupp/issues/1

See also:
Producing searchable and copyable pdf files with accents using latex-pdflatex
Copy-pastable ASCII characters with pdftex/pdflatex


Tagged as: