Почему \luaexec работает, а среда luacode — нет?

Почему \luaexec работает, а среда luacode — нет?

Следующий код может быть скомпилирован lualatex(Версия beta-0.70.1-2011061410 (рев. 4277)) правильно. Но если я использую \begin{luacode} ... \end{luacode}environment для замены \luaexec{...}команды, возникают ошибки. Это ошибка?

! 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

Вот пример

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

решение1

Каждая среда/макрос отличается. Каждая переопределяет специальные символы по-разному.

Например, в вашем примере кода

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

вы используете \\. В latex \это специальный символ. Latex обрабатывает блок кода lua ПЕРВЫМ, прежде чем lua получит возможность взглянуть на него. Это означает, что если у вас есть что-то вроде

\directlua{print('\n')}

Latex проанализирует это, увидит \и попытается что-то с этим сделать. Если \nэто какой-то макрос latex, он попытается его расширить. Один из способов не дать latex испортить код lua — сказать ему не расширять его, например

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

В этом случае латекс не будет \noexpandрасширяться, так как он будет находиться после него.

ТЕПЕРЬ, если мы изменим catcodes для \и других специальных символов, мы можем остановить latex от вмешательства в наш lua-код. Иногда это хорошо, а иногда это плохо.

Например

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

будет печатать, my textтак как латекс расширяется \mylatexmacro. НО если мы используем

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

выведет ?latexmacroгде ? то, что \mнаходится в lua.

Я стараюсь хранить весь свой код lua отдельно от кода latex, потому что обычно возникает слишком много проблем, когда вы начинаете вникать в него. Для очень простых вещей я буду использовать встроенный код lua, но кодировать все свои функции в отдельном файле lua, который включен в файл latex.

По сути, проблема в том, что lualatex не обрабатывает файл tex предварительно, а просто предоставляет интерпретатор lua, подключенный к latex. Код lua в latex на самом деле является кодом latex, который передается интерпретатору lua. Когда latex анализирует блок кода, он может испортить код, и lua не поймет, что это такое. Например,

\directlua{print('\\')}

не печатает a, \потому что latex видит \\и пытается создать новую строку, а затем этот новый код передается в анализатор lua, который в итоге не имеет никакого смысла как код lua.

решение2

попробуйте так:

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

или как альтернатива

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

Связанный контент