以下程式碼可以透過lualatex
(Version beta-0.70.1-2011061410 (rev 4277))正確編譯。但是如果我使用\begin{luacode} ... \end{luacode}
環境來替換\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 在 lua 有機會查看它之前首先處理 lua 程式碼區塊。這意味著如果你有類似的東西
\directlua{print('\n')}
Latex 會解析它並查看\
並嘗試用它做一些事情。如果\n
是某個乳膠宏,它將嘗試擴展它。防止 Latex 弄亂 lua 程式碼的一種方法是告訴它不要擴展它,例如
\directlua{print('\noexpand\n')}
在這種情況下,乳膠會看到它\noexpand
不會擴展它後面的內容。
現在,如果我們更改 Catcode\
和其他特殊符號,我們就可以阻止 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 檔案中。
本質上,問題在於 lualatex 不會預處理 tex 文件,而只是提供一個掛鉤到 Latex 的 lua 解釋器。 Latex 中的 lua 程式碼實際上是傳遞給 lua 解釋器的 Latex 程式碼。當 Latex 解析程式碼區塊時,它可能會弄亂程式碼,而 lua 無法理解它是什麼。例如,
\directlua{print('\\')}
不要列印 a\
因為乳膠看到\\
並嘗試在那裡創建一個新行,然後將新程式碼傳遞給 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}