¿Por qué \luaexec funciona pero el entorno luacode no?

¿Por qué \luaexec funciona pero el entorno luacode no?

El siguiente código se puede compilar lualatexcorrectamente con (Versión beta-0.70.1-2011061410 (rev 4277)). Pero si uso \begin{luacode} ... \end{luacode}el entorno para reemplazar el \luaexec{...}comando, se producen errores. ¿Es esto un error?

! 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

Aquí hay un ejemplo

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

Respuesta1

Cada entorno/macro es diferente. Cada uno redefine los caracteres especiales de manera diferente.

Por ejemplo, en su ejemplo de código

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

tu usas \\. En látex \es un carácter especial. Latex procesa el bloque de código lua PRIMERO antes de que lua tenga la oportunidad de verlo. Lo que esto significa es que si tienes algo como

\directlua{print('\n')}

Latex analizará eso, lo verá \e intentará hacer algo con él. Si \nse trata de alguna macro de látex, intentará expandirla. Una forma de evitar que el látex arruine el código lua es decirle que no lo expanda, como por ejemplo

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

En cuyo caso el látex \noexpandno expandirá lo que hay detrás.

AHORA, si cambiamos los códigos cat \y otros símbolos especiales, podemos evitar que el látex altere nuestro código lua. A veces esto es bueno y otras veces es malo.

Por ejemplo

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

se imprimirá my textya que el látex se expandirá \mylatexmacro. PERO si usamos

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

¿Imprimirá ?latexmacrodónde? es lo que sea que \mesté en lua.

Tiendo a mantener todo mi código lua separado del código latex porque generalmente hay demasiados problemas involucrados cuando comienzas a utilizarlo. Para cosas muy simples, usaré el código lua en línea, pero codificaré todas mis funciones en un archivo lua separado que se incluye en el archivo latex.

Básicamente, el problema es que lualatex no preprocesa el archivo tex, sino que simplemente proporciona un intérprete lua conectado a látex. El código lua en látex es en realidad un código látex que se pasa al intérprete de lua. Cuando latex analiza el bloque de código, puede estropear el código y lua no entenderá de qué se trata. p.ej,

\directlua{print('\\')}

no imprime a \porque látex ve \\e intenta hacer una nueva línea allí, luego ese nuevo código se pasa al analizador lua, lo que termina sin tener ningún sentido como código lua.

Respuesta2

pruébalo de esta manera:

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

o como alternativa

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

información relacionada