考虑下面的代码。
\setbox0 \hbox{XXX}
\fbox{\copy0}
{
\setbox0\hbox{ZZZ}
{\wd0 0pt}
\fbox{\copy0}
}
\fbox{\box0}
这样就生成了三个带格框。两个 XXX 在格框内,而 ZZZ 不在格框内。
之后\wd0 0pt
,框 0 的宽度为 0,并且此分配是全局的,这解释了为什么 ZZZ 不完全在规则内。同时,分配是局部的,因为它不会影响包含 XXX 的框 0。
这种行为的目的是什么?或者说,能够设置当前组之外的框的尺寸有什么用处?
编辑:需要明确的是,这不是关于什么行为是,这是一个关于为什么Knuth 赋予了 TeX 这种行为。我认为它可能有用途,但 TeX by Topic 明确提到了这一点,所以我没有发现。我现在怀疑 Taco 的评论是正确的答案,即它只是一个实现细节,而不是设计目标。
答案1
我只是在这里猜测,但我相信盒子尺寸与每个盒子相关联。您没有专门的尺寸寄存器。这就是我相信这里发生的情况。进入第一个组后,在您分配 \setbox0\hbox{ZZZ} 时,TeX 会分配一个本地盒子寄存器。然后您进入第二个组,但您的盒子寄存器 0 仍然是相同的 \hbox{ZZZ},TeX 不会创建该盒子的本地副本。因此,当您将 0pt 分配给 \wd0 时,您会修改上一个组中的 \hbox{ZZZ}。
尝试像这样修改您的代码:
\setbox0 \hbox{XXX}
\fbox{\copy0}
{
\wd0 0pt
\setbox0\hbox{ZZZ}
{\wd0 0pt}
\fbox{\copy0}
}
\fbox{\box0}
看看会发生什么。
编辑:我认为以下行为与此相关:
\setbox0 \hbox{XXX}
\fbox{\copy0}
{
\fbox{\box0}
}
\fbox{\box0}
请注意,组内的 \box0 清空了盒子寄存器,它不会在组结束时恢复。
答案2
也许有人会想到将以下内容“翻译”为 C 语言:
box *box0 = alloc_hbox("XXX");
fbox(box0);
{
box *box0 = alloc_hbox("ZZZ");
{
/* only affects the box object pointed to by the *inner* box0 */
box0->width = 0;
}
fbox(box0);
}
fbox(box0);
内部声明box0
遮蔽了外部声明,这就是为什么修改对象内容(而不是指针)只会影响盒子ZZZ
。
答案3
正如 Jan 所说:盒子分配(\setbox
,,\copy
)\box
需要进行分组,盒子的宽度/高度/深度分配始终与特定盒子相连(这些存储在第一个盒子节点本身内)。
第二个\fbox{\copy0}
应该是\fbox{\box0}
,因为之后就不再使用了。 并且 中的分组{\wd0 0pt}
毫无用处,因为分组在这里毫无意义。
正如 Jan 所说。