Printing LaTeX code in LuaTeX

Another option is to use the luacode package and its luacode* environment, which doesn't expand as well:

\documentclass{article}
\usepackage{array,longtable}
\usepackage{luacode}
\begin{luacode*}
  function mymulticol()
    tex.sprint([[\multicolumn{3}{l}{1}&\bf 2]])
  end
\end{luacode*}
\begin{document}

\begin{longtable}{p{8cm}rrr}
\textbf{1}&2é&3&4\\ \hline\\
\multicolumn{3}{l}{1}&\bf 2\\
\multicolumn{3}{l}{1}&\bf 2\\
\directlua{mymulticol()}
\end{longtable}

\end{document}

In general you should only have simple function calls in \directlua, complex code is harder to maintain due to expansion issues and the mixture of Lua and TeX code. For longer pieces of Lua code, it is best to place them in a dedicated file (possibly as a LuaTeXBase module).


To explain why such issues arise, consider that \directlua does two things: first it expands its argument like writing to a file would, second it interprets the expansion as Lua code. Both steps have to succeed and produce meaningful results. As a simple example, we try to print \TeX (giving the TeX logo) from Lua. \directlua{tex.sprint(\TeX)} expands the \TeX command, leading to garbage on the Lua side. \directlua{tex.sprint(\noexpand\TeX)} prevents the expansion so that Lua sees tex.sprint(\TeX), which is still invalid Lua code because Lua expects a string. The next refinement \directlua{tex.sprint("\noexpand\TeX")} at least causes no compilation errors, but still does not give the desired result: Lua sees tex.sprint("\TeX") and tries to interpret the backslash escape (in this case the backslash is removed because \T is not a valid escape sequence). Only if we suppress backslash escape interpretation with \directlua{tex.sprint([[\noexpand\TeX]])} the code works as expected. Note that in this case we had to suppress both TeX expansion and Lua's escape character to get the desired result.


\directlua fully expands its arguments. So you need to ensure that the output of tex.print is equal to what you would have typed directly in the file. For example instead of

\directlua{tex.print("\multicolumn{3}{l}{1}&\bf 2")}

use

\directlua{tex.print("\string\\multicolumn{3}{l}{1}&\string\\bf 2")}

What you need to watch is expansion. Both \directlua as well as luacode fully expand their arguments. Escaping with "" normally works. There is also \luastringescape but I had problems using it as well. For large blocks rather use \directlua { dofile('mysetups.lua')}, see the manual page 18.

\documentclass{article}
 \usepackage[utf8]{luainputenc}
 \begin{document}

 \def\name{Yiannis}
 \begin{luacode}
 function Test(name)
     tex.print{name}
 end
 Test("\name")
 \end{luacode}

 \directlua{tex.sprint(Test("\name"))}
 \end{document}

Tags:

Luatex