6

I am having difficulty printing LaTeX from a lua function in a LaTeX document processed with lualatex (version 0.70.2). I have a sample that works (if I remove all newlines from the code) and a case that fails. I don't know why these get different results. Here is the sample that fails:

\documentclass{report}
\usepackage{luacode}
\begin{document}

\begin{luacode*}
tex.sprint([[
\begin{tabular}{ | l | l | p{4.in} | } 
\hline 
{\bf File} & {\bf Cards} & {\bf Summary} \\
\hline 
\end{tabular} ]])
\end{luacode*} 

\end{document}

I get an error saying:

! Misplaced \noalign.
\hline ->\noalign
              {\ifnum 0=`}\fi \hrule \@height \arrayrulewidth \futurelet...
l.22 \end{luacode*}

When I put all of the LaTeX code printed from lua on one line the code works fine:

\documentclass{report}
\usepackage{luacode}
\begin{document}

\begin{luacode*}
tex.sprint([[ \begin{tabular}{ | l | l | p{4.in} | } \hline {\bf File} &{\bf Cards} & {\bf Summary} \\ \hline \end{tabular} ]])
\end{luacode*} 

\end{document}

So I have a few question. First, why does the first example shown above fail? It seems like something I am not aware of is being inserted into the generated LaTeX.

Also is there a way for me to see the actual LaTeX that is generated and processed so that I can debug issues like this better? Is there a way to tell the lualatex to log the actual LaTeX it tries to process?

Any other suggestions for how to debug a problem like this?

7

The problem are the line ends:

tex.sprint([[
\begin{tabular}{ | l | l | p{4.in} | } 
\hline 
{\bf File} & {\bf Cards} & {\bf Summary} \\
\hline 
\end{tabular} ]])

The string encoded via [[ and ]] will contain characters with code 10 ("\n", new line character). When TeX gets the string from Lua, it takes it as whole line, thus the line ends does not get the usual treatment (replacing it including previous spaces, setting the character configured by \endlinechar). Instead the new line character is a normal character, the slot position in cmr10 is Ω.

Because there is a character, the Ω before \hline, the cell has already started and \hline complains, because it must be used at the begin of the row.

Possible workarounds:

  • Without new lines as single strings:

    \begin{luacode*}
    tex.sprint(
    [[\begin{tabular}{ | l | l | p{3in} | }]],
    [[\hline]],
    [[\bfseries File & \bfseries Cards & \bfseries Summary \\]],
    [[\hline]],
    [[\end{tabular}]])
    \end{luacode*}
    
  • Removing the new line char at TeX level with a category code for ignoring (9):

    \begingroup
    \catcode10=9\relax
    \begin{luacode*}
    tex.sprint([[
    \begin{tabular}{ | l | l | p{3in} | }
    \hline
    \bfseries File & \bfseries Cards & \bfseries Summary \\
    \hline
    \end{tabular}]])
    \end{luacode*} 
    \endgroup
    

    Also catcode tables can be used, if the catcode setting for slot 10 is 9.

  • Split string in lines in Lua, see also question "Split string in lua?".

    \begin{luacode*}
    for line in unicode.utf8.gmatch([[
    \begin{tabular}{ | l | l | p{3in} | }
    \hline
    \bfseries File & \bfseries Cards & \bfseries Summary \\
    \hline
    \end{tabular}]],
    "[^\r\n]+") do tex.sprint(line) end
    \end{luacode*}
    

Full example:

\documentclass{report}
\usepackage{luacode}
\begin{document}

\begin{luacode*}
tex.sprint(
[[\begin{tabular}{ | l | l | p{3in} | }]],
[[\hline]],
[[\bfseries File & \bfseries Cards & \bfseries Summary \\]],
[[\hline]],
[[\end{tabular}]])
\end{luacode*}

\begingroup
\catcode10=9\relax
\begin{luacode*}
tex.sprint([[
\begin{tabular}{ | l | l | p{3in} | }
\hline
\bfseries File & \bfseries Cards & \bfseries Summary \\
\hline
\end{tabular}]])
\end{luacode*}
\endgroup

\begin{luacode*}
for line in unicode.utf8.gmatch([[
\begin{tabular}{ | l | l | p{3in} | }
\hline
\bfseries File & \bfseries Cards & \bfseries Summary \\
\hline
\end{tabular}]],
"[^\r\n]+") do tex.sprint(line) end
\end{luacode*}

\end{document}

Result

  • Ok. I think I understand the problem a little better now. I know that you can specify a catcode table to tex.sprint. Is there a way to write a LaTeX stream via lua and have it processed as if it were text directly types into the document (newlines and all). I tried using tex.sprint with some of the catcodes defined in the luatexbase-cctb package (such as CatcodeTableLaTeX and CatcodeTableIniTeX but these did not seem to help - I still got Ω characters). – Lance Larsen Jul 3 '15 at 14:35
  • @LanceLarsen Then you need a category code table, which the correct category code for the new line character. Probably you have to define your own table for this. – Heiko Oberdiek Jul 3 '15 at 15:03
3

You are using the wrong print command in the first example. Since you are entering multiple lines, these lines are not string any more. So, you can't use sprint in that case. You should've used texio.write_nl instead.

\documentclass{report}
\usepackage{luacode}
\begin{document}

\begin{luacode*}
texio.write_nl([[
\begin{tabular}{| l | l | p{4.in} | } 
\hline
{\bf File} & {\bf Cards} & {\bf Summary} \\  
\hline 
\end{tabular}]])
\end{luacode*} 

\end{document}

Then you get this as output:

enter image description here

  • This almost works for me, but I get some strange extra text in my table. – Lance Larsen Jul 3 '15 at 4:47
  • This almost works for me, but I get some strange extra text in my table. Just before 'File' there is \Omega height \Omega where the omegas are tex actual capital symbol (not text). I did try to use the 'process_input_buffer' callback to see what tex commands lua was returning, but only the tex file came to this callback - no lua output. – Lance Larsen Jul 3 '15 at 4:55
  • texio.write_nl prints the string into the log and does not pass it back to TeX to typeset the table. – Heiko Oberdiek Jul 3 '15 at 6:58
3

use the environment luacode without the star and escape the backslashes:

\documentclass{report}
\usepackage{luacode}
\begin{document}

\begin{luacode}
tex.print("\\begin{tabular}{| l | l | p{4.in} | } \\hline")
tex.print("\\bfseries File & \\bfseries Cards & \\bfseries Summary \\\\\\hline") 
tex.print("\\end{tabular}")
\end{luacode} 

\end{document}
  • \hline is fine in luacode*. You can see that it is correctly tokenized in the error message of the question. The problem is the line ends, see my answer – Heiko Oberdiek Jul 3 '15 at 7:00
  • ah yes that is true. However, using luacode makes more sense – user2478 Jul 3 '15 at 7:02

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.