5

I'm trying to understand how boxes work in TeX, and I've some question, all related with boxes in general (if you think it's better to create 3 questions, let me know, but I think they are quite related):

  1. For example, I would like to know, is it possible to create a \hbox whose width fills the rest of of the line (a bit like a glue \hfill, see for example a list of tex macros here)?
  2. Also, any idea why the code \leaders\hrule\hfill. displays a line, but not the code \leaders\hrule\hfill (no char at the end)?
  3. Do you know if I can somehow move the code (or similar):
    \hrule width \hsize
    \kern 1mm
    \hrule width \hsize
    
    into a \vbox{} to display them at the end of a line? I can achieve similar result with \leaders and negative spaces, but it's not as practical since I can't just "stack" lines with some space and I need to do some math for every line to add.

MWE:

enter image description here

\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}

-- EDIT --

To answer to Udo, if I put a line like:

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

it does indeed something close to the result I want for question 3, except that what is actually does is that it repeats a small (1pt) pattern until it fills the current line, instead of directly creating a single \hbox that fills the current line (so question 1 is still left un-answered). Because of that, the PDF reader sometimes displays it poorly and adds white space like that (see the white space in the middle of the line):

enter image description here

But the trick is interesting, thanks for that. I'm also curious: why is the negative -11pt space required here but not in the code I wrote in question 3? Isn't it possible to use \vbox without automatically adding a large space between lines? I tried to \unskip but it does not change anything.

5
  • 1
    As to #2, \hfill needs an anchor against which to push. Mar 24, 2021 at 0:46
  • @StevenB.Segletes oh I see thanks. Is \null the typical anchor?
    – tobiasBora
    Mar 24, 2021 at 0:54
  • Typically, \mbox{} Mar 24, 2021 at 1:15
  • 2
    @StevenB.Segletes -- Even though the example uses \textbf, the tag is tex-core, so \null is the answer that better matches the tag. Mar 24, 2021 at 4:10
  • @tobiasBora -- Regarding #3, you could probably cobble together a \vbox into which parallel rules could be set with a simple skip between them, but I think you'd have to specify the width (\hsize), so arithmetic would still be involved. Mar 24, 2021 at 4:18

3 Answers 3

5

On page 65 of this TUGboat article a solution for question 1 is shown: A paragraph should end with \leaders\hrule\hskip\parfillskip\null instead of the default \parfillskip. (\null or something similar is required here; question 2 has been answered in the comments.) Either at the end of a paragraph some macro is called that draws the line or \par is redefined. With a \vbox that contains two \hboxes an answer for question 3 can be produced as \leaders do not only accept rules but also boxes.

Horizontal boxes have a dimension but the answer of question 1 requires glue/leaders not a dimension. Page 344, example 2, of this TUGboat article shows that it is in principle possible to compute the length of the material in a short last line. Then after some computation an \hbox with keyword to and the remaining distance can be added to fill the line. But that is much too complicated as the result can be achieved with glue/leaders as described above.

Here is some code for plain \TeX\ that redefines \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
3
  • Thanks for you answer. However, as far as I understand, this does not exactly answers question 1: instead of creating one big hbox that fills the line, it duplicates many very small hbox of 1pt until it fills the line right? (see my edit for more details) So question 1 is still not answered, but the trick already helps to answer Q.3, so thanks for that (+1 for now, if I can't find any answer to Q.1 I will accept it later). Does that mean that it is impossible to create a single \hbox that spans a whole line?
    – tobiasBora
    Mar 27, 2021 at 17:33
  • Also, why is \vskip-11pt required in vbox? Its not possible to specify directly the space between in lines? I tried to use \unskip to remove the space added automatically by \vbox, but the space is still here. I don't really like this idea of putting approximate negative space since it's always a rough estimate of the exact space that is required: here the line may not be spaced by exactly 1mm.
    – tobiasBora
    Mar 27, 2021 at 17:35
  • @tobiasBora (1) A \hbox has only a dimension; a whole line is reached by \hbox to \hsize which is abbreviated by \line. But if a line has material in it the width that the hbox should have must be calculated. I added some text to my answer. (2) The -11pt is the difference between \baselineskip (12pt) and the distance for the two rules. Try -10pt to have 1pt more white space between the rules. (3) To satisfy the pdf display I let the \hboxes for the 3rd question overlap; I can test it myself but I assume it improves the display. Mar 27, 2021 at 19:48
0

You can use 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}

enter image description here

0

If you want to set the box at the end of the paragraph into the par-fill space then you can measure the paragraph before printing using \predisplaysize primitive register.

\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

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .