创建一个填充剩余行的水平盒子 + 一些关于盒子的常见问题

创建一个填充剩余行的水平盒子 + 一些关于盒子的常见问题

我试图了解 TeX 中的盒子是如何工作的,我有一些问题,所有问题都与盒子有关(如果你认为最好创建 3 个问题,请告诉我,但我认为它们非常相关):

  1. 例如,我想知道,是否可以创建一个\hbox宽度填充行的其余部分的(有点像胶水\hfill,例如参见 tex 宏列表这里)?
  2. 另外,知道为什么代码\leaders\hrule\hfill.显示一行,但不显示代码\leaders\hrule\hfill(末尾没有字符)吗?
  3. 你知道我是否可以以某种方式移动代码(或类似代码):
    \hrule width \hsize
    \kern 1mm
    \hrule width \hsize
    
    \vbox{}它们显示在行尾?我可以使用和\leaders负空间实现类似的结果,但这并不实用,因为我不能只用一些空间“堆叠”行,而且我需要对要添加的每一行进行一些计算。

梅威瑟:

在此处输入图片描述

\documentclass[]{article}

\begin{document}

I can create stacked boxes like \vbox{\hbox{A}\hbox{B}} and \vtop{\hbox{A}\hbox{B}}.

I can also fill the rest of the line like \hrulefill.

I can also create a box of fixed width like \hbox to 3cm{\hrulefill}.

\textbf{Question 1}: But how can I create a hbox that fills the rest of the line? I tried this, but \verb|\hsize| is too big and \verb|\hfill| does not work: \hbox to \hsize{\hrulefill}.
\vspace{4mm}

I can also use leaders to repeat \verb|\hrule| until it fills \verb|\hfill|: \leaders\hrule\hfill.

\textbf{Question 2}: I don't know why, if I don't end the line with some char nothing is printed: \leaders\hrule\hfill


\vspace{4mm}

I am able to do something like that:

\hrule width \hsize
\kern 1mm
\hrule width \hsize

\vspace{1mm}
\textbf{Question 3}: Can I somehow put that code inside a \verb|\vbox| to get the same result, but at the end of the current line like:
\leaders\hrule height5pt depth-4.6pt\hfill % We draw a first rule that fills the line
\hskip 0pt plus -1fill % We come back at the beginning of the line
\leaders\hrule height0.4pt \hfill. % We draw a second line on top
\vspace{1mm}

The problem of the current solution is that I need to do some math to compute the correct height and depth of the rules, while I would prefer to directly specify the space between them using \verb|\kern| as above.

\vspace{3mm}


\end{document}

- 编辑 -

为了回答 Udo,如果我输入如下一行:

\textbf{Question 3}: \leaders\hbox{\vbox{\hbox{\leaders\hrule\hskip1pt}\vskip-11pt \hbox{\leaders\hrule\hskip1pt}}}\hfill\null

它确实与我想要的第 3 个问题的结果接近,只不过它实际上重复了一个小的(1pt)模式,直到填满当前行,而不是直接创建一个\hbox填充当前行的单个字符(因此问题 1 仍然没有得到解答)正因为如此,PDF 阅读器有时显示效果不佳,并添加这样的空白(参见行中间的空白):

在此处输入图片描述

但这个技巧很有趣,谢谢。我也很好奇:为什么-11pt这里需要负空间,但在问题 3 中我写的代码中却不需要?难道不能\vbox在不自动在行间添加大空间的情况下使用它吗?我试过了,\unskip但什么也没改变。

答案1

在本 TUGboat 第 65 页文章问题 1 的解决方案如下:段落应该以 结尾,\leaders\hrule\hskip\parfillskip\null而不是默认的\parfillskip。 (\null或者这里需要类似的东西;问题 2 已在评论中回答。)在段落末尾调用一些绘制线条的宏或\par重新定义。使用\vbox包含两个\hboxes 的 ,可以生成问题 3 的答案,因为\leaders不仅接受规则,还接受框。

水平盒子有尺寸,但问题 1 的答案需要胶水/引线而不是尺寸。第 344 页,示例 2,此 TUGboat文章表明原则上可以计算出最后一行较短的材料长度。然后经过一些计算,可以添加\hboxwith 关键字to和剩余距离来填充该行。但这太复杂了,因为结果可以通过如上所述的 glue/leaders 来实现。

下面是重新定义的普通 \TeX\ 的一些代码\par

\hsize=10cm

\def\lineatendofpar{\unskip\nobreak\endofparrule{\parfillskip=0pt\endgraf}}

\begingroup
\let\par=\lineatendofpar % be careful with \par from now on
% %%%
% first a single line
\def\endofparrule{\leaders\hrule\hskip\parfillskip\null}%
%
Hello

% %%%
% second two lines
% to make sure that there is no space between the boxes in pdf screen
% display they overlap a little bit
\def\endofparrule{\leaders\hbox to 0.9pt{\vbox{\hbox{\leaders\hrule\hskip1pt }%
                                   \vskip-11pt % -(\baselineskip - rule distance)
                                   \hbox{\leaders\hrule\hskip1pt }}\hss}%
                           \hskip\parfillskip\null}%
%
Goodbye

\endgroup

\bye

答案2

您可以使用linegoal

\documentclass{article}
\usepackage{linegoal}

\newcommand{\linestoend}{%
  \leavevmode\vbox{%
    \dimen0=\linegoal
    \hrule width \dimen0
    \vskip3pt
    \hrule width \dimen0
  }%
}
\newcommand{\boxtoend}{%
  \leavevmode
  \hbox{\vrule\kern-0.4pt\linestoend\kern-0.4pt\vrule}%
}

\begin{document}

Here we have a long text that should break across lines and
end up with two lines up to the right margin.\linestoend

Here we have a long text that should break across lines and
end up with a box up to the right margin.\boxtoend

\end{document}

在此处输入图片描述

答案3

如果您想将段落末尾的框设置到 par-fill 空间中,那么您可以在打印之前使用\predisplaysize原始寄存器测量段落。

\newdimen\tmpdim
\def\parwithrules#1\par{\par
   \setbox0=\vbox{#1$$\global\tmpdim=\dimexpr\hsize-\predisplaysize+2em$$}
   #1\unskip\vbox{\hrule width\tmpdim\kern1mm\hrule}\par
}

\parwithrules
Here we have a long text that should break across lines and
bla bla bla bla end up with two lines up to the right margin.

\bye

相关内容