我正在尝试测量一个的宽度\hskip
。我尝试过类似
\ExplSyntaxOn
a
\skip_horizontal:N 10pt plus 1fill
\box_set_to_last:N \l_tmpa_box
b\par
\the\box_wd:N \l_tmpa_box
\ExplSyntaxOff
但\l_tmpa_box
宽度似乎为零。我以为\hskip
一旦排版完成,它就会变成一个框,但也许我误解了什么。
无论如何,我知道如何使用\tikzmark
两次编译来测量宽度。但是,我想知道是否可以在一次编译中直接完成。
答案1
该函数\box_set_to_last:N
本质上是 TeX 原语\lastbox
,并且调用如下
\box_set_to_last:N \l_tmpa_box
是相同的
\setbox\l_tmpa_box=\lastbox
TeXbook 对此是这样说的:
上表底部的行指的是
\lastbox
,这是之前没有提到过的一个基本操作。如果当前水平列表或垂直列表的最后一项是 hbox 或 vbox,则将其从列表中移除并变为\lastbox
;否则\lastbox
为空。此操作在内部垂直模式、水平模式和受限水平模式下允许,但您不能使用它在垂直模式下从当前页面中获取框。在数学模式下,\lastbox
始终为空。在段落开头,'{\setbox0=\lastbox}
' 会删除缩进框。
因此您的尝试失败了,因为当前水平列表中的最后一项是跳过。
然而,
a\setbox0=\lastbox\hskip 10pt plus 1fill
将导致\box0
宽度为零;更准确地说,它将为空,因为最后一项不是 hbox 或 vbox,而是字符。
你不能检测段落被吸收时的最终跳过量,因为拉伸或收缩发生在段落被分成行时的后期阶段。
答案2
如果您事先知道该行右侧包含什么,那么您可以执行以下操作。
这塔托包定义了一个命令\tabto
,该命令会跳转到一行中的特定位置,以及一个\CurrentLineWidth
包含调用该命令时行宽的长度。此外,\tabto
还将上次调用的位置存储在一个长度中\TabPrevPos
。因此,如在https://tex.stackexchange.com/a/541683/89417(由包作者回答),您可以“跳转”到当前宽度(这不会导致位置发生变化),然后执行\hskip
,然后通过从线宽中减去右侧和第一个位置的宽度来计算跳过的宽度。此计算仅需要一次编译。
梅威瑟:
\documentclass{article}
\usepackage{showframe}
\usepackage{calc}
\usepackage{tabto}
\newlength{\hskiplen}
\newlength{\firstpos}
\newlength{\secondpos}
\newsavebox{\rhs}
\begin{document}
\sbox{\rhs}{xyz}
abc\hskip10pt plus 1fill xyz
abc\tabto{\CurrentLineWidth}\hskip10pt plus 1fill\setlength{\firstpos}{\TabPrevPos}\setlength{\secondpos}{\linewidth-\wd\rhs-\TabPrevPos}\usebox{\rhs}
first position: \the\firstpos
second position: \the\secondpos
\setlength{\hskiplen}{\secondpos-\firstpos}length of hskip: \the\hskiplen
width of rhs: \the\wd\rhs
\end{document}
结果:
请注意,这实际上绕过了原始问题,因为您不是在测量 hskip 本身,而是测量行中的所有其他元素。实际上很难测量使用\hskip
填充创建的框,因为宽度取决于行的其余部分,因此在实际命令之后该框尚不可用(我认为……)。您可以尝试 LuaLaTeX 是否可以提供有关完整框列表的更多信息,请参阅https://www.overleaf.com/learn/latex/Articles/Pandora%E2%80%99s_%5Chbox%3A_Using_LuaTeX_to_Lift_the_Lid_of_TeX_Boxes以获得一些指点。