Warum funktioniert \luaexec, die Luacode-Umgebung jedoch nicht?

Warum funktioniert \luaexec, die Luacode-Umgebung jedoch nicht?

lualatexDer folgende Code kann von (Version beta-0.70.1-2011061410 (rev 4277)) korrekt kompiliert werden . Wenn ich jedoch \begin{luacode} ... \end{luacode}die Umgebung verwende, um den \luaexec{...}Befehl zu ersetzen, treten Fehler auf. Ist das ein Fehler?

! Extra }, or forgotten \endgroup.
<template> \unskip \hfil }
                          \hskip \tabcolsep \endtemplate 
l.19 \end{luacode}

? 
! Missing \endgroup inserted.
<inserted text> 
                \endgroup 
l.19 \end{luacode}

? 
! Missing } inserted.
<inserted text> 
                }
l.19 \end{luacode}

? 
! LaTeX Error: \begin{tabular} on input line 8 ended by \end{luacode}.
See the LaTeX manual or LaTeX Companion for explanation.
Type  H <return>  for immediate help.
 ...                                              

l.19 \end{luacode}

? q

Hier ist ein Beispiel

\documentclass[]{article}
\usepackage{luacode}
\usepackage[left=1cm,right=1cm]{geometry}

\begin{document}

\begin{center}

\begin{tabular}{lllllllll}

\luaexec{
  num=6
  for i=1,num do  
    for j=1,num do
    ixj='$'..i..'\\times'..j..'='..i*j..'$';
    tex.print(ixj)
    if(j<num) then tex.sprint('&') else tex.sprint('\\\\') end 
    end 
  end 
}

\end{tabular}
\end{center}

\end{document}

Antwort1

Jede Umgebung/jedes Makro ist anders. Jedes definiert Sonderzeichen anders neu.

Zum Beispiel in Ihrem Codebeispiel

\luaexec{
  num=6
  for i=1,num do  
    for j=1,num do
    ixj='$'..i..'\\times'..j..'='..i*j..'$';
    tex.print(ixj)
    if(j<num) then tex.sprint('&') else tex.sprint('\\\\') end 
    end 
  end 
}

Sie verwenden \\. In Latex \ist dies ein Sonderzeichen. Latex verarbeitet ZUERST den Lua-Codeblock, bevor Lua die Chance bekommt, ihn anzusehen. Das bedeutet, dass, wenn Sie etwas wie

\directlua{print('\n')}

Latex analysiert das und \versucht, etwas damit zu tun. Wenn es \nsich um ein Latex-Makro handelt, wird versucht, es zu erweitern. Eine Möglichkeit, zu verhindern, dass Latex Lua-Code durcheinander bringt, besteht darin, ihm zu sagen, dass es ihn nicht erweitern soll, wie zum Beispiel:

\directlua{print('\noexpand\n')}

In diesem Fall erkennt Latex, dass \noexpandes nicht erweitert wird, was danach kommt.

Wenn wir jetzt die Catcodes \und andere Sonderzeichen ändern, können wir verhindern, dass Latex unseren Lua-Code durcheinanderbringt. Manchmal ist das gut und manchmal schlecht.

Zum Beispiel

\newcommand{\mylatexmacro}{my text}
\directlua{print('\mylatexmacro')}

wird gedruckt my text, da Latex sich ausdehnt \mylatexmacro. ABER wenn wir verwenden

\newcommand{\mylatexmacro}{my text}
\luaexec{print('\mylatexmacro')} 

wird gedruckt, ?latexmacrowobei ? das ist, was \min Lua steht.

Ich halte meinen gesamten Lua-Code normalerweise getrennt vom Latex-Code, da es im Allgemeinen zu viele Probleme gibt, wenn man sich damit beschäftigt. Für sehr einfache Dinge verwende ich Inline-Lua-Code, codiere aber alle meine Funktionen in einer separaten Lua-Datei, die in die Latex-Datei aufgenommen wird.

Das Problem besteht im Wesentlichen darin, dass Lualatex die Tex-Datei nicht vorverarbeitet, sondern einfach einen Lua-Interpreter bereitstellt, der in Latex eingebunden ist. Lua-Code in Latex ist eigentlich Latex-Code, der an den Lua-Interpreter übergeben wird. Wenn Latex den Codeblock analysiert, kann es den Code durcheinanderbringen, sodass Lua ihn nicht versteht. Beispiel:

\directlua{print('\\')}

druckt kein „a“, \weil Latex das sieht \\und versucht, dort eine neue Zeile einzufügen. Anschließend wird dieser neue Code an den Lua-Parser übergeben, was als Lua-Code letztlich keinen Sinn ergibt.

Antwort2

Versuchen Sie es folgendermaßen:

\begin{tabular}{lllllllll}

\luacode
  num=6
  for i=1,num do  
    for j=1,num do
    ixj='$'..i..'\\times'..j..'='..i*j..'$';
    tex.print(ixj)
    if(j<num) then tex.sprint('&') else tex.sprint('\\\\') end 
    end 
  end 
\endluacode

\end{tabular}

oder als Alternative

\documentclass{article}
\usepackage{luacode}

\begin{document}

\begin{luacode}
  tex.print("\\begin{tabular}{lllllllll}")
    num=6
  for i=1,num do  
    for j=1,num do
    ixj='$'..i..'\\times'..j..'='..i*j..'$';
    tex.print(ixj)
    if(j<num) then tex.sprint('&') else tex.sprint('\\\\') end 
    end 
  end 
  tex.print("\\end{tabular}")
\end{luacode}

\end{document}

verwandte Informationen