Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

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?

share|improve this question
    
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 at 13:16
    
@Mico I want to know where they are in order to interpret the input string correctly. –  bastibe Jun 15 at 14:53

2 Answers 2

up vote 7 down vote accepted

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

share|improve this answer

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

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.