设置\tracingassigns
为正值会导致 eTeX 将\tracingonline
其执行的所有分配写入日志文件(如果为正值,则写入控制台)。因此,我希望以下代码指示\foo
从 更改undefined
为select 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”)。