The following approach uses TeX's \label
-\ref
system to check whether a \section
already appears on the current page. It does by by creating/examining a macro called \section-on-page-<pnum>
(where <pnum>
is the page of the section being set). If this macro exists for a given <pnum>
(checked via \ifcsname <csname>\endcsname
), a \section
already exists on that <pnum>
and issues a \newpage
. If it doesn't exist, it sets the \section
like before and (re)creates \section-on-page-<pnum>
.
\documentclass{book}
\usepackage{lipsum,refcount}
\NewCommandCopy{\oldsection}{\section}
\RenewDocumentCommand{\section}{ s o m }{%
\label{before-section-\thesection}% Set \label for section
% Check if there is already a section on the current page by
% examining the existence of \section-on-page-<pnum>
\ifcsname section-on-page-\getpagerefnumber{before-section-\thesection}\endcsname
\newpage% Action if a section already exists
\fi
\IfBooleanTF{#1}
{\oldsection*{#3}}% \section*{..}
{\IfValueTF{#2}
{\oldsection[#2]{#3}}% \section[.]{..}
{\oldsection{#3}}% \section{..}
}%
\label{section-\thesection}% Set new label for section (could be on a following page)
% Update \section-on-page-<pnum>
\expandafter\xdef\csname section-on-page-\getpagerefnumber{section-\thesection}\endcsname{Section on page \getpagerefnumber{section-\thesection}}%
}
\begin{document}
\chapter{A chapter}
\section{Long section}\lipsum[1-10]
\section{Long section}\lipsum[1-10]
\section{Short section}\lipsum[1]
\section{Long section}\lipsum[1-10]
\section{Short section}\lipsum[1]
\section{Long section}\lipsum[1-10]
\end{document}
Before:
After:
Page numbers of a \ref
erence is extracted using the functionality provided by refcount
.
Since the \label
-\ref
system is used, changes in the document layout may require multiple runs. The construction of the document, and therefore also the conditional issuing of \newpage
, is sequential. So, one \newpage
can cause a ripple effect throughout the document. Keep compiling until all references have settled.