为什么我可以使用
\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