何时允许隐式令牌?

何时允许隐式令牌?

例如:latex 代码:

\documentclass{article}
\begin{document}

% test-case 1
% Output: "b"
% Expansion is not allowed, and implicit token doesn't take effect.
\begingroup
\let\implicitToken=b
\uppercase{\implicitToken}
\endgroup

% test-case 2
% Output: "b"
% Expansion is allowed, and implicit token takes effect.
\begingroup
\let\implicitToken=b
\if \implicitToken b
b
\else
B
\fi
\endgroup

% test-case 3
% Compile error: \cq is undefined
% Expansion is not allowed, and implicit token doesn't take effect.
\begingroup
\let\implicitToken\cq
\def\implicitToken{}
\cq
\endgroup

% test-case 4
% Output: "B"
% Expansion is allowed, but implicit token doesn't take effect.
\begingroup
\let\implicitToken=b
\edef\cq{\implicitToken}
\let\implicitToken=B
\cq
\endgroup

\end{document}

以下是我的问题:

  • 如果上下文允许扩展,是否允许隐式标记?

    这可能是解释测试用例 1、2、3 的唯一方法。但它无法解释测试用例 4。

  • 如果不允许,什么时候才允许?


我已阅读 TeXByTopic 但找不到确定的结论。

答案1

隐式标记不会扩展其含义,它们它们的意义。

\let\tokenAlias=b

\tokenAlias 一个b。这出现在您的第二个测试中:\tokenAliasb完全等价。

但是,大小写转换是根据相关标记的字符代码进行的。(如注释中所述,\uppercase也是不可扩展的。)因此,由于它根本没有字符代码,因此\tokenAlias不会受到影响,它是一个控制序列。\uppercase

让隐式字符标记“自然出现”的唯一方法是迭代输入并对每个输入的含义进行测试,用其含义替换每个隐式标记。


每次进行一个测试(编辑后),在任何情况下都不会发生扩展。因此:

  1. \implicitToken保持不变,因为它在大写字母表中没有字符代码

  2. \implicitToken b,因此比较两者使用\if是正确的:有的扩展\implicitToken

  3. \cq从未定义,因此\let\def行无效

  4. 由于没有扩展,所以\edef不执行任何操作。相反,我们最终会得到替换文本:因此,其效果取决于使用时的含义。\implicitToken\cq\implicitToken

再次注意排版不是扩展上下文:结果取决于执行的令牌。

答案2

让我们逐一分析您的测试。

一个隐式标记(更准确地说是隐式字符标记)是由 定义的符号标记\let<token>=<character>

测试 2

% test-case 2
% Output: "b"
% Expansion is enabled, and implicit token takes effect.
\begingroup
\let\implicitToken=b
\if \implicitToken b
b
\else
B
\fi
\endgroup

这将输出“b”,因为隐式标记的行为类似于它被定义为相等的字符在上下文中\if\ifcat

测试 3

% test-case 3
% Compile error: \cq is undefined
% Expansion is disabled, and implicit token doesn't take effect.
\begingroup
\let\implicitToken\cq
\def\implicitToken{}
\cq
\endgroup

这比较简单:赋值\def\implicitToken{}会覆盖\let。另一方面,\implicitToken永远不会使用,并且\cq(undefined) 会引发错误。

测试 4

% test-case 4
% Output: "B"
% Expansion is enabled, but implicit token doesn't take effect.
\begingroup
\let\implicitToken=b
\edef\cq{\implicitToken}
\let\implicitToken=B
\cq
\endgroup

如果你\show\cq在执行完后添加,\edef你会看到

> \cq=macro:
->\implicitToken .

并且由于后续的重新定义,输出将包含“B”。

隐式标记是不是可扩展,所以代码

\let\implicitToken=b
\edef\cq{\implicitToken}

\let\implicitToken=b
\def\cq{\implicitToken}

\implicitToken完全等价。TeX 将使用时间扩展中的当前含义\cq:在您的测试中,它是“B”。

测试 1

% test-case 1
% Output: "b"
% Expansion is disabled, and implicit token doesn't take effect.
\begingroup
\let\implicitToken=b
\uppercase{\implicitToken}
\endgroup

原语\uppercase检查其参数(没有宏扩展,但这里无关紧要)并转换每个明确的字符标记转换为大写形式(存储在\uccode向量中)。它没有对隐式标记采取行动。

评论

存在不对称性:使用\let\implicitToken=b,测试\if\implicitToken b将返回 true。类似地,\ifcat将使用定义时当前字符的类别代码;例如

\let\implicitToken=b
\catcode`b=12
\ifcat\implicitToken a%
  \message{letter}%
\else
  \message{nonletter}%
\fi

letter将在控制台上打印,而\ifcat ba会打印nonletter

为什么会出现这种不对称?抱歉,只有 Donald Knuth 可以回答。隐式标记的最突出用法是和\bgroup\egroup它们可以在某些(并非所有)上下文中替代{和。我猜让它们在或}中进行转换会很烦人。\uppercase\lowercase

扩张

TeX 中的标记可以是可扩展的,也可以是不可扩展的。后一种标记在单独找到时,会直接传递给执行处理器。这是什么意思?让我们看一个例子。原语\dimen是不可扩展的。如果 TeX 找到\dimen2=12pt,它将传递\dimen给执行处理器;执行提示在输入流中搜索一个<number>、一个<optional equal>和一个合适的值(带扩展)。相反,在 中\advance\dimen2 by 2pt,标记\dimen被吸收作为 的参数进行\advance进一步处理。非活动(显式)字符标记是不可扩展的;活动字符可以是或不可以是,这取决于如何定义其含义。

哪些代币是可扩展的?很简单:

  1. 一些原语,例如条件、\string等等\noexpand
  2. ,即用\def\edef或定义\gdef的标记\xdef
  3. 标记\let等于可扩展标记。

由于您的\implicitToken不属于上述任何类型,因此无法扩展。

相关内容