9

I want to write a Lua function that processes some multi-line string.

Thus, I created a new file test.lua which contains

userdata = userdata or {}
function userdata.surroundwithdashes(str)
  str = str:gsub("\n", " (linebreak)\\\\ ")
  tex.print("--" .. str .. "--")
end

and added \directlua{dofile('test.lua')} to my latex preamble. To call that function, I created a macro \newcommand{\dash}[1]{\directlua{userdata.surroundwithdashes([[#1]])}}.

This works well for regular text like

\dash{This is some test text}

However, It does not recognize line breaks

\dash{This is some test text
      with more than one line}

And throws errors (undefined control sequence) if I insert them manually

\dash{This is some test text \\
      with more than one line}

Also, this produces an additional "m" after the "TeX" for

\dash{This is some \TeX text}

How can I parse the input string reliably and detect newlines in it?

2
  • It's not clear to me what the concern is with potential line breaks in a string: Do you want to eliminate them, do you want to preserve them, or something entirely different? Please clarify.
    – Mico
    Jun 15, 2014 at 13:16
  • @Mico I want to know where they are in order to interpret the input string correctly.
    – bastibe
    Jun 15, 2014 at 14:53

2 Answers 2

10

The \\ gets expanded before it is passed to the Lua function userdata.surroundwithbraces. Because the expansion is an expansion like \edef and not LaTeX's \protected@edef, macro \\ breaks.

Expansion can be prevented by e-TeX's \detokenize.

Also I prefer \luaescapestring (or LuaLaTeX's \luatexluaescapestring) for passing string arguments, because the primitive takes care of the necessary escapings:

\RequirePackage{filecontents}
\begin{filecontents*}{dash.lua}
userdata = userdata or {}
function userdata.surroundwithdashes(str)  
  str = str:gsub("\n", " (linebreak)\\\\ ")
  tex.print("--" .. str .. "--")
end
\end{filecontents*}
\directlua{dofile('dash.lua')}

\documentclass{article}

\newcommand*{\dash}[1]{%
  \directlua{userdata.surroundwithdashes(%
    "\luatexluaescapestring{\detokenize{#1}}")}%
}

\begin{document}
  \dash{This is some test text}

  \dash{This is some test text \\
    with more than one line}
\end{document}

Result

2

except within verbatim or obeylines etc end of line is reported to the macro layer as a space (or as \par if a blank line) so the macro \dash has an argument with a single space token between text and with

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .