[Tex/LaTex] In which order is Lua Code in LuaTeX being processed

lualuatex

Can someone help me understand the order in which LuaTeX documents are being processed?

From what I've understood, the order is the following:

  • the code is being read, top to bottom
  • when the compiler finds the start of some Lua code it swallows it, expands any TeX commands it can find and passes the result to a Lua interpreter
  • the Lua interpreter interprets the code and puts its output back into the document

  • is the output being parsed by again? Is it just put into the document as is?

To illustrate my question:

\newcommand{\compare}[2]{
#1
\directlua{
    testNumber=#2
    if #1<testNumber then
        tex.sprint("is bigger")
    else
        tex.sprint("is smaller")    
    end
    tex.sprint(" than "..testNumber..".")
    }
}

When \compare{1}{5} is called the Lua interpreter is being fed:

testNumber=5
if 1<testNumber then
    tex.sprint("is bigger")
else
    tex.sprint("is smaller")    
end
tex.sprint(" than "..testNumber..".")

And the output would be pasted into the document in the place where the directlua command was called.

Now suppose I add another command:

\newcommand{\iterate}[2]{
    \directlua{
        for i=1,#1,1 do
        tex.print(\\compare{i}{#2})
        end
    }
}

and call it via \iterate{5}{5}

From my limited understanding, this should be fed to the Lua interpreter as follows:

for i=1,10,1 do
tex.print(\compare{i}{5})
end

and the output would be:

\compare{1}{5}
\compare{2}{5}
\compare{3}{5}
\compare{4}{5}
\compare{5}{5}

Is this output being evaluated again? I can't seem to get my code to run, hence I was thinking that I've maybe misunderstood something.

Can this process be understood in terms of a preprocessor-processor relationship such as with, say, a PHP application which outputs JS code which itself is being interpreted by the client?

Best Answer

When you write

\newcommand{\iterate}[2]{
    \directlua{
        for i=1,#1,1 do
        tex.print(\\compare{i}{#2})
        end
    }
}

The Lua process sees

for i=1,#1,1 do
  tex.print(<the result of \compare>)
end

What you need to do is something like that:

\newcommand\iterate[2]{%
  \luaexec{
    for i=1,#1 do
        tex.print(string.format("\\compare{\%d}{#2}",i))
    end
 }
}

\iterate{3}{2}

(luaexec is from the luacode package) This prints "\compare{1}{2} \compare{2}{2} \compare{3}{2}" into TeX's input string and that gets evaluated. This works because \\ generates a backslash and it is separate from the word "compare". It's a hack and I don't recommend that. Please see How to do a 'printline' in LuaTeX for more info.

This is an experiment on "reevaluating":

For example: if you write

\documentclass[a4paper]{article}
\usepackage{luacode}
\begin{document}

\begin{luacode*}
tex.sprint("%hello")
\end{luacode*}

\end{document}

TeX will see %hello and interprets it as a comment and thus no output file will be generated.

When you write this instead (see the -2 as the first argument to tex.print())

\documentclass[a4paper]{article}
\usepackage{luacode}
\begin{document}

\begin{luacode*}
tex.sprint(-2,"%hello")
\end{luacode*}

\end{document}

tex sees %hello, but the % has a "safe" category code. If the first argument to tex.print is a number, it will be taken as a catcode table. What I want to show: TeX reads the result of the \directlua{} call.

Related Question