7

What is a good way to create blank space (preferably, underlined -- it is to be filled in by hand when document is printed) that takes up all the remaining space on a line. The blank space may appear at the beginning, in the middle or at the end of the line; it may also occupy the whole line.

I would appreciate a solution that survives changing the font and font size of surrounding text, as well as the size of page and page margins.

UPDATE: I am looking for a solution with Knuth's TeX and plain TeX.

UPDATE 2: I find egreg's suggestion that blanks have a minimum length a good one. However, in this case it would be very convenient if blanks can be broken across lines (automatically, of course) in cases where the blank is too long to fit on current line and has to be broken up either because it is longer than the line or because text on that line is too short and would result in an underfull box if left alone.

UPDATE 3:

Types of fill-in blanks I need:

1) unbreakable blanks of a specified fixed length; (egreg already provided an elegant solution to this case here)

2) breakable blanks of a specified fixed length;

3) breakable blanks no shorter than a specified minimum length. These are the same as type 2 blanks except that the last part of a broken blank (or the whole blank when it is not broken) should expand and take up all the available space on its line (like \hrulefill).

3

If you need to break the underlined space with given size to two parts at the end of the line (sum of the parts is approximately the given size) then there is a solution:

\newcount\tmpnum \newdimen\tmpdim

\def\uelement{\hbox{\vrule height-1pt depth1.4pt width5pt}\penalty0 
    \hskip0pt minus.1pt \relax}
\def\softelement{\leaders\vrule height-1pt depth1.4pt\hskip 0pt plus5pt\relax}

\def\underlined#1{\bgroup
  \tmpdim=#1 \divide\tmpdim by327680 \tmpnum=\tmpdim
  \leavevmode \softelement
  \loop \ifnum\tmpnum>0\advance\tmpnum by-1 \uelement \repeat
  \softelement \egroup
}

First \underlined{5cm} second.

First \underlined{20cm} second.

\bye

broken underlined space

The code above implements the type 2 of the breakable blanks, as mentoned in the Update 3 of the question. The type 3 can be simply implemented by adding the \ufill macro:

\def\ufill{\leaders\vrule height-1pt depth1.4pt \hfill}.

First \underlined{5cm}\ufill second.

First \underlined{20cm}\ufill second.
  • Out of curiosity: why do you need a space before the closing brace in the definition of \uelement and a \relax in the definition of \softelement? – SJU Jun 4 '14 at 12:24
  • Space delimits the number zero. I am sure that the \penalty0 command is closed when the space is here. And \relax delimits the \hskip primitive. – wipet Jun 4 '14 at 13:02
  • What is the point of surrounding each run of \uelements with two \softelements provided that it is natural to have a space before \underlined and a space or a punctuation mark after it? – SJU Jun 4 '14 at 13:23
  • Also, is there any specific reason for choosing 5pt as the length of a \uelement? – SJU Jun 4 '14 at 13:29
  • \softelement may be removed if there is another elastic glue. The 5p piece defines the precision of the result. It means that the given dimension is rounded to multiply of 5pt pieces. You can set it to another value but you have to change the \divide constant too. The given dimension in sp (i.e. 2^16 pt) is divided by this constant in order to reach the number of pieces to be printed. – wipet Jun 4 '14 at 14:08
13

Plain TeX only: the macro \filltoend will fill a line.

  • If the argument is empty, no minimum width is required (which can then be zero),
  • if the argument is non empty, it should be the minimum required length.
\def\filltoend#1{%
  \leavevmode % in case it's at the beginning of a line
  \hbox{}% something not discardable
  \nobreak % no line break here
  \leaders\hrule\hskip \if\relax#1\relax 0pt \else #1\fi plus 1fill\relax % the rule
  \hbox{}% something not discardable
}

\parindent0pt

Here is some text \filltoend{} to the end

\filltoend{}

\filltoend{}

Some more text that goes up to the end of the line which
is not as long as the first but is far too short \filltoend{}

Some more text that goes up to the end of the line which
is not as long as the first but is far too short \filltoend{2cm}

\bye

Note that in the last case the whole line is filled, because no text follows.

enter image description here

  • Seems to work great! But can we have blanks that "hyphenate" for cases where a blank is too long to fit on current line and has to be broken up either because it is longer that line or because text on the line is too short and would result in an underfull box if left alone, e.g.: My address is: \filltoend{20cm}. – SJU May 28 '14 at 12:46
  • @AngelTsankov That's much more difficult, I think. You need to know how far you are in a line, which can be done with \pdfsavepos in pdftex, but needs at least two runs and writing in an auxiliary file. – egreg May 28 '14 at 14:06
  • How about blanks of fixed width or blanks with a minimum and a maximum width? These can be used for data whose length is known in advance, e.g. dates? – SJU May 29 '14 at 9:54
  • What is the purpose of the \hboxs in the definition of \filltoend? – SJU Jun 5 '14 at 14:54
  • @AngelTsankov They are used so the leaders don't disappear at line breaks. – egreg Jun 5 '14 at 14:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.