# Controlling text overflow when using \hfill to left- and right-align parts of title

I’m creating a template in plain (Xe)TeX which must have, in the first line, a location and reference number. The location is left-aligned and the reference number is right-aligned. (See example 1, below.)

If both of these are short, I can just use:

{\it Location}: UK \hfill {\it Ref}: Xyz


However, if either of these are so long that TeX cannot fit them both into the same line, it overflows the reference number onto the next line (example 2).

Usually this is the best way of dealing with the problem of too much text in one line but because of the way these documents will eventually look, it is not what I would like.

What I’d prefer is for the first half to overflow onto the next line so that the reference number is always entirely on the first line (example 3). This would be relatively easy if the reference number was always static in size but it can change quite a lot (e.g. example 4).

Is there an obvious way of doing this within plain TeX? I can't think of a good way of approaching this problem, short of putting the reference number in a box, calculating its size, subtracting that from the line width and putting the other number into a box of that width, which seems like quite a complex method.

Any pointers as to a method gratefully received. Thanks!

-
You can use a tabular environment with breakable columns. –  Marco Daniel Dec 18 '11 at 12:03
I’m not sure I can in plain TeX, I’m afraid. I did look at eplain’s \makecolumns command, but I’m not sure it is flexible enough to do what I want here. –  JacobH Dec 18 '11 at 12:12

Here is a starting point. The problem that is not solved is Example 4 because I don't know how to make the long reference extend to the left into the address block.

For demonstration purposes I have limited the overall width to 8cm but you could easily set it to \hsize.

\documentclass{article}

\def\locref#1#2{\hbox to 8cm
{\vtop{\hsize=4cm\noindent\raggedright {\it Location:}\hfill #1}

\begin{document}
\locref{UK}{12345453}

\locref{London, Oxford Street, UK}{12345453}

\locref{London, Oxford Street, United Kingdom}{12345453}

\locref{London, Oxford Street, United Kingdom}{12345453-123454}

\locref{London, Oxford Street, United Kingdom}{12345453-12345453-12345453}
\end{document}


-
You can combine the hbox with a vbox to allow line breaks. (I hope this is want you mean): \def\locref#1#2{\hbox to 8cm {\vbox{\hsize=4cm\noindent\raggedright {\it Location:}\hfill #1}} \hfill\vbox{\hsize=3cm\quad{\it Ref:} #2}} –  Marco Daniel Dec 18 '11 at 13:17
@Marco: In the examples for desired behavior the reference is never wrapped but extends to the left into the address block. Therefore I only used a vbox for the address block. Nevertheless, this seems like a good idea. –  Christian Lindig Dec 18 '11 at 13:20
Thank you for the suggestion; the problem here is that the left-hand block has to have a pre-determined size (e.g. \hsize=4cm). I suppose the only way to do this with the flexibility I need will be to calculate that size in reference to the right-hand block. –  JacobH Dec 18 '11 at 13:30

We can use the \parshape primitive, together with a ragged right shape. The command \parshape must be followed by an integer n and n pairs of dimensions; say

\parshape 3
0pt 3cm
4pt \dimexpr 3cm+4pt\relax
8pt \dimexpr 3cm+8pt\relax


will give a paragraph shape where the first line starts at the left margin and is 3cm long, the second line starts 4pt right of the left margin and is 3cm+4pt long, the third line is pushed a bit more to the right and is a bit longer. Lines after the third will follow the same specification as the third.

In our case we need zero indentation, but the first line must have a shorter length in order to accommodate the reference. We can measure the width of the reference and add a clearance, say 1em: with

\setbox0=\hbox{{\it Ref\/}: #2}


we'll have available the reference's width, so

\parshape 2 0pt \dimexpr\hsize-1em\relax 0pt \hsize


will produce a paragraph leaving as much space as needed.

\def\entry#1#2{% #1 = location -- #2 = ref
\setbox0=\hbox{{\it Ref\/}: #2}%
\vbox{\parindent=0pt % no indent
\rightskip 0pt plus 6em % raggedright
\spaceskip .3333em \xspaceskip .5em\relax % no flexible space
\language255 % no hyphenation
\hsize=5.5cm % overall size
\parshape=2 0pt \dimexpr\hsize-\wd0-1em\relax 0pt \hsize
\leavevmode\rlap{\line{\hfil\box0}}{\it Location\/}: #1\par}}

\entry{UK}{Xyz}
\medskip
\entry{Oxford Street, UK}{Xyz}
\medskip
\entry{Oxford Street, UK}{Xxxx Yyyy Xyz}
\bye


Some more adjustments are done: for example a stronger \rightskip than that given by \raggedright (some experiments to find the best dimensions are needed). The reference is put at the beginning with \rlap{\line{\hfill\box0}} so that it will be placed flush with the right margin, yet not taking up space.

-
Could you explain the \parshape=2? Very nice code! –  Christian Lindig Dec 18 '11 at 13:48
That's really helpful. Thank you. It’s also the first practical use of \parshape I’ve come across.The command I wasn’t familiar with is \dimexpr (which doesn’t seem to be the TeXBook) but which seems quite a useful way of solving these sorts of issues. –  JacobH Dec 18 '11 at 23:06
@JacobH \dimexpr is an e-TeX extension; one could avoid it, but it makes things easier. –  egreg Dec 18 '11 at 23:20
@egreg -- the break between "Oxford" and "Street" isn't wonderful. could be overcome by putting a tie between them, but maybe a measuring or boxing step could avoid that manual adjustment. encouraging line-breaking to occur preferentially at spaces following commas could be another tactic; that would reduce the need for manual exception handling. –  barbara beeton Dec 19 '11 at 15:27

Could you use a \halign? For example, if you need tight columns with line-breakability, you could have a \vbox in the preamble:

\newdimen\locwd
\locwd=3cm
\newdimen\refwd
\refwd=3cm
\halign{\vbox{\parindent0pt\hsize\locwd\raggedright{\it Location\/}: #\hfil}&