为什么 \luaexec 可以工作,但 luacode 环境却不工作?

为什么 \luaexec 可以工作,但 luacode 环境却不工作?

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}

相关内容