Let's look at the simplest case
\hbox to \hsize{<horizontal material>}
Among the <horizontal material>
there will be also glue, implicit (that is, space tokens) or explicit (\hskip
commands).
TeX maintains two four dimensional vectors in order to compute the glue ratio, say v for the stretching and w for the shrinking. A glue such as
\hskip 4pt plus 2pt minus 1pt
contributes 2pt to the first component of v and 1pt to the first component of w. A glue such as
\hskip 6pt plus 1fil minus 0.5fill
contributes 1 to the second component of v and 0.5 to the third component of w. At the end we'll have
v=(finite, first order infinite, second order infinite, third order infinite)
and similarly for w, where the components are the sum of all contributions. TeX also maintains the sum of the natural widths of characters, boxes and glues in the <horizontal material>
.
When TeX has finished gathering the material for the \hbox
, it compares the natural width to the desired box width (in our example to \hsize
) and decides what to do. If the natural width is equal to the desired width, it typesets the box. Otherwise it decides that it has to stretch or shrink the glue. In the former case it looks at v and in the latter to w.
Let's look at the stretching case (the other is similar). If v is zero, there' little to do: there's no glue or the glues all cancel with each other: the box will be underfull.
Otherwise one entry in v will be different from zero; TeX will choose the rightmost non-zero component. This is the order of infinity that wins (it may be the "finite" component). The excess space to fill is then distributed proportionally among the glues that contributed that order of infinity.
Let's look at some examples
\hbox spread 3cm{A\hskip 4pt plus 2pt minus 1pt
B\hskip 4pt plus 1fil minus 1pt
C\hskip 4pt plus 2fil minus 1pt
D}
The box must stretch by 3cm (it's a convenient syntax for doing experiments of this kind), so we have to compute v=(2pt,3,0,0). The first-order infinity wins, so the excess space will be divided adding 1cm between B and C, and 2cm between C and D; between A and B there will be a 4pt wide space (no stretching). The result is ( denotes the resulting space)
A<4pt>B<4pt+1cm>C<4pt+2cm>D
Let's see with
\hbox spread 3cm{A\hskip 4pt plus 2pt minus 1pt
B\hskip 4pt plus 1fill minus 1pt
C\hskip 4pt plus 2fil minus 1pt
D}
Here v=(2pt,2,1,0), so the second-order infinity wins and the 3cm wide space will go between B and C:
A<4pt>B<4pt+3cm>C<4pt>D
Third order infinities are rarely used, but they are there for emergency cases when one has to cancel second order infinities.
The coefficient before fil(ll)
should be a decimal number less than 16384 in absolute value (there must be one). The minimum non-zero value is 2^(-16)=0.000015
, so saying 0.000014filll
is equivalent to say 0filll
(and useless, of course).
TeX has some primitives equivalent to glue specifications:
\hfil = \hskip 0pt plus 1fil minus 0pt
\hfilneg = \hskip 0pt plus -1fil minus 0pt
\hss = \hskip 0pt plus 1fil minus 1fil
\hfill = \hskip 0pt plus 1fill minus 0pt
The same algorithm is used for shrinking, but no glue will be stretched to become less than its natural width, while all glues may be used for stretching (possibly resulting in an underfull box). The same holds for vertical boxes.
\vskip
rather they are TeX primitives that are "essentially equivalent" to those\vskip
s. I'm not sure whether there is any significant difference, and why Knuth chose to implement these as primitives instead of macros. Perhaps I should ask a separate question....