The following macro, which a full MWE can be found at Unmodified Source Code ,
\def\SourceCode{%
\begingroup%
\endlinechar`\^^J%
\catcode`\\=12\catcode`\^^M=12\catcode`\#=12\catcode`\~=12\catcode`\%=12\catcode`\^=12\catcode`\_=12\catcode`\@=12\catcode`\ =12\catcode`\|=12%
\SourceCodeAux}%
\def\SourceCodeAux#1#2{\endgroup\directlua{print("\luaescapestring{#1}")}}%
has the issue that the last terminating } cannot have anything else after it, on it's line:
\begin{itemize}
\item 2
\SourceCode{
{this
is
a
test}
}\end{itemize} % < This line is the problem, } \end{itemize} works but produces protected space in pdf.
will not work unless \end{itemize} is moved to the next line or a space is put between the } \end{itemize} (which then puts a protected space in the pdf)
The issue seems to be how the macro handles the last character but I don't quite understand what is going on. Is there any way to get the }\end{itemize} case to work?
I'm a bit confused on what the second argument for \def\SourceCodeAux#1#2 is doing. It is required but I'm not sure how it actually works. I've replaced it with other stuff and can get
}\end{itemize}to work but end up with protected spaces or other characters showing up in the pdf. My thinking is if I can insert a new-line into the stream right after the final}then TeX will see}\^^M\end{itemize}and allow it to work. Anyways, maybe someone can enlighten me on what exactly is going on.
here is how I see the macro:
Start new group to locally define catcodes(so the catcode modifications do not effect anything but what is in the macro)
Modify endlinechar and catcodes so that tokens after the macro call are not "Special"
Call an auxiliary macro that accepts two arguments. The first being will end up being the token stream(the source code argument "passed" to the original macro call). The second argument is then going to be the last token in the source code. (In the problem case happens to be a
\which gets picked up "accidently" and breaks the\end{itemize}(tex see's it asend{itemize})endgroup is called to return the catcodes back to normal then processing is done on the first "argument". (I'm not quite sure how the macro knows when to stop processing tokens though but I guess it has something to do with some trick using the #2 which is also what is causing the problem)
Here is a full MWE:
\documentclass{book}
\usepackage{luatex}
\directlua{tex.enableprimitives('',tex.extraprimitives())}
\begin{document}
\def\SourceCode{%
\begingroup%
\endlinechar`\^^J%
\catcode`\\=12\catcode`\^^M=12\catcode`\#=12\catcode`\~=12\catcode`\%=12\catcode`\^=12\catcode`\_=12\catcode`\@=12\catcode`\ =12\catcode`\|=12%
\SourceCodeAux}%
\def\SourceCodeAux#1#2{\endgroup\directlua{print("\luaescapestring{#1}")}}%
\begin{itemize}
\item 1
\SourceCode{
{this
is
a sucessful
test}
}
\end{itemize}
\iftrue
\begin{itemize}
\item 2
\SourceCode{
{this
is
a failed
test}
}\end{itemize}
\fi
\end{document}
{ }are not changed, so#1is the next argument (token or{..}). The#2might be just there to remove the space created by a line break, i.e. the macro is designed to have a line break (or space) after it. I guess that without it the line break (i.e. EOF-character) is placed verbatim in the document, which is not what you want. I remember having basically the same trouble programming a similar macro forydoc. Instead of#2use a macro which checks if the following character is EOL and discards it. – Martin Scharrer Sep 11 '12 at 06:03