为什么盒子维度分配既是局部的又是全局的?

为什么盒子维度分配既是局部的又是全局的?

考虑下面的代码。

\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 所说。

相关内容