# xparse verbatim with newline

I'm trying to define a simple command using xparse and it's verbatim argument:

\DeclareDocumentCommand\macro{v}{#1}


but see

! LaTeX error: "xparse/verbatim-newline"
!
! Verbatim argument of \macrocode ended by end of line.
!
! See the LaTeX3 documentation for further information.
!
! For immediate help type H <return>.


when the argument is multiple lines of code (i.e., contains a new line):

\macro{This
Is
A
Test}


but it has no problem for something like

  \macro{This    Is    A    Test}


In my case, I need it to work with new lines.

Update:

\documentclass{book}
\usepackage{luatex,xparse}
\directlua{tex.enableprimitives('',tex.extraprimitives())}
\begin{document}

\DeclareDocumentCommand{\macro}{+v}{\directlua{print("\luaescapestring{#1}")}}
\DeclareDocumentCommand{\macroa}{+v}{#1}

\macro{
This
Is
A
Test
}

\macroa{
This
Is
A
Test
}

\end{document}


macro prints "ThisIsATest" without newlines. I need to print Exactly what is passed to the macro. macroa gives fi Thisfi Isfi Afi Testfi.

BTW, here is a MWE of it working but I want to "wrap" the behavior inside a macro for convenience:

\documentclass{book}
\usepackage{luatex}
\directlua{tex.enableprimitives('',tex.extraprimitives())}
\begin{document}

\endlinechar\^^J%
\catcode\^^M=13%
\directlua{print("\luaescapestring\expandafter{\detokenize{%
This
Is
A
Test
}}")}%
\catcode\^^M=5

\end{document}


EXCEPT Some random characters are output to the pdf (In my working example this doesn't happen because, I guess, I'm using a different font encoding).

• The LuaTeX part here is really nothing to do with xparse, as far as I can see. to me, it looks like it would make a better question separately. – Joseph Wright Sep 8 '12 at 22:01

You get the lines printed in the log file and no output in the PDF with this:

\documentclass{book}
\usepackage{luatex}
\directlua{tex.enableprimitives('',tex.extraprimitives())}

\def\myprint{%
\begingroup
\endlinechar\^^J%
\catcode\^^M=13%
\myprintaux}
\def\myprintaux#1#2{%
\directlua{print("\luaescapestring\expandafter{\detokenize{#1}}")}\endgroup}

\begin{document}

\myprint
{This
is
a
test
}

\end{document}


You need to use that form (the closing brace must be on a line of its own).

• Can you explain what the macro is doing? I'm a bit confused on why it does not print to the pdf. – AbstractDissonance Sep 8 '12 at 23:10
• @AbstractDissonance That's what I assumed from print and not tex.print – egreg Sep 8 '12 at 23:30
• Not sure if the catcode assignment is needed, since the end-line character is not ^^M but ^^J with your setting. – Bruno Le Floch Sep 8 '12 at 23:32
• @BrunoLeFloch Try without it – egreg Sep 8 '12 at 23:36
• What I'm trying to figure out is how you new to use the \begingroup and \endgroup and split the macro up into two parts like that. – AbstractDissonance Sep 9 '12 at 0:04

As covered in the xparse documentation, the v argument type is very similar to \verb, and has to be ended within a line. You can grab multiple lines using the 'long' indicator, +:

\DeclareDocumentCommand{\macro}{+v}{#1}


You should note that you will get

This^^MIs^^MA^^MTest


when you grab verbatim here (i.e. you get end-of-line tokens, not \par).

• Ok, using + stops the error but now I do not get end of lines at all. I'm printing out the argument to the console using lualatex and there are no new-lines in the statement. See my update: – AbstractDissonance Sep 8 '12 at 20:41
• @AbstractDissonance 'Works for me' with an up to date TL2012, but you don't need \detokenize here as you've already grabbed verbatim material. As I say in the answer, if you check the argument (using \showtokens) you will see the ^^M are there. – Joseph Wright Sep 8 '12 at 20:48
• Maybe this luaescapestring is messing with the newlines. But see my update for a working example that doesn't use a macro. Using your method I still do not get new lines but just extra spaces and fi for newlines. – AbstractDissonance Sep 8 '12 at 21:02
• @AbstractDissonance [not tested] Try adding \cs_generate_variant:Nn \tl_replace_all:Nnn { Nxx } somewhere before defining the macro, and instead of using #1 directly in your macro definition, you can start by replacing all ^^M by ^^J, for instance by storing in a variable \tl_set:Nn \l_tmpa_tl {#1}, replacing with \tl_replace_all:Nxx \l_tmpa_tl { \iow_char:N \^^M } { \iow_char:N \^^J } and using \l_tmpa_tl instead of #1 later on. Another option is to fiddle around with the values of \endlinechar and \newlinechar (try combinations with the values 10 and 13`). – Bruno Le Floch Sep 8 '12 at 23:35