这是代码,它可以编译(请不要问我它是做什么的):
\documentclass{minimal}
\begin{document}
\ExplSyntaxOn
\newcommand\foo[1]{
\tl_set:Nn \l_ebnf_tl { }
\tl_set_rescan:Nno \l_ebnf_tl {}{#1}
\l_ebnf_tl
}
\ExplSyntaxOff
\foo{ \textdollar}
\end{document}
但是,如果我将该行修改为textdollar
这一行(我只需删除前导空格):
\foo{\textdollar}
它打印出以下内容:
! Undefined control sequence.
\l_ebnf_tl ->\?
-cmd \textdollar \?\textdollar
l.10 \foo{\textdollar}
这是怎么回事?如何修复?我不需要那里的空格字符。
答案1
的扩展\textdollar
是(由 提供\tl_analysis_show:N
)
The token list \textdollar contains the tokens:
> \?-cmd (control sequence=macro:#1#2->\ifx \protect \@typeset@protect \ETC.)
> \textdollar (control sequence=macro:->\?-cmd \textdollar \?\textdollar )
> \?\textdollar (control sequence=\long macro:->\UseTextSymbol {TS1}\te\ETC.).
第一个控制序列通常无法获得,但显然可以用 获得\csname ?-cmd\endcsname
。第三个控制序列也可以用 获得\csname ?\string\textdollar\endcsname
。
你正在应用\tl_set_rescan:no {} {\textdollar}
并且 TeX\textdollar
在执行之前适当地扩展一次\tl_set_rescan:nn
,你得到
\tl_set_rescan:nn {} {\?-cmd \textdollar \?\textdollar}
但此时,类别代码是标准代码,因此重新扫描将输入解释为
\?•-•c•m•d• •\textdollar•\?•\textdollar
(其中•
用于将一个标记与另一个标记分开)
现在\?
通常是未定义的,并且您会收到错误。
如果你添加一个空格,例如
\foo{ \textdollar}
说明o
符意味着第一的尝试扩展参数中的 token。它不可扩展,因此什么也不会发生,并且重新扫描会产生一个空格,后面跟着\textdollar
。