為什麼 \luaexec 可以運作,但 luacode 環境卻不行?

為什麼 \luaexec 可以運作,但 luacode 環境卻不行?

以下程式碼可以透過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在哪裡列印?是\mlua 中的任何內容。

我傾向於將所有 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}

相關內容