diff --git a/CHANGELOG b/CHANGELOG index 50ddd43..d1c6737 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -3,6 +3,10 @@ version next - Fix "Underfull \hbox (badness 10000)" warning in banking \subsection dotted rules by adding \hss glue as in \dotfill (#307) - Update "circle" option to allow for half-filled circles in skill matrix (#309) +- Fix orphaned \section and \subsection headings in the casual, classic and + contemporary styles: the trailing \addvspace of the \cvitem used to typeset + the heading allowed a page break between the heading and its first entry + (#226) version 2.6.1 (24 Jun 2026) - Allow the customisation of the contemporary style (#297) diff --git a/manual/moderncv_userguide.pdf b/manual/moderncv_userguide.pdf index 1559481..bc1a26d 100644 Binary files a/manual/moderncv_userguide.pdf and b/manual/moderncv_userguide.pdf differ diff --git a/manual/moderncv_userguide.tex b/manual/moderncv_userguide.tex index 13d2712..b8396a8 100644 --- a/manual/moderncv_userguide.tex +++ b/manual/moderncv_userguide.tex @@ -95,7 +95,7 @@ belowcaptionskip=0.75\baselineskip, % frame=L, emph={ - cvitem, cventry, cvdoubleentry, cvdoubleitem, cvtripleitem, cvlistitem, cvlistdoubleitem, cvcolumns, moderncvstyle, moderncvcolor, + cvitem, cventry, cvdoubleentry, cvdoubleitem, cvtripleitem, cvlistitem, cvlistdoubleitem, cvcolumns, @cvheadingitem, moderncvstyle, moderncvcolor, cvskill, cvskilllegend, cvskillplainlegend, cvskillhead, cvskillentry, nopagenumbers, name, born, address, email, link, social, phone, homepage, extrainfo, photo, quote, section, subsection, setlength, NewDocumentCommand, definecolor, colorlet, cvitemwithcomment, recipient, subject, opening, closing, signature, postscript, enclosure, makelettertitle, makeletterclosing, httplink, httpslink, emaillink @@ -497,6 +497,13 @@ This can be combined with the \code{itemize} environment. \end{lstlisting} \code{} is a number between 0 and 1 controlling the width of the column. +\paragraph{\code{\\@cvheadingitem}} +A variation of \code{\\cvitem} with no trailing vertical space and \code{\\addvspace} gobbled. +This removes a legal break point that could lead to orphaned headings in prior versions of the styles \code{classic}, \code{casual} and \code{contemporary}. +\begin{lstlisting} + \@cvheadingitem{}{} +\end{lstlisting} + \subsubsection{Skill matrix macros} The skill matrix is a table for displaying skills such as computer skills or project management skills graphically. The skill matrix table consists of several elements: @@ -1005,51 +1012,6 @@ An email link. The \texttt{mailto:} prefix is generated automatically and is not \emaillink[my email]{jdoe@website.org} \end{lstlisting} -\subsection{Page breaks and orphaned section headers} -If \Latex breaks pages just after \code{\\section} or \code{\\subsection} commands, try adjusting the stretchability of the page with \code{\\cvsectionstretchability} or \code{\\cvsubsectionstretchability}: -\begin{lstlisting} - \setlength{\cvsectionstretchability}{\baselineskip} - \setlength{\cvsubsectionstretchability}{100pt} -\end{lstlisting} -These two lengths tell \Latex how much extra length it needs after \code{\\section} and \code{\\subsection} commands. -By default, \Moderncv sets both lengths to \code{0.9\\baselineskip}. - -This should solve orphaned \code{\\section} and \code{\\subsection} commands that are used alone for most users. -However, \Latex does not check for content. -For example, writing -\begin{lstlisting} - \section{blub} - \subsection{blubblub} -\end{lstlisting} -one after the other may cause \Latex to place the section and subsection headers on separate pages. -Since \Latex considers the subsection header to not be orphaned, it may place the section header at the bottom of a page if there is enough space to do so while placing the subsection header on the next page. -One solution is to increase \code{\\cvsectionstretchability} to force the break of the section header. -However, this changes the behaviour for all \code{\\section} commands in your CV and might cause unnecessary page breaks. -It is therefore recommended to force the page break manually with a \code{\\newpage} in this case. - -\paragraph{Experts only:} -Internally, \Moderncv uses a custom \code{\\needspace} command: -\begin{lstlisting} - \NewDocumentCommand\@cvneedspace{m}{% - \begingroup - \setlength{\dimen@}{#1}% - \vskip\z@\@plus\dimen@ - \penalty \withinstretchpenalty\vskip\z@\@plus -\dimen@ - \vskip\dimen@ - \penalty \poststretchpenalty% - \vskip -\dimen@ - \vskip\z@skip % hide the previous |\vskip| from |\addvspace| - \endgroup - } -\end{lstlisting} -Thus, instead of setting \code{\\cvsectionstretchability} and/or \code{\\cvsubsectionstretchability}, page break behavior can be adjusted by redefining the following internal penalties: -\begin{lstlisting} - \renewcommand{\withinstretchpenalty}{<-100...9999>} - \renewcommand{\poststretchpenalty}{<-100...9999>}. -\end{lstlisting} -By default, \Moderncv sets \code{\\withinstretchpenalty} to 0 and \code{\\poststretchpenalty} to 9999. -The higher the penalties are, the less likely a page break will occur. -A good explanation of \code{\\needspace} can be found at \url{https://tex.stackexchange.com/questions/348994/understanding-needspace}. \subsection{Tips and Tricks} diff --git a/moderncv.cls b/moderncv.cls index 1bc93cf..7cfaafd 100644 --- a/moderncv.cls +++ b/moderncv.cls @@ -567,6 +567,16 @@ % usage: \cvitem[spacing]{header}{text} \newcommand*{\cvitem}[3][.25em]{} +% typesets a (sub)section heading as a \cvitem, without the trailing vertical +% space \cvitem normally adds +% usage: \@cvheadingitem{header}{text} +% the trailing \addvspace of \cvitem would contribute glue right after the +% heading box and before the \nobreak of the heading definition; glue after a +% box is a legal page breakpoint, so LaTeX could leave the heading orphaned at +% the bottom of a page. Gobbling it makes \nobreak the first item following +% the heading box, so the page can only break before the heading +\newcommand*{\@cvheadingitem}[2]{{\let\addvspace\@gobble\cvitem[0ex]{#1}{#2}}} + % makes a resume line 2 headers and their corresponding text % usage: \cvdoubleitem[spacing]{header1}{text1}{header2}{text2} \newcommand*{\cvdoubleitem}[5][.25em]{} diff --git a/moderncvbodyi.sty b/moderncvbodyi.sty index b1155d2..3de93c6 100644 --- a/moderncvbodyi.sty +++ b/moderncvbodyi.sty @@ -78,14 +78,14 @@ \par\addvspace{2.5ex}% \phantomsection{}% reset the anchor for hyperrefs \addcontentsline{toc}{section}{#2}% - \cvitem[0ex]{\strut\raggedleft\raisebox{\baseletterheight}{\color{bodyrulecolor}\rule{\hintscolumnwidth}{0.95ex}}}{\strut\sectionstyle{#2}}% + \@cvheadingitem{\strut\raggedleft\raisebox{\baseletterheight}{\color{bodyrulecolor}\rule{\hintscolumnwidth}{0.95ex}}}{\strut\sectionstyle{#2}}% \par\nobreak\addvspace{1ex}\@afterheading}% to avoid a pagebreak after the heading \RenewDocumentCommand{\subsection}{sm}{% \par\addvspace{1ex}% \phantomsection{}% reset the anchor for hyperrefs \addcontentsline{toc}{subsection}{#2}% - \cvitem[0ex]{}{\strut\subsectionstyle{#2}}% + \@cvheadingitem{}{\strut\subsectionstyle{#2}}% \par\nobreak\addvspace{.5ex}\@afterheading}% to avoid a pagebreak after the heading \renewcommand*{\cvitem}[3][.25em]{% diff --git a/moderncvbodyvi.sty b/moderncvbodyvi.sty index 79b9d3f..58ab97a 100644 --- a/moderncvbodyvi.sty +++ b/moderncvbodyvi.sty @@ -92,7 +92,7 @@ \par\addvspace{1ex}% \phantomsection{}% reset the anchor for hyperrefs \addcontentsline{toc}{subsection}{#2}% - \cvitem[0ex]{}{\strut\subsectionstyle{#2}}% + \@cvheadingitem{}{\strut\subsectionstyle{#2}}% \par\nobreak\addvspace{.5ex}\@afterheading}% to avoid a pagebreak after the heading \renewcommand*{\cvitem}[3][.25em]{%