12

A calculation is done in Lua, and according to the result a certain type of cell must display the data.

This works:

\multicolumn{3}{p{11cm}}{Test}&-10\\[0.4cm]

But this doesn't

\directlua{tex.print(\multicolumn{3}{p{11cm}}{Test}&-10\\[0.4cm])}

with the following error message:

! Undefined control sequence.
\@setfontsize ...b ####1<#2}\@tempa >##2<##3\@nil 
                                                  {\def \bright@baselineskip...

What is the right way to print LaTeX code in directlua ?

Here is a minimal example:

\documentclass{article}
\usepackage{array,longtable}
\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{tex.print("\multicolumn{3}{l}{1}&\bf 2")}
%\directlua{dofile('test.lua')}
\end{longtable}

\end{document}
  • 2
    Please don't post something like "this doesn't work" here without any explanation. What happens exactly? Does an error message appear and if yes which one? Etc.etc. – Martin Scharrer Apr 17 '11 at 18:46
  • 1
    One problem seems to be that the code in \directlua{tex.print(...)} is expanded like in an \edef. Adding \noexpand before all macros removes the first error Incomplete \iffalse but then gives LuaTeX error <\directlua >:1: unexpected symbol near '\'. I don't know LuaTeX enough to help further. – Martin Scharrer Apr 17 '11 at 19:08
  • Sure. I thought (maybe mistakenly now you say it) that my mistake was obvious enough for the regular user. – Klaus Apr 17 '11 at 19:11
19

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.

  • +1 for the explanation, expansion looks less mysterious after reading that. – Khaled Hosny Apr 18 '11 at 18:20
9

\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")}
7

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}
  • I tried to put the tex.print into an external file. Now I get an error Misplaced \omit. that one usually get with multirow when something that is not a cell is printed. So the right string is not yet printed... Is there a way to see the string echoed by lua ? – Klaus Apr 17 '11 at 19:45
  • @Klaus misplaced omit is a TeX error associated with halign. The error is still due to expansion and not string printing. is it possible to post a minimal? – Yiannis Lazarides Apr 17 '11 at 19:53
  • Thank you for your help, I added a minimal example in the message. – Klaus Apr 17 '11 at 20:26
5

You can write a \directluanoexpand macro that doesn't do expansion

\newcommand\directluanoexpand[1]{%
        \directlua{\unexpanded{#1}}%
}

but you still need to double slashes as per Aditya's answer.

5

This page contains some explanations about how to use \directlua: http://wiki.luatex.org/index.php/Writing_Lua_in_TeX

In your example this would work:

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

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

But you must be careful when using \multicolumn inside \directluaor another command. \multicolumn must be the first thing in a cell or you get the misplaced \omit error (that's why the dofile doesn't work). In general it is better not to use \multicolumn as the first command. Try to put something before the \multicolumn in your \directlua e.g. the line end \\\multicolumn or a cell separator &\multicolumn.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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