\unexpanded 是如何定义的?

\unexpanded 是如何定义的?

我想知道\etoolbox它是如何\expandonce工作的。所以我查了一下它的定义,发现

\unexpanded\expandafter{#1}

但无论我在哪里寻找,我都找不到 的定义\unexpanded。我试过

 texdef -t latex unexpanded -s

返回以下内容:

Source code definition of 'unexpanded' could not be found.
\unexpanded is defined by (La)TeX.

\unexpanded:
\unexpanded

我也尝试过查看文档source2e,但是那里没有相关内容\unexpanded

有人能告诉我在哪里可以找到该文档的正确方向吗?

答案1

\unexpanded是 ε-TeX 基元。如果你这样做

\documentclass{article}
\begin{document}
\show\unexpanded
\end{document}

你会在日志中看到:

> \unexpanded=\unexpanded.
l.3 \show\unexpanded

这似乎是多余的信息,但实际上告诉你这是一个原始的控制序列。原始信息列在 TeX Book 或TeX 按主题分类但你不会\unexpanded在那里找到它,因为它是一个 ε-TeX 原语。它被描述为在 e-TeX 手册中, 尽管:

\unexpanded<general text>

扩展是标记列表<balanced text>

[...]

在构建扩展标记列表时,扩展产生的标记不会进一步扩展(这与 TeX 和 ε-TeX 中变量\unexpanded扩展产生的标记所表现的行为相同 )。\the<token>

答案2

正如 cgnieder 的出色回答所说,\unexpanded是 e-TeX 的一个原语,即原始 TeX 语言的扩展。原语没有定义,它们是引擎直接理解的命令。其中一些是可扩展的,也就是说,它们不会到达 TeX 的“胃口”,因为它们的扩展就像宏一样(例如,条件语句也是如此);\unexpanded是这些宏之一。

它是对 的泛化,在或 的\noexpand上下文中,具有空扩展,但也使下一个标记对于当前任务而言不可扩展。因此\edef\write

\def\foo{something}
\def\baz{else}
\edef\x{\foo\noexpand\baz}

相当于

\def\x{something\baz}

使用\unexpanded它可以防止一个\edef(或\xdef)或\write整个标记列表扩展,而无需将其添加\noexpand到所有可扩展标记的前面。

由于\unexpanded遵循模式

\unexpanded <general text>

它有一个有趣的特性。当 TeX 想要扩展它时,它会期待找到一个<general text>定义为

<filler> { <balanced text> <right brace>

扩展标记来识别 a<filler>和最终的{。 A<filler>只是\relax和空间标记的任意序列,它们被忽略。{是类别代码 1 的显式或隐式标记。

这样做的结果是

\unexpanded\expandafter{\cs}

将导致在启动令牌列表\cs之前展开,这将{不是不再扩展。事实上,的定义\expandonce

\newcommand{\expandonce}[1]{\unexpanded\expandafter{#1}}

此外\detokenize(e-TeX 的另一个可扩展原语)具有相同的属性。

请注意<filler>:在某些情况下,它可能会导致一些意想不到的后果,如下所示让狮子跑来跑去。简洁地

相关内容