39

By default, LaTeX allows a page break after the first two lines of paragraphs following section/subsection headings. How can I enlarge this minimum to, say, three lines or 10 percent of the value of \textheight?

21

There may be a generalisable mechanism: Using e-TeX and its \clubpenalties command. In the following example, patching \@afterheading seems to do the trick.

\documentclass{article}

\usepackage{etex}

\usepackage{etoolbox}
\makeatletter
\patchcmd{\@afterheading}%
    {\clubpenalty \@M}{\clubpenalties 3 \@M \@M 0}{}{}
\patchcmd{\@afterheading}%
    {\clubpenalty \@clubpenalty}{\clubpenalties 2 \@clubpenalty 0}{}{}
\makeatother

\usepackage{blindtext}

\textheight 480pt

\begin{document}

\section{bla}

\blindtext[3]

\section{blubb}

\blindtext

\clearpage

\section{foo}

\blindtext[3]

An extra line.

\section{bar}

\blindtext

\end{document}

UPDATE: egreg has written a detailed explanation of \widowpenalties and \clubpenalties.

  • 3
    Neat. I didn't know \clubpenalties. One lives and learn. – Ulrike Fischer Aug 26 '10 at 14:22
  • 1
    That must be the first time I taught you something, Ulrike. ;-) Note: I'm not sure about the workings of \clubpenalties, but I've edited my code example so that the third penalty value (which seems to affect the third and all following lines of a paragraph) is 0 instead of \@clubpenalty (which defaults to 150). – lockstep Aug 26 '10 at 14:28
  • 2
    I don't think you need the third argument at all if you want to affect only the first 3 lines. But I have some doubts about your patch: Your setting affects now all following paragraphs. If you want to set the penalty only for the first, you must reset \clubpenalties with "\clubpenalties 0" in the "else"-part of \@afterheading. – Ulrike Fischer Aug 26 '10 at 14:51
  • If I replace \clubpenalties 3 \@M \@M 0 with \clubpenalties 2 \@M \@M, no page break is allowed at all. But your're right about all following paragraphs being affected; I've edited my code example to solve this issue. – lockstep Aug 26 '10 at 15:29
  • Oooh, I didn't know about \clubpenalties either. Nor did I know about the etex documentation or etoolbox. That's a good value answer! – Norman Gray Aug 27 '10 at 13:38
15

I solved this with the needspace and titlesec packages, as in:

\usepackage{titlesec}
\usepackage{needspace}
...
\titleformat{\section}
{\needspace{1in}\Large\bfseries}{\thesection}{1em}{}

Hardcoding 1in is crude -- should probably be a multiple of line height. At any rate, this works great in my documents without the need for hand tuning each section.

  • @srking: Thanks, but Ulrike Fischer and Lev Bishop already mentioned needspace in their answers. – lockstep Mar 27 '11 at 1:17
  • 3
    @lockstep - Sure, but I just found combining needspace with titlesec capability to be particularly convenient. Cheers. – srking Mar 27 '11 at 2:44
  • 4
    @lockstep: The advantage of srking's solution is obviouly that one doesn't need to manually put \Needspace (and that it works without \patchcmd trickery), so +1 from me. – Hendrik Vogt Mar 27 '11 at 7:57
  • @Hendrik: You're right -- +1, and +1 for @srking's answer. – lockstep Mar 27 '11 at 9:30
  • 1
    Actually, titlesec provides a feature very similar to needspace with \bottomtitlespace. – Javier Bezos Jul 1 '11 at 10:09
11

You could use needspace. With a bit calculations and tests it shouldn't be too difficult to find sensible values:

\documentclass{article}
\usepackage{lipsum,needspace}

\begin{document}
\lipsum[1] \vspace{27\baselineskip}

\Needspace{7\baselineskip}
\section{Blubb}
\lipsum[1]

\newpage
\lipsum[1] \vspace{28\baselineskip}

\Needspace{7\baselineskip}
\section{Blabb}
\lipsum[1]

\end{document}
3

I haven't tried it myself, but perhaps you can use the needspace package for this. Be sure to heed the FAQ warning about how this may confuse tex, even if you do succeed in preventing page breaks between the lines (eg, ending up with an overfull page leaving those lines jutting out of the bottom of the page).

3
\patchcmd{\@afterheading}%
    {\clubpenalty \@M}{\clubpenalties 3 \@M \@M 0}{}{}

\patchcmd works for all cleanable parameterless macros, but it is meant for cleanable parameterized macros. For parameterless macros, LaTeX \g@addto@macro does the job without the need for the <success> and <failure> parts and, of course, without the need for etoolbox.

  • Oops, I am very sorry, I got it wrong! \patchcmd searches and replaces! – Ahmed Musa Aug 26 '10 at 16:44
1

titlesec offers the option nobottomtitles to move titles close to the bottom to the next page. The starred variant is more accurate, see the manual. By default the threshold is .2\textheight.

\usepackage[nobottomtitles*]{titlesec}
\renewcommand{\bottomtitlespace}{.2\textheight} % default value
0

There isn't a generalisable mechanism.

Single last lines or single first lines of a paragraph, appearing at the beginning or the end of a page, are known as 'widows' and 'orphans/clubs' (I think they're that way round). TeX has a mechanism for avoiding, or at least penalising, widows and orphans, but it's specialised for this case of keeping the first or last two lines together, and it can't be extended to three lines or more.

There may be a way of addressing this by doing scary output routine gymnastics, but that would be a very exotic thing to do.

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.