为什么 \baselineskip 没有插入到 \unvbox 之前?

为什么 \baselineskip 没有插入到 \unvbox 之前?

似乎\setbox0=\vbox{\hbox{abc}}\unvbox0不等同于:在以下情况下,\hbox{abc}前者不插入。\baselineskip

\vbox{% 
  \hbox{XY}% 
  \hbox{abc}% 
  \hbox{def}
}

\vbox{% missing baselineskip before \unvbox0
  \hbox{XY}%
  \setbox0=\vbox{\hbox{abc}}%
  \unvbox0
  \hbox{def}
}

解决方案可能是

\vbox{% the baselineskip is inserted when we write \box0, then remove it.
  \hbox{XY}%
  \setbox0=\vbox{\hbox{abc}}%
  \box0
  \setbox2=\lastbox
  \unvbox2
  \hbox{def}
}

但这真的是正确的做法吗?

\halign供参考,我正在尝试使用手工制作的框来模拟的行为,我不认为我能将\hbox{abc}(对应于行)直接放在当前垂直列表中,因为需要读取所有行并且粘连保持未设置,直到到达表格末尾,我们才能知道每列的宽度。重置粘连需要我浏览行框列表,\unhbox然后\unhbox重新设置\hbox每个单元格等。

\bye

答案1

在 的开头,\vbox该参数\prevdepth设置为 -1000pt,当您这样做时\unvbox,此值会抑制行间粘连。您必须\prevdepth在 中恢复正确的值\vbox

\showboxbreadth=1000
\tracingonline=1

\setbox0=\vbox{
  \hbox{XY}
  \hbox{abc}
  \hbox{def}
}

\showbox0 \box0

\setbox0=\vbox{
  \hbox{XY}\dimen255=\prevdepth
  \setbox0=\vbox{\prevdepth=\dimen255 \hbox{abc}}
  \unvbox0
  \hbox{def}
}

\showbox0 \box0

答案2

与明确跟踪不同的解决方案\prevdepth是使用\lastbox:此原语从当前列表中删除最后一个框(此处\hbox{abc}),并且由于我们不对其进行任何操作,因此将其放回列表中。然后,TeX 使用正确的值插入基线跳过\prevdepth(即使在我手动更改\prevdepth之后的奇怪情况下\hbox{XY})。

当然,这个解决方案不如 egreg 的答案通用,因为它只有当保存的盒子包含一个盒子时才有效(在我的情况下确实如此)。

\showboxbreadth=1000
\tracingonline=1

\setbox0=\vbox{
  \hbox{XY}
  \hbox{abc}
  \hbox{def}
}

\showbox0 \box0

\setbox0=\vbox{
  \hbox{XY}
  \setbox0=\vbox{\hbox{abc}}
  \unvbox0
  \lastbox % <= this
  \hbox{def}
}

\showbox0 \box0

相关内容