Lua 中的 TeX 条件

Lua 中的 TeX 条件

为什么我可以使用

\startluacode
context.mymacro("\noexpand\\iftrue")
\stopluacode

但不是

\startluacode
context.mymacro([[\noexpand\iftrue]])
\stopluacode

或不

\startluacode
context.mymacro([[\unexpanded{\iftrue}]])
\stopluacode

或不

\startluacode
context.mymacro("\luaescapestring{\normalunexpanded{\iftrue}}")
\stopluacode

我相信\iftrue这是一个可扩展的原语。

编辑

\def\mymacro#1{%
    \let\mycond#1%
    \show\mycond}

答案1

\startluacode<code>\stopluacode大致翻译为:

\begingroup
  <catcode settings> (basically verbatim, but \ is catcode 0)
  <shorthands> (\\ is defined to be the two backslash characters, as
    well as \|, \-, \(, \), \{, \}, etc.)
\normalexpanded {\endgroup \noexpand \directlua {<code>}}

而让你感到困惑的是<code>两次:一次通过\normalexpanded\expanded原始),再一次通过\directlua

第一个方法有效,因为一旦 的扩展\normalexpanded结束,就剩下\directlua{context.mymacro("\\iftrue")},它可以满足您的要求。请注意,由于\\被定义为扩展为,因此您不需要在那里,因此您可以将第一个示例简化为:\12\12\noexpand

\startluacode
context.mymacro("\\iftrue")
\stopluacode

第二个:

\startluacode
context.mymacro([[\noexpand\iftrue]])
\stopluacode

不起作用,因为 会\noexpand随着 消失\normalexpanded,剩下\directlua{context.mymacro([[\iftrue]])},然后过早地\directlua扩大\iftrue。您需要两轮\noexpand

\startluacode
context.mymacro([[\noexpand\noexpand\noexpand\iftrue]])
\stopluacode

第三个:

\startluacode
context.mymacro([[\unexpanded{\iftrue}]])
\stopluacode

不起作用,原因有三:首先,在 ConTeXt 中\unexpanded\protected原语,而不是\unexpanded。您\normalunexpanded在这里需要。其次,\startluacode括号内是 catcode 12,因此\normalunexpanded会抛出Missing { inserted错误。第三点与上面相同:您有两轮扩展,因此您需要两个\normalunexpanded

\everyluacode\expandafter{\the\everyluacode
  \catcode`\{=1 \catcode`\}=2\relax} % catcode setting to have braces be braces
\startluacode
context.mymacro([[\normalunexpanded{\normalunexpanded{\iftrue}}]])
\stopluacode

第四个:

\startluacode
context.mymacro("\luaescapestring{\normalunexpanded{\iftrue}}")
\stopluacode

不起作用的原因与上述相同:括号的 catcode 为 12,因此\luaescapestring永远看不到它{需要的内容并引发Missing { inserted错误。您需要先设置正确的 catcode:

\everyluacode\expandafter{\the\everyluacode
  \catcode`\{=1 \catcode`\}=2\relax} % catcode setting to have braces be braces
\startluacode
context.mymacro("\luaescapestring{\normalunexpanded{\iftrue}}")
\stopluacode

相关内容