10

One is often taught that "\\ causes a line break which is not a paragraph break" and "the variant \\* additionally prevents a page break".

(I hereby acknowledge user egreg's admonition that "\\* should not be used".)

But \\* often doesn't work! When does \\* not work? How can one fix this?

The following code produces a footnote example and then a body text example. Note that usage of \\* within body text is probably more common.

\documentclass{article}
\usepackage{lipsum}


\begin{document}

\lipsum[1-4]\footnote{
  no asterisk \\ asterisk \\*
  no asterisk \\ asterisk \\*
  no asterisk \\ asterisk \\*
  no asterisk \\ asterisk \\*
  no asterisk \\ asterisk \\*
  % the pagebreak happens here
  last line}
\lipsum[5]


\lipsum[6-8]
\lipsum[2]

Line 1 \\*
  % the pagebreak happens here
Line 2 \\*
Line 3 \\*
Line 4 \\*
Line 5 \\
Line 6

\end{document}
  • Guide to the accepted answer: The answer to the when is intricate and has to do with penalties. (Above I've intentionally asked in a vague and open-ended way because a non-expert will know little about TeX's penalties, and maybe this is how it should be.) The/an answer to the how to fix is Heiko Oberdiek's excellent \NLS ("newline with star") macro, which simulates \\* (but has a potential side effect related to widows and orphans, explained in his answer). – Lover of Structure May 24 '14 at 10:44
15

Theory

\\* throws an error if used in vertical mode; in horizontal mode it does the following actions:

\unskip        % remove any preceding spaces
\vadjust{\penalty 10000}% \nobreak in vertical mode after this line
\penalty 10000 % \nobreak in horizontal mode
\hfil          % fill current line
\penalty-10000 % force line break

Thus it looks as if there was a \nobreak in vertical mode between the two lines that prevents a page break.

However, what happens if TeX puts the lines of a paragraph in the vertical list?

  • It inserts interline glue between the boxes (depending on the values of \baselineskip, \lineskiplimit, and \lineskip). Glue after a non-discardable item would constitute a break point.

  • Therefore TeX adds a penalty before the interline glue to control the page breaks. This penalty is \interlinepenalty plus some other penalties depending on the context (\clubpenalty, \widowpenalty, \displaywidowpenalty, \brokenpenalty). Then the break point is this penalty, not the interline glue.

The penalty added via \vadjust is put right after the current line before the interline penalty and interline glue. Thus we have:

\hbox                         % the line
\penalty10000                 % \nobreak via \vadjust
\penalty\interlinepenalty+... % interline penalty
\vskip                        % interline glue
\hbox                         % next line

Thus we have a break point if the interline penalty is smaller than 10000, despite using \\*. If the interline penalty is 10000 or greater, then we do not have a break point anyway with an additional \nobreak of \\* or without.

However, there is one case where \\* actually prevents a line break. Namely "The TeXbook" is not always telling the truth: There is a situation, where TeX does not add a interline glue. It tries to be clever and rationalizes an interlinepenalty of value zero. It probably thinks: interline glue after \hbox – we have a break point; penalty of zero – neither good nor bad, since there is already a break point, we do not need it. In appendix A in answer to exercise 14.26 can be found:

(When the total penalty is zero, as between lines 3 and 4 in this case, no penalty is actually inserted.)

Then \nobreak of \\* kicks in:

\hbox          % line box
\penalty 10000 % of \\* via \vadjust
\vskip <interline glue>
\hbox          % next line

Voila, the page break is surprisingly prevented. Of course this over-optimization is not a "bug" (TeX is per definition bug-free, de facto), let's call it a "design misfeature". ;-)

For illustration, an example for ini-TeX (or plain TeX) for experimenting/studying. Macro \NPB simulates \\*:

% iniTeX or plain TeX
\showboxbreadth=10000
\showboxdepth=10000
\tracingonline=1
\catcode`\{=1
\catcode`\}=2
\font\rm=cmr10
\rm
\baselineskip=12pt
\parfillskip=0pt plus 1fil\relax
\hsize=2in
\vsize=4in

\interlinepenalty=1
\clubpenalty=-1
\widowpenalty=150

\def\NPB{% \\*
  \unskip
  \vadjust{\penalty10000}%
  \penalty10000\hfil\penalty-10000 %
}

\noindent
A\NPB B\NPB C

\scrollmode
\showlists
\end

Console output:

### vertical mode entered at line 0
### current page:
\glue(\topskip) 0.0
\hbox(6.83331+0.0)x144.54, glue set 137.03998fil
.\rm A
.\penalty 10000
.\glue 0.0 plus 1.0fil
.\penalty -10000
.\glue(\rightskip) 0.0
\penalty 10000
\glue(\baselineskip) 5.16669
\hbox(6.83331+0.0)x144.54, glue set 137.45663fil
.\rm B
.\penalty 10000
.\glue 0.0 plus 1.0fil
.\penalty -10000
.\glue(\rightskip) 0.0
\penalty 10000
\penalty 151
\glue(\baselineskip) 5.16669
\hbox(6.83331+0.0)x144.54, glue set 137.31776fil
.\rm C
.\penalty 10000
.\glue(\parfillskip) 0.0 plus 1.0fil
.\glue(\rightskip) 0.0
total height 30.83331
 goal height 289.07999
prevdepth 0.0, prevgraf 3 lines

! OK.
l.28 \showlists

The stuff between the first lines/\hboxes:

\penalty 10000
\glue(\baselineskip) 5.16669

The first penalty comes from \vadjust{\penalty10000}. The interline penalty sums up to zero: \interlinepenalty + \clubpenalty = 1 - 1 = 0

In the second case:

\penalty 10000
\penalty 151
\glue(\baselineskip) 5.16669

the interline penalty is not suppressed: \interlinepenalty + \widowpenalty = 1 + 150 = 151. This penalty allows a page break at this place.

Practice

The following part is inherited from this answer to the more specific question variant.

The problem is the automatically inserted \interlinepenalty. It is usually smaller than 10000 and allows a page break even if it is preceded by a \nobreak (= \penalty10000).

The following uses a workaround. Instead of ending the line, the paragraph is ended. Then the effects of \parskip and \parindent need to be reversed and avoided:

\documentclass{article}
\usepackage{lipsum}

\newcommand*{\NLS}{%
  \par
  \nobreak
  \vspace{-\parskip}%
  \noindent
  \ignorespaces
}

\begin{document}

\lipsum[1-4]\footnote{
  no asterisk \\ asterisk \NLS
  no asterisk \\ asterisk \NLS
  no asterisk \\ asterisk \NLS
  no asterisk \\ asterisk \NLS
  no asterisk \\ asterisk \NLS
  last line}
\lipsum[5]  

\end{document}

page1 page2

However, this is still a workaround and does not provide a correct implementation for \\*. By splitting a paragraph in two paragraphs, up to two interline penalties for the line break before and after the inserted \par are increased by \widowpenalty or \clubpenalty. That is, additional page breaks can be forbidden as a side effect, if the addition by \widowpenalty or \clubpenalty now increases the interline penalty to 10000.

The other case is less problematic: If the line break, where the \par gets inserted, would have get \clubpenalty or \widowpenalty, then this penalty is now lost. But since we forbid a page break already by \nobreak, a loss of an additional penalty does not matter.

|improve this answer|||||
  • I don't think that \interlinepenalty is the problem - if this were true \\* would never work - at least as long it has the value zero. If you add \interlinepenalty=1 to the original example you can see the difference. In the text case the problem are club- and widowpenalty. In the footnote case perhaps also \interfootnotelinepenalty=10000. See also latex-project.org/cgi-bin/ltxbugs2html?pr=latex/2411. – Ulrike Fischer May 23 '14 at 11:15
  • @UlrikeFischer: TeX adds a inter line penalty that consists of \interlinepenalty. \clubpenalty and/or \widowpenalty is added, if the line break is after the first/before the last line. Only if this value is zero, then the \nobreak of \\* has an effect of preventing the page break at the interline glue. Otherwise there can be a page break, if the minimum of the inter line penalty or the \nobreak penalty is smaller than 10000. – Heiko Oberdiek May 23 '14 at 13:53
  • If you try out some examples (normal text, not footnotes) you can see that the page breaks at \\* occur only after the first and before the last line of a paragraph. And if you set club and widow penalty to 10000 there will be no page breaks -- even if you have lots of line\\*line\\* in a row. As long as \interlinepenalty is zero it doesn't interfere. – Ulrike Fischer May 23 '14 at 14:10
  • @UlrikeFischer: Yes, if the interline penalties sum up to zero, then TeX suppresses the output of a \penalty and the \nobreak prevents the page break at the interline glue. This is a kind of "mis-feature". If someone increases \interlinepenalty, then a page break, that was formerly prevented, should not become possible. – Heiko Oberdiek May 23 '14 at 14:52
  • @UlrikeFischer: I have added an iniTeX example; perhaps it makes the description clearer, if it can be studied with TeX's debugging facilities. – Heiko Oberdiek May 23 '14 at 15:04

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.