当我尝试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
宏时标记化规则仍然适用)。