LuaLaTeX for dummies: how to add LaTeX macros into \directlua?

First, you want to concatenate the value of the variable i with the token \hskip1cm, but the expression i\hskip1cm is not a valid lua expression. What you need is to make \hskip1cm a lua string and concatenate it with the value of i. That is:

tex.sprint(i .. "\hskip1cm")

This, however, won't work either because inside the quotes, the \ is a escape-char for lua, so \h will be interpreted as a escape sequence, and lua will complain that \h is an invalid escape sequence. So you have to "escape the escape":

tex.sprint(i .. "\\hskip1cm")

This would be ok for lua, but causes problems to TeX, since it makes \\ to appear inside a tex definition, and TeX tries to expand it, causing trouble.

You can avoid this trouble in two different ways:

First solution

This is the preferred one. Move your lua code to an external file. For example, create a file called mycommand.lua, which contains a lua function implementing your code:

-- mycommand.lua
function mycommand()
    for i = 1, 10 do
        tex.sprint(i .. "\\hskip1cm")
    end
end

Then, in your tex file, run the lua file (which defines that function and makes it available for lua), and define \mycommand to execute the function mycommand. This way:

\documentclass{article}
\directlua{dofile("mycommand.lua")}  % This defines the lua function mycommand()

\newcommand*{\mycommand}{\directlua{mycommand()}} % This defines the tex macro
\begin{document}
test \mycommand
\end{document}

Note that the expansion of \mycommand does not contain now any \\, so TeX is happy. When TeX expands \mycommand, this causes the function mycommand() to be executed, and this will "output" into the tex document the concatenation of i.."\\hskip1cm", which results into 1\hskip1cm2\hskip1cm3\hskip1cm etc, which is ok. The resulting pdf shows the intended result:

result

Second solution

This is uglier and in general not recommended. You can put any tex macro inside \luatexluaescapestring, and this will modify its expansion so that the result is a valid lua string. So, if you write for example "\luatexluaescapestring{\foo}" this will produce a complex string which contains the expansion of \foo, but wich each \ escaped as \\. Applying this to your example:

\documentclass{article}   
\newcommand*{\mycommand}{%
  \directlua{for i = 1, 10 do tex.sprint(i .. "\luatexluaescapestring{\hskip1cm}") end}
}
\begin{document}
test \mycommand
\end{document}

Note how you still require double quotes around it, to get a lua string which can be concatenated to the value of variable i.


For solution 1 above, to avoid backslash escape, I suggest to use the bracket version of lua string (the number of = characters can be any number provided you use the same twice) :

-- mycommand.lua
function mycommand()
    for i = 1, 10 do
        tex.sprint(i .. [===[\hskip1cm]===])
    end
end

If someone with enough reputation can reply this to the answer, please do so.

Tags:

Lua

Luatex