为什么 \if 之后不遵守 \unexpanded?

为什么 \if 之后不遵守 \unexpanded?

我很惊讶地发现,如果位于 之后的前两个标记内,则的参数\unexpanded会扩展。使用 Knuth TeX 的也可以,但我很好奇区别在哪里。\unexpanded\if\noexpand

\documentclass{article}

\begin{document}

    \def\endtoken{~}
    
    \typeout{! ========== tracing 1 ==========}
    \tracingmacros=2
    \tracingcommands=3
    
%   \if \expandafter\noexpand\endtoken \noexpand~% this would work
    \if \unexpanded\expandafter{\endtoken} \noexpand~% this does not
        true
    \else
        false
    \fi
    
    \tracingcommands=0
    \tracingmacros=0
    \typeout{! ========== tracing 0 ==========}

\end{document}

\expandafter扩展了一次的参数,没有\unexpanded什么区别。 ~无论有没有它,都会一直扩展,结果都是一样的。

\tracingmacros显示了如何~扩展,并\tracingcommands显示了\if求值为真。我假设它通过比较和得出这个结果,\protect\unhbox两个都是通过扩展插入的~,并且相等,因为它们都是控制序列。有没有跟踪命令可以显示 TeX 在评估条件时比较哪些标记?(我已经浏览了很棒的跟踪命令列表但不幸的是没有在其中找到这一点。

(开头的感叹号\typeout让 TeXstudio 认为出现了错误,因此它为我提供了一个链接,指向日志文件中跟踪命令输出开始和结束的位置。然而,这可能会产生意想不到的副作用,即尽管 pdf 已正确构建,但它无法加载。)

为什么 的参数\unexpanded在 之后扩展\if(不在 之内\edef),但是 之后的标记\noexpand即使在 之后也没有扩展\if

有趣的问题让狮子绕圈奔跑。简洁明了。也处理和\if\unexpanded但我认为它没有回答这个问题,因为在的里面\fi,但是这里在和结束的花括号之后。<filler>\unexpanded<balanced text>

答案1

\unexpanded语本质上是一个匿名标记,这意味着在\edef或类似标记内没有扩展,而\noexpand显式地将下一个标记的行为更改为等于\relax一次扩展。如果我们选择对两者的结果进行排版,也许会更容易看到这一点:

\documentclass{article}
\begin{document}
\newcommand{\demo}{FOO}
Text \noexpand\demo\space text \unexpanded{\demo} text.
\end{document}

第一个\demo被转换\relax为 ,因此不执行任何操作。相反,第二个被有效地传递\toks0{\demo}\the\toks0,因此排版正常。


作为埃格尔指出,人们还可以看到

\documentclass{article}
\begin{document}
\expandafter\edef\expandafter\foo\expandafter{\unexpanded{~}} 
\show\foo
\expandafter\edef\expandafter\foo\expandafter{\noexpand~}
\show\foo
\end{document}

相关内容