如何在lua代码中执行expl3命令

如何在lua代码中执行expl3命令

当我尝试expl3在 Lua 代码中执行命令时,出现错误:

! Undefined control sequence.
\\  ->\let \reserved@e
                       \relax \let \reserved@f \relax \@ifstar {\let \reserv...

l.13 \test{1}

是的,我知道下面的示例可以使用完整expl3函数编写,但我有一些代码在 Lua 中保存了一些数据,因此我需要举例说明如何expl3在 Lua 中执行代码。请帮助我,让我的示例可以在 Lua 中运行。第二个问题是,我如何\directlua使用空间而不是~,因为~Lua 中也使用了。

\documentclass{article}
\usepackage{expl3}
\ExplSyntaxOn
\prop_gset_from_keyval:Nn \g__my_prop
  { value0 = -1 , value1 = 0 }
\cs_new_eq:NN \PropRemovecn \prop_remove:cn
\ExplSyntaxOff
\newcommand{\test}[1]{%
  \directlua{%
    if #1==1 then
      tex.print("\\PropRemovecn{g__my_prop}{value1}")
    end
  }}
\begin{document}
\test{1}
\end{document}

答案1

您的错误来自\directlua尝试扩展\\。您会收到相同的错误\edef\x{\\}(在 2020-02-02 之前的 LaTeX 版本中)。您需要确保\\在 Lua 解释器启动之前变为两个字符标记。您可以使用 或\string\\prop...\luaescapestring{\prop...}或者,更多expl3-y,\lua_escape:e)。

此外,与扩展宏不同,宏的替换文本已被标记化,当您执行tex.print此操作时,就像您在输入文件中键入这些标记一样,当时\directlua被扩展。由于您在代码上下文\test之外使用命令,并且不是字母,因此被误解为。就像您自己输入代码一样,您必须使用:expl3_:\prop_remove:cn\prop _remove:cn\ExplSyntaxOn/Off

tex.print("\luaescapestring{\\ExplSyntaxOn\\prop_remove:cn{g__my_prop}{value1}\\ExplSyntaxOff}")

但是这会产生一些开销,如果你碰巧在某些代码\test中间使用,那么它会不顾一切地执行,而你却不想要它这样做。我建议为 定义一个接口:expl3\ExplSyntaxOff\prop_remove:cn

\documentclass{article}
\usepackage{expl3}
\ExplSyntaxOn
\prop_gset_from_keyval:Nn \g__my_prop
  { value0 = -1 , value1 = 0 }
\cs_new_eq:NN \PropRemovecn \prop_remove:cn
\ExplSyntaxOff
\newcommand{\test}[1]{%
  \directlua{%
    if #1==1 then
      tex.print("\luaescapestring{\PropRemovecn{g__my_prop}{value1}}")
    end
  }}
\begin{document}
\test{1}
\end{document}

您还可以按照 Ulrike 的建议将 catcode 表传递给tex.print,然后 LuaTeX 将使用该 catcode 设置打印标记。如果您加载,l3cctab则可以使用(在这种情况下,\int_use:N \c_code_cctab代码定义必须在里面):\ExplSyntaxOn/Off

\documentclass{article}
\usepackage{expl3}
\usepackage{l3cctab}
\ExplSyntaxOn
\prop_gset_from_keyval:Nn \g__my_prop
  { value0 = -1 , value1 = 0 }
\cs_new_eq:NN \PropRemovecn \prop_remove:cn
\newcommand{\test}[1]{%
  \lua_now:e {%
    if~#1==1~then~
      tex.print(\int_use:N \c_code_cctab,
        "\lua_escape:e {\prop_remove:cn{g__my_prop}{value1}}")
    end
  }}
\ExplSyntaxOff
\begin{document}
\test{1}
\end{document}

至于您的第二个问题:如果您需要大量空格,请在expl3代码环境之外定义命令(它所在的事实\directlua并不重要,因为在定义\test宏时标记化规则仍然适用)。

相关内容