6

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 08 '12 at 22:01

2 Answers2

4

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).

egreg
  • 1,121,712
3

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).

Joseph Wright
  • 259,911
  • 34
  • 706
  • 1,036
  • 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 08 '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 08 '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 08 '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 08 '12 at 23:35