3

many LaTeX sectioning-related commands have a block in manipulating the \@nobreak flag. Taking the following example for the sake of example:

\begingroup
\parindent \z@ \rightskip \@pnumwidth 
\parfillskip -\@pnumwidth 
{\leavevmode 
\large \bfseries #1 
\leaders\hbox{$\m@th\mkern 1.5mu\cdot\mkern 1.5mu$} 
\hfil \hb@xt@\@pnumwidth{\hss #2}}\par 
\nobreak 
\global\@nobreaktrue 
\everypar{\global\@nobreakfalse\everypar{}}% 
\endgroup 
\fi}

(from an implementation of \l@chapter), I am looking to understand why the mechanism is required and how it works in detail.

  • 1
    And the question is? – egreg Aug 27 '14 at 9:19
  • @egreg In what circumstance does it work, could you provide a case and explain it, thank you! – poplar Aug 27 '14 at 9:31
  • 1
    @egreg I've edited to try to make into a question: as I understand it the idea is to explain why this is needed and how it works, in particular the reset bit. – Joseph Wright Aug 27 '14 at 9:43
6

The \nobreak macro prevents a break after the current material. That's standard for headings amongst other places: no line break should come between the heading and the following text. In LaTeX, a common construct is

\section{Some section}
\label{sec:important}

Text here

Using just a \nobreak inside \section, the break would keep the label with the section heading but then the text could split off. To prevent this, LaTeX sets the \@nobreak flag inside the section code. This is picked up by \label (or rather by an internal command, \protected@write) and a second \nobreak is inserted. The result is that the block of section, label and text cannot have a page break inserted.

To turn the flag off, the \everypar hook is used. This is inserted by TeX when it starts a paragraph, so for example when TeX finds the T in Text here in my example. At this stage, the \nobreak is safely inserted so the flag is switched off so that the next \label or whatever doesn't add one that's not needed. Everything is done globally for this mechanism as the hook can be inside a group. A trivial example

\section{Some section}
\label{sec:important}

{\texttt Text here}

which would mean that a local flag could get 'stuck on'. The construct

\everypar{\global\@nobreakfalse\everypar{}}

means that not only is the flag cleared but also the reset itself is removed from further action.


All of the above applies most obviously to section headings, but the same mechanism is used in a few places (search latex.ltx for @nobreak to see them all). In the example in the question we are looking at parts as displayed in the table of contents. When a part is inserted, no break is allowed before the following chapter/section/whatever, while breaks are allowed between chapters/sections. To see why the \@nobreak flag has to be set, look at the standard definition of \l@chapter:

\newcommand*\l@chapter[2]{%
  \ifnum \c@tocdepth >\m@ne
    \addpenalty{-\@highpenalty}%
    \vskip 1.0em \@plus\p@
    \setlength\@tempdima{1.5em}%
    \begingroup
      \parindent \z@ \rightskip \@pnumwidth
      \parfillskip -\@pnumwidth
      \leavevmode \bfseries
      \advance\leftskip\@tempdima
      \hskip -\leftskip
      #1\nobreak\hfil \nobreak\hb@xt@\@pnumwidth{\hss #2}\par
      \penalty\@highpenalty
    \endgroup
  \fi}

The first thing this does is use \addpenalty, which without the \@nobreak flag would undo the work of the \nobreak inserted by \l@part. (You can readily test this by redefining \l@part with a suitably set-up demo file.) However, \addpenalty checks the \@nobreak flag as part of its work: with the flag on, no additional penalty is added and so a page break is still prevented after the line for a chapter.


A note on \protected@write. It reads

\begingroup 
  \let \thepage \relax
  #2%
  \let \protect \@unexpandable@protect
  \edef \reserved@a {\write #1{#3}}%
  \reserved@a
\endgroup
\if@nobreak
  \ifvmode
    \nobreak
  \fi
\fi

and thus tests for the no break flag. If TeX is in vertical mode, as it is after a \section (which ends in a \par token) then a break is prevented: this is what keeps the following text with the label, which is itself kept with the section heading.

  • To put it in simple sentenes. the first \nobreak prohibits page splitting before the part and the first chapter(in context or our question); \global\@nobreaktrue works with the command \nobreak to achieve this function, therefore the flage \@nobreak must be needed and be set true. \everypar{\global\@nobreakfalse\everypar{}}% breaks are allowed for the following Chapter/Section/Subsection....etc. – poplar Aug 27 '14 at 13:29
  • @JosephWright Could you explain "picked up by \protected@write". I do not see how a \nobreak is inserted after \label, for example, by \section code. – Jonathan Komar Nov 8 '16 at 15:13
  • I think I understand it now! So \everypar{\global\@nobreakfalse\everypar{}} is used when breaking is permitted after a sectioning command/label. What confuses me is that I would expect \everypar{\global\@nobreaktrue\everypar{}} or just \@nobreaktrue somewhere in \@startsection such that it gets passed to the \label (\protected@write's \if@nobreak) but I cannot find it... – Jonathan Komar Nov 8 '16 at 16: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.