我在使用 lualatex(版本 0.70.2)处理的 LaTeX 文档中从 lua 函数打印 LaTeX 时遇到困难。我有一个可以运行的示例(如果我从代码中删除所有换行符),还有一个失败的示例。我不知道为什么它们会得到不同的结果。以下是失败的示例:
\documentclass{report}
\usepackage{luacode}
\begin{document}
\begin{luacode*}
tex.sprint([[
\begin{tabular}{ | l | l | p{4.in} | }
\hline
{\bf File} & {\bf Cards} & {\bf Summary} \\
\hline
\end{tabular} ]])
\end{luacode*}
\end{document}
我收到一条错误消息:
! Misplaced \noalign.
\hline ->\noalign
{\ifnum 0=`}\fi \hrule \@height \arrayrulewidth \futurelet...
l.22 \end{luacode*}
当我将从 lua 打印的所有 LaTeX 代码放在一行上时,代码运行良好:
\documentclass{report}
\usepackage{luacode}
\begin{document}
\begin{luacode*}
tex.sprint([[ \begin{tabular}{ | l | l | p{4.in} | } \hline {\bf File} &{\bf Cards} & {\bf Summary} \\ \hline \end{tabular} ]])
\end{luacode*}
\end{document}
所以我有几个问题。首先,为什么上面显示的第一个示例失败了?似乎有我不知道的东西被插入到生成的 LaTeX 中。
另外,有没有办法让我看到实际生成和处理的 LaTeX,以便更好地调试此类问题?有没有办法告诉 lualatex 记录它尝试处理的实际 LaTeX?
关于如何调试此类问题还有其他建议吗?
答案1
问题出在以下行结尾:
tex.sprint([[
\begin{tabular}{ | l | l | p{4.in} | }
\hline
{\bf File} & {\bf Cards} & {\bf Summary} \\
\hline
\end{tabular} ]])
[[
通过和编码的字符串]]
将包含代码为 10 的字符(“\n”,换行符)。当 TeX 从 Lua 获取字符串时,它会将其视为整行,因此行尾不会得到通常的处理(替换它包括前面的空格,设置由 设置的字符\endlinechar
)。相反,换行符是一个普通字符,中的插槽位置cmr10
是 Ω。
因为有一个字符,即之前的 Ω \hline
,单元格已经开始并且\hline
会发出抱怨,因为它必须在行的开头使用。
可能的解决方法:
不包含换行符的单个字符串:
\begin{luacode*} tex.sprint( [[\begin{tabular}{ | l | l | p{3in} | }]], [[\hline]], [[\bfseries File & \bfseries Cards & \bfseries Summary \\]], [[\hline]], [[\end{tabular}]]) \end{luacode*}
在 TeX 级别删除换行符,并使用类别代码进行忽略(9):
\begingroup \catcode10=9\relax \begin{luacode*} tex.sprint([[ \begin{tabular}{ | l | l | p{3in} | } \hline \bfseries File & \bfseries Cards & \bfseries Summary \\ \hline \end{tabular}]]) \end{luacode*} \endgroup
如果插槽 10 的 catcode 设置为 9,那么也可以使用 catcode 表。
在 Lua 中按行拆分字符串,另请参阅问题“在 lua 中拆分字符串?“。
\begin{luacode*} for line in unicode.utf8.gmatch([[ \begin{tabular}{ | l | l | p{3in} | } \hline \bfseries File & \bfseries Cards & \bfseries Summary \\ \hline \end{tabular}]], "[^\r\n]+") do tex.sprint(line) end \end{luacode*}
完整示例:
\documentclass{report}
\usepackage{luacode}
\begin{document}
\begin{luacode*}
tex.sprint(
[[\begin{tabular}{ | l | l | p{3in} | }]],
[[\hline]],
[[\bfseries File & \bfseries Cards & \bfseries Summary \\]],
[[\hline]],
[[\end{tabular}]])
\end{luacode*}
\begingroup
\catcode10=9\relax
\begin{luacode*}
tex.sprint([[
\begin{tabular}{ | l | l | p{3in} | }
\hline
\bfseries File & \bfseries Cards & \bfseries Summary \\
\hline
\end{tabular}]])
\end{luacode*}
\endgroup
\begin{luacode*}
for line in unicode.utf8.gmatch([[
\begin{tabular}{ | l | l | p{3in} | }
\hline
\bfseries File & \bfseries Cards & \bfseries Summary \\
\hline
\end{tabular}]],
"[^\r\n]+") do tex.sprint(line) end
\end{luacode*}
\end{document}
答案2
第一个例子中,您使用了错误的print
命令。由于您输入了多行,这些行不再存在string
。因此,在这种情况下您不能使用sprint
。您应该使用texio.write_nl
。
\documentclass{report}
\usepackage{luacode}
\begin{document}
\begin{luacode*}
texio.write_nl([[
\begin{tabular}{| l | l | p{4.in} | }
\hline
{\bf File} & {\bf Cards} & {\bf Summary} \\
\hline
\end{tabular}]])
\end{luacode*}
\end{document}
然后你会得到这个输出:
答案3
使用不带星号的环境luacode
并转义反斜杠:
\documentclass{report}
\usepackage{luacode}
\begin{document}
\begin{luacode}
tex.print("\\begin{tabular}{| l | l | p{4.in} | } \\hline")
tex.print("\\bfseries File & \\bfseries Cards & \\bfseries Summary \\\\\\hline")
tex.print("\\end{tabular}")
\end{luacode}
\end{document}