lualatex
下面的代码可以通过(Version beta-0.70.1-2011061410 (rev 4277))正确编译。但是如果我使用\begin{luacode} ... \end{luacode}
environment 替换\luaexec{...}
命令,就会出错。这是一个 bug 吗?
! 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')}
将打印哪里? lua 中有?latexmacro
什么。\m
我倾向于将所有 lua 代码与 latex 代码分开,因为当你开始使用它时,通常会涉及太多问题。对于非常简单的东西,我将使用内联 lua 代码,但将所有函数编码在单独的 lua 文件中,该文件包含在 latex 文件中。
本质上,问题在于 lualatex 不会预处理 tex 文件,而只是提供一个连接到 latex 的 lua 解释器。latex 中的 lua 代码实际上是传递给 lua 解释器的 latex 代码。当 latex 解析代码块时,它可能会弄乱代码,而 lua 无法理解它是什么。例如,
\directlua{print('\\')}
不打印,\
因为 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}