Practical uses for skips with negative stretch or shrink components
As @egreg mentioned in comments, they are usually paired with equal positive values.
plain and latex both have
\def\filbreak{\par\vfil\penalty-200\vfilneg}
if the break happens the negative stretch is thrown away at the top of the next page, but if it does not happen, it counteracts the fil
space before the penalty leaving zero total stretch.
In short, negative stretch and shrink can be combined with positive ones to “cancel out”, as mentioned by @egreg and @David. This makes it possible for the line-breaking algorithm to automatically make some complex choices.
That's really the full answer, but just to elaborate: There are some examples in The TeXbook, but such things are explained and organized better in the paper Breaking Paragraphs into Lines by Knuth and Plass (you can find it online; also reprinted in Digital Typography with some minor corrections).
The first example given in the paper is:
Although the box/glue/penalty model appears at first glance to be oriented solely to the problem of justified text, we shall now see that it is powerful enough to be adapted to the analogous problem of unjustified typesetting: [...] The idea is to let spaces between words be represented by the sequence
glue(0,18,0)
penalty(0,0,0)
glue(6,-18,0)instead of the ‘glue(6,3,2)’ we used for justified typesetting. [...] If a break occurs at the penalty, there will be a stretchability of 18 units on the line, and the ‘glue(6,-18,0)’ will be discarded after the break so that the next line will begin flush left. On the other hand if no break occurs, the net effect is to have glue(6,0,0), representing a normal space with no stretching or shrinking.
Note that the stretchability of -18 in the second glue item has no physical significance, but it nicely cancels out the stretchability of +18 in the first glue item. Negative stretchability has several interesting applications, so the reader should study this example carefully before proceeding to the more elaborate constructions below.
To reproduce the above (sort of) with TeX syntax, compile the following with pdftex
:
\def\randomword{\ifcase\pdfuniformdeviate6 one\or two\or three\or four\or five\or six\fi}
\def\oneword{\randomword\hskip 0pt plus 18pt\penalty 0\hskip 3.333pt plus -18pt\relax}
\def\tenwords{\oneword \oneword \oneword \oneword \oneword \oneword \oneword \oneword \oneword \oneword}
\def\paragraph{\tenwords \tenwords \tenwords \tenwords \tenwords \tenwords \tenwords \tenwords \tenwords \tenwords}
\hsize=4.5in
\paragraph
\bye
to get something like:
(This is not how \raggedright
is implemented in TeX—that uses \rightskip
—but this one adds stretchability on each line instead of constant space between words.)
As the paper goes on to show, the same idea can be used for inserting optional hyphens in ragged-right paragraphs, and for “ragged-centered” paragraphs:
\def\randomword{\ifcase\pdfuniformdeviate6 one\or two\or three\or four\or five\else six\fi}
\def\oneword{%
\randomword
\hskip 0pt plus 18pt
\penalty 0
\hskip 3.333pt plus -36pt\relax
\hbox{}
\penalty 10000
\hskip 0pt plus 18pt
}
\def\tenwords{\oneword \oneword \oneword \oneword \oneword \oneword \oneword \oneword \oneword \oneword}
\def\paragraph{%
\noindent
\hskip 0pt plus 18pt
\tenwords \tenwords \tenwords \tenwords \tenwords \tenwords \tenwords \tenwords \tenwords \tenwords \randomword
\hskip 0pt plus 18pt
\penalty -10000
}
\hsize=4.5in
\paragraph
\bye
— the idea is that if the break at the \penalty 0
is taken, then the line being broken ends with a glue of \hskip 0pt plus 18pt
and the next one starts with \hbox{}\penalty 10000\hskip 0pt plus 18pt
(so basically, that amount of stretch), while if the break is not taken, then all the glues cancel out.
Then this idea is used for typesetting computer programs at different widths simply by changing \hsize
and nothing else:
(Knuth wrote a preprocessor to generate the TeX files for these PASCAL programs; it was called BLAISE.)
Finally,
The final application of line breaking that we shall study is the most difficult one that has so far been encountered by the authors; it was solved only after acquiring more than two years of experience with more straightforward line-breaking tasks, since the full power of the box/glue/penalty primitives was not immediately apparent.
And this is to typeset a certain index and get any of the following simply by varying \hsize
:
The features here in each entry are:
There's a name (possibly too long to fit on a line), followed by dot leaders, followed by a list of review numbers (possibly too long to fit on a line).
All lines after the first should be indented (hanging indentation).
The name part, if broken, should be left-aligned (ragged-right); the numbers part, if broken, should be right-aligned (ragged-left) with indentation.
If the dot leaders end a line, they should stop at a certain distance before the end of line; also the ragged-right lines should have a max width a certain (other) distance before the end of line.
Minimize whitespace, and (secondarily) minimize the number of lines for the numbers.
There's a way to achieve all this while keeping the input simply something like:
ACM Symposium on Theory of Computing, Eighth Annual (Hershey, %
Pa., 1976)\:1879, 4813, 5414, 6918, 6936, 6937, 6946, 6951, %
6970, 7619, 9605, 10148, 11676, 11687, 11692, 11710, 13869
and negative stretch and shrink are involved in the solution: see the paper, or see the section “7. Paragraph maneuvers” in Appendix D: Dirty Tricks of the TeXbook, page 392–394. The paper goes on to give an “algebra” that can help one come up with the right tricks for such tasks.
The same idea also applies to page-breaking; see \beginsection
in plain.tex
, or \vfilneg
, or the package needspace
.
maybe not exactly what is requested, but an absolute negative skip is useful in creating composite symbols, e.g.
x \rightarrow\mskip-15mu\rightarrow\mskip-15mu\rightarrow y
will give you
it's also instructive to notice that \llap
, \rlap
, \clap
and their vertical friends are all based on \hss
or \vss
which are primitives defined with infinite (positive) shrink and stretch. \llap
is immensely useful for positioning page numbers flush right in a table of contents. and marginal notes couldn't exist without these facilities.