Por que \luaexec funciona mas o ambiente luacode não?

Por que \luaexec funciona mas o ambiente luacode não?

O código a seguir pode ser compilado por lualatex(versão beta-0.70.1-2011061410 (rev 4277)) corretamente. Mas se eu usar \begin{luacode} ... \end{luacode}o ambiente para substituir o \luaexec{...}comando, ocorrerão erros. Isso é um inseto?

! 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

Aqui está um exemplo

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

Responder1

Cada ambiente/macro é diferente. Cada um redefine caracteres especiais de maneira diferente.

Por exemplo, no seu exemplo 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 
}

você usa \\. No látex \é um caractere especial. O Latex processa o bloco de código lua PRIMEIRO antes que lua tenha a chance de observá-lo. O que isso significa é que se você tiver algo como

\directlua{print('\n')}

O Latex irá analisar isso, ver \e tentar fazer algo com isso. Se \nhouver alguma macro de látex, ele tentará expandi-la. Uma maneira de evitar que o latex atrapalhe o código lua é dizer a ele para não expandi-lo, como

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

Nesse caso, o látex \noexpandnão verá o que está depois dele expandir.

AGORA, se mudarmos os catcodes \e outros símbolos especiais, podemos impedir que o látex mexa com nosso código lua. Às vezes isso é bom e às vezes isso é ruim.

Por exemplo

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

será impresso my text, pois o látex se expandirá \mylatexmacro. MAS se usarmos

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

imprimirá ?latexmacroonde? é o que quer que \mesteja em lua.

Eu costumo manter todo o meu código lua separado do código latex porque geralmente há muitos problemas envolvidos quando você começa a usá-lo. Para coisas muito simples, usarei o código lua inline, mas codificarei todas as minhas funções em um arquivo lua separado que está incluído no arquivo latex.

Essencialmente, o problema é que lualatex não pré-processa o arquivo tex, mas simplesmente fornece um interpretador lua conectado ao látex. O código lua em látex é, na verdade, um código de látex que é passado para o interpretador lua. Quando o latex analisa o bloco de código, ele pode bagunçar o código, onde lua não entenderá o que é. por exemplo,

\directlua{print('\\')}

não imprime a \porque o latex vê o \\e tenta fazer uma nova linha ali então esse novo código é passado para o analisador lua, o que acaba não fazendo sentido como código lua.

Responder2

tente desta forma:

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

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

informação relacionada