[Tex/LaTex] How to keep indentations in Python code copied from LaTeX PDF

indentationlistingspdfpython

I tried to include Python 3.6 code in a LaTeX PDF document which should be easily be copied to save to a file or to try the Python code.

Although,

\begin{verbatim}
for row in range(1,9):
    for col in range(1,9):
        print(int(str(row)+str(col)))
\end{verbatim}

shows nicely in the PDF but if I copy it and paste it to a text editor it looks like:

for row in range(1,9):
for col in range(1,9):
print(int(str(row)+str(col)))

The indentations which are essential for Python are gone.

I also tried the suggestion here using the listings package:

How to highlight Python syntax in LaTeX Listings \lstinputlistings command

where I can simply give the file name of an Python file
e.g.

\pythonexternal{Test.py}

And the source code will be included and colored.
But the same thing with the missing spaces at the start when copy&pasting.

If I use the option "showspaces=true"
I get the following:

for␣row␣in␣range(1,9):
␣␣␣␣for␣col␣in␣range(1,9):
␣␣␣␣␣␣␣␣print(int(str(row)+str(col)))

which is also not suitable for copy&paste. Well, I could replace all ␣ with space… not a really practicable solution.

There have been some weird hacks described in 2011 here:

How to make listings code indentation remain unchanged when copied from PDF?

Is there anything new since then…?
Any ideas how to achieve copy&paste Python code in a LaTeX PDF?
Thank you for suggestions.

Best Answer

One more solution that works well in both Acrobat Reader and Chrome, but is compatible with pdfTeX only (not XeTeX/LuaTeX):

\usepackage{transparent}
\makeatletter
\def\@xobeysp{\leavevmode\nobreak\texttransparent{0}{\char32}}
\makeatother

The \texttransparent is used to make ⎵ symbol invisible (actually, in some fonts the slot 32 is mapped onto the real space character, and this trick is not necessary, but the above code covers all cases).

Most likely, this code works because the generated file is not Unicode-based, and PDF viewer has no information about matching between code 32 and actual Unicode character, and so it copies it "as-is" as character code 32 (i.e. the space character). In favor of this hypothesis, there are failed XeTeX/LuaTeX-generated files and an attempt to set Unicode correspondence via /ActualText command (by replacing \char32 with \pdfliteral direct{/Span<</ActualText<FEFF0020>>> BDC}\char32\pdfliteral direct{EMC} in the above code).