\tracingassigns 与 \font 的奇怪输出

\tracingassigns 与 \font 的奇怪输出

设置\tracingassigns为正值会导致 eTeX 将\tracingonline其执行的所有分配写入日志文件(如果为正值,则写入控制台)。因此,我希望以下代码指示\foo从 更改undefinedselect font cmr10

\tracingonline=1
\tracingassigns=1
\font\foo=cmr10
\message{But \foo is \meaning\foo!}

然而,eTeX 报告

{changing \foo=undefined}
{into \foo=select font nullfont}
But \foo is select font cmr10!

为什么?

答案1

Knuth 在 TeXbook 第 278 页提到了这种机制:

\TeX\ 采取预防措施,使得诸如 ' \chardef\cs=10\cs' 和 ' ' 之类的构造在分配完成之前\font\cs=name\cs不会扩展第二个。\cs

如果你添加

\chardef\cs=63

你会在日志中发现

{changing \cs=undefined}
{into \cs=\relax}
{changing \cs=\relax}
{into \cs=\char"3F}

然而,显然,“选择字体 nullfont”到“选择字体 cmr10”的含义变化没有被追踪到,这可能是 e-TeX 的一个错误。

为什么需要采取这样的预防措施?当 TeX

\font\foo=<filename>

它对符号后面的内容进行扩展=。如果\foo出于某些原因, 已经被定义为宏,则代码如下

\font\foo=cmr10\foo

可能会导致灾难。因此,首先,TeX 将 的含义更改\foo为不可扩展的标记,确切地说是\nullfont。因此,后面的\foo标记将停止扩展,并且可以执行真正的赋值。

如果\chardef\cs=63我们处于同样的情况:

\chardef\cs=63\cs

如果我们之前有的话,这将是灾难性的。因此,TeX 首先将的含义\def\cs{1}分配给,并且可以执行分配而不必担心可能会扩展。当 TeX再次读取时,它已经具有 所分配的含义。\cs\relax\cs\cs\chardef

更新

这是由于 Don 的典型(当时有效)优化之一而导致的 e-TeX 错误。eTeX 更改文件\tracingassigns通过模块 §277 中的程序接口实现eq_define(),并且 §1257 中的“nullfont”的分配使用此程序完成。但是,(这是 Don 节省一些计算机周期的方法 :-) 第二个分配是通过直接调用该程序完成的,该程序equiv()通常不用于分配,因为它只更改指针但不设置“类型”(当然仍然是“selectfont”)。

相关内容