Следующий код может быть скомпилирован 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}