Coupures et ajustement des pages

La coupure de page dans LaTeX ne ressemble en rien à la coupure de ligne. Un paragraphe est découpé en évaluant d'un seul coup toutes les répartitions possibles pour retenir la meilleure d'ensemble ; une page, elle, n'est jamais reconsidérée une fois terminée. Taper \newpage sans comprendre pourquoi la page s'est arrêtée là, c'est risquer d'entraîner les quarante pages suivantes. Cette page mesure la mécanique du rythme d'un document — veuves et orphelines (\widowpenalty et \clubpenalty, tous deux à 150 par défaut), la différence entre \raggedbottom et \flushbottom, et la façon dont les flottants bousculent le texte — puis en tire une méthode pour diagnostiquer une mauvaise coupure au lieu de la forcer.

Pourquoi une page finit là où elle finit : la différence avec la coupure de ligne

Une page se termine où elle se termine sur la seule foi des informations disponibles pendant la construction de cette page. TeX fait couler le texte vers le bas, surveille les points de coupure licites qui apparaissent entre les lignes, et dès que la hauteur accumulée dépasse la cible, il revient au candidat le moins coûteux rencontré jusque-là et coupe à cet endroit. La coupure des lignes dans un paragraphe est une optimisation globale sur toutes les dispositions possibles ; la coupure de page est une décision séquentielle prise en avançant. C'est la différence qui compte en pratique, et c'est pourquoi corriger la coupure de la page 40 décale tout à partir de la page 41.

Décider séquentiellement, c'est aussi ne plus rien pouvoir renégocier ensuite. Il ne reste à TeX qu'un moyen de déclarer, sous forme de nombre, à quel point il répugne à couper à tel endroit : la pénalité. Une pénalité est un entier attaché à un point de coupure ; plus elle est grande, plus TeX rechigne à couper là. 10000 est la valeur spéciale « ne jamais couper ici », et -10000 signifie au contraire « couper ici à coup sûr ». Le dispositif qui évite d'isoler une ligne de paragraphe, celui qui place les flottants et celui qui interdit une coupure juste après un titre s'expriment tous avec cette unique sorte de nombre. Régler les coupures de page revient donc à régler des pénalités.

Veuves et orphelines : \widowpenalty et \clubpenalty valent 150 par défaut

Mesurés dans la classe article, \widowpenalty et \clubpenalty valent tous deux 150, et \displaywidowpenalty vaut 50. Une veuve est la dernière ligne d'un paragraphe restée seule en haut de page ; une orpheline est la première ligne restée seule en bas. Les typographes allemands les distinguent sous les noms de Hurenkind et Schusterjunge. Le premier piège est le nom : le paramètre qui supprime l'orpheline ne s'appelle pas \orphanpenalty — cette variable n'existe ni dans TeX ni dans LaTeX — mais \clubpenalty, survivance du vieux terme d'imprimerie club line pour une ligne d'ouverture isolée.

latex
% Print the defaults into the .log yourself:
%   pdflatex penalties.tex  ->  grep MEASURE penalties.log
\documentclass{article}
\begin{document}
\typeout{MEASURE widowpenalty=\the\widowpenalty}
\typeout{MEASURE clubpenalty=\the\clubpenalty}
\typeout{MEASURE displaywidowpenalty=\the\displaywidowpenalty}
\typeout{MEASURE brokenpenalty=\the\brokenpenalty}
x
\end{document}

Le nombre 150 a une généalogie. Dans TeX Live 2024, ces trois affectations occupent les lignes 514 à 516 de latex.ltx — et les trois mêmes lignes figurent aux lignes 290 à 292 du plain.tex de Knuth. LaTeX a donc simplement hérité des valeurs par défaut de plain TeX et ne les a jamais réexaminées en quarante ans. Or 150 ne pèse presque rien en pratique. La laideur — la badness — que représente une page raccourcie d'une ligne dépasse aisément 1000 dans du texte courant, où le blanc vertical élastique est rare. Une pénalité de 150 perd ce bras de fer presque à tous les coups.

ParamètreValeur par défautCe qu'il décourage
\widowpenalty150la dernière ligne d'un paragraphe seule en haut de page
\clubpenalty150la première ligne d'un paragraphe seule en bas de page
\displaywidowpenalty50une ligne isolée juste avant une formule hors-texte
\brokenpenalty100une coupure de page juste après une ligne césurée
\interlinepenalty0une coupure n'importe où dans un paragraphe (non découragée par défaut)
\predisplaypenalty10000une coupure juste avant une formule hors-texte (de fait interdite)

Il existe exactement un endroit où LaTeX renonce lui-même à ces valeurs. L'environnement thebibliography d'article.cls appelle \sloppy dès l'entrée et fixe \clubpenalty4000 et \widowpenalty4000 (lignes 576 à 579 de l'article.cls livré avec TeX Live 2024). Une bibliographie est une longue suite d'entrées courtes : les veuves y sont fréquentes, et une entrée coupée en deux pages est réellement pénible à lire — voilà pourquoi la classe standard fait un effort à cet unique endroit. Ce qui implique la réciproque : dans le texte courant, les classes standard ne font rien pour vous.

Ce que coûte vraiment \widowpenalty=10000 : le marché, mesuré

La veuve disparaît, et une page courte prend sa place. Composez un document de 20 lignes par page avec des paragraphes de six lignes en \flushbottom et mesurez : avec les valeurs par défaut, la page 1 accueille 23 lignes et la dernière ligne du quatrième paragraphe reste seule en haut de la page 2. Ajoutez \widowpenalty=10000 : la page 1 tombe à 22 lignes, les deux dernières lignes passent ensemble à la page suivante, et la veuve a disparu. Mais le journal gagne une ligne :

log
Underfull \vbox (badness 10000) has occurred while \output is active []

Cet avertissement signifie que TeX n'a pas pu remplir la page jusqu'à sa hauteur cible, et il n'apparaît qu'en \flushbottom. La même expérience en \raggedbottom ne le déclenche jamais : la page a le droit de s'arrêter court, il n'y a donc rien à remplir. Le coût de \widowpenalty=10000 se manifeste donc par un interlignage étiré et irrégulier en \flushbottom, et une bande de blanc variable en pied de page en \raggedbottom. Dans les deux cas, le coût n'est pas nul. Malgré tout, pour un manuscrit essentiellement composé de texte courant, 10000 se défend : une ligne isolée se remarque à coup sûr, une page qui s'arrête une ligne plus tôt presque jamais.

latex
% A defensible pair of settings for a text-heavy manuscript.
\widowpenalty=10000
\clubpenalty=10000
% Also stop a two-line gap opening before a displayed formula:
\displaywidowpenalty=10000
% Prefer this over sprinkling \newpage through the source.

\raggedbottom ou \flushbottom, et lequel vous avez déjà

\flushbottom étire les blancs verticaux pour que toutes les pages s'achèvent à la même hauteur ; \raggedbottom laisse les pieds de page varier. C'est ici que beaucoup de conseils publiés se trompent : la valeur par défaut d'un article en recto seul est \raggedbottom, pas \flushbottom. article.cls, report.cls et book.cls exécutent tous en fin de fichier \if@twoside \else \raggedbottom \fi : sans twoside, vous êtes donc en mode ragged bottom. Seul book, qui est twoside par défaut, reste du côté flush bottom. Demandez deux colonnes et chacune de ces classes appelle explicitement \flushbottom.

Options de classeCe qui s'applique réellementAspect du pied de page
\documentclass{article}\raggedbottomle pied se situe à une hauteur différente selon les pages
\documentclass[twoside]{article}\flushbottomles pieds s'alignent ; l'interlignage peut être étiré
\documentclass{book}\flushbottombook est twoside par défaut, d'où ce réglage
\documentclass[twocolumn]{article}\flushbottomappelé explicitement par la classe ; des colonnes inégales se voient

Le mécanisme est presque décevant de simplicité. Dans latex.ltx, \raggedbottom est défini par \def\@textbottom{\vskip \z@ \@plus.0001fil} et \flushbottom par \let\@textbottom\relax. Le premier place tout en bas de page un ressort de longueur nulle mais d'élasticité infinie ; ce fil écrase le peu d'élasticité finie disponible dans le texte au-dessus, si bien que tout le mou est absorbé au pied. Demandez \meaning\@textbottom : article répond macro:->\vskip \z@ \@plus .0001fil et book répond \relax — une ligne dans le préambule suffit à savoir dans quel mode se trouve votre document.

latex
% Which bottom mode am I in? Put this in the preamble and read the .log.
\makeatletter
\AtBeginDocument{\typeout{MEASURE textbottom=\meaning\@textbottom}}
\makeatother
% article  -> macro:->\vskip \z@ \@plus .0001fil   (\raggedbottom)
% book     -> \relax                                (\flushbottom)

Quand les flottants bousculent le texte : \topfraction et \textfraction

Quand une coupure de page paraît inexplicable, le coupable est presque toujours un flottant. Avant de poser une figure ou un tableau, LaTeX vérifie quelle part de la page il peut occuper et combien s'y trouvent déjà. Mesures dans les classes standard : les flottants du haut peuvent remplir jusqu'à \topfraction = .7 de la hauteur de texte, ceux du bas jusqu'à \bottomfraction = .3, il doit rester au moins \textfraction = .2 de texte véritable, et une page accueille au plus totalnumber = 3 flottants (topnumber = 2 en haut, bottomnumber = 1 en bas). Une figure qui échoue à un seul de ces tests n'est pas posée sur cette page mais reportée plus loin. Les flottants reportés se placent avant le texte qui les suit : voilà comment la prose se retrouve page 12 et sa figure page 14.

ParamètreValeur par défautSignification
\topfraction.7part de la hauteur de texte que les flottants du haut peuvent occuper
\bottomfraction.3part que les flottants du bas peuvent occuper
\textfraction.2part minimale d'une page qui doit rester du texte
\floatpagefraction.5remplissage minimal autorisant une page de flottants seuls
totalnumber3nombre total de flottants admis sur une page
topnumber2flottants admis en haut de page
bottomnumber1flottants admis en bas de page

Quand un flottant est en cause, le journal le dit en premier. Si une figure marquée [h] ne peut pas y tenir, LaTeX annonce LaTeX Warning: 'h' float specifier changed to 'ht'. et la déplace discrètement en haut. Si trop de flottants reportés s'accumulent, il s'arrête sur ! LaTeX Error: Too many unprocessed floats. (le message \@fltovf de latex.ltx). En pratique, les remèdes courants sont \FloatBarrier de placeins aux frontières de section, qui retient les figures dans leur section, ou \afterpage{\clearpage} du package afterpage, qui ne vide la file qu'une fois la page en cours achevée. Un \clearpage nu écrit sur place laisse un grand trou au milieu du texte.

latex
\usepackage{placeins}   % \FloatBarrier
\usepackage{afterpage}  % \afterpage{\clearpage}

% Keep every figure inside the section that discusses it:
\let\oldsection\section
\renewcommand\section{\FloatBarrier\oldsection}

% Or loosen the rules instead of forcing breaks:
\renewcommand{\topfraction}{0.85}
\renewcommand{\textfraction}{0.1}
\renewcommand{\floatpagefraction}{0.75}

Réparer une mauvaise coupure de page : avant de forcer

Il y a un ordre : repérer la cause, corriger ensuite un réglage global, et seulement alors retoucher à la main l'unique page encore fautive. Dans l'ordre inverse, une seule phrase ajoutée en amont anéantit tout le travail manuel. Le repérage commence dans le .log. Un Underfull \vbox signale que \flushbottom et vos pénalités tirent en sens contraire ; un message float specifier changed désigne un flottant ; une série d'Overfull \hbox indique que le problème est du côté de la coupure de ligne, terrain d'une autre page. La cause connue, il reste à choisir quoi déplacer : une pénalité, une proportion de flottant, ou la longueur du paragraphe lui-même.

  • Lire le .log. Selon que s'affiche Underfull \vbox, float specifier changed ou Overfull \hbox, le coupable change.
  • Relever \widowpenalty et \clubpenalty dans le préambule. Comme cela vaut pour tout le document, ce qui est réparé le reste.
  • Si un flottant est en cause : \FloatBarrier, ou un ajustement de \topfraction. Élargir le spécificateur en [htbp] aide aussi.
  • Raccourcir ou allonger le paragraphe d'une ligne. Reformuler une seule tournure est souvent la correction la plus durable.
  • \enlargethispage{\baselineskip} n'agrandit que cette page d'une ligne. Le travail manuel ne commence qu'ici.
  • \newpage et \pagebreak sont l'ultime recours. Une fois insérés, il faut revérifier leur position à chaque modification du texte.

\looseness est le moyen de demander à TeX « une ligne de moins ». Écrit à l'intérieur d'un paragraphe, \looseness=-1 signifie « compose-le une ligne plus court si tu peux » et +1 une ligne de plus. La mesure est pourtant instructive : dans un paragraphe réglé sur \tolerance=9999 et \emergencystretch=3em, \looseness=1 a bien fait passer six lignes à sept — au prix de six avertissements Underfull \hbox. Et \looseness=-1, le sens que tout le monde souhaite en réalité, n'a pas changé le nombre de lignes, faute de solution plus courte dans les limites de \tolerance. \looseness est un coup à tenter, pas un levier fiable. Quand il ne donne rien, supprimer un mot du manuscrit va plus vite.

latex
% Ask for one line fewer inside the paragraph itself.
% \looseness is reset by every \par, so it must sit inside the paragraph.
\tolerance=9999 \emergencystretch=3em
Some paragraph text ... \looseness=-1

% Only after the above has failed: one page, one line taller.
\enlargethispage{\baselineskip}

Où sont traités \pagebreak, \linebreak et \-

Cette page traite du rythme à l'échelle du document ; les commandes de coupure individuelles relèvent d'ailleurs. Côté page — \pagebreak[n] et \nopagebreak[n] (n de 0 à 4), le \newpage inconditionnel, \clearpage qui vide aussi les flottants en attente, et \cleardoublepage qui ajoute une page blanche en recto-verso — voyez le réglage fin des coupures de page. Côté ligne — \\, \newline, \linebreak[n], \nolinebreak[n], le trait d'union conditionnel \-, la liste d'exceptions \hyphenation{man-u-script} du préambule et le package hyphenat — voyez le réglage fin des coupures de ligne. La structure du paragraphe et \par appartiennent à la page sur les paragraphes. Quant à Overfull \hbox, \sloppy et \emergencystretch, ils ont une page d'erreur dédiée, où \sloppy est mesuré comme n'étant rien de plus que quatre affectations (\tolerance 9999, \emergencystretch 3em, \hfuzz .5\p@, \vfuzz\hfuzz).

Enfin, un membre de cette famille est déjà employé sans un mot pour votre compte. Les commandes de sectionnement portent temporairement \clubpenalty à 10000 pour le paragraphe qui suit un titre, de sorte qu'aucune coupure de page ne puisse tomber juste après — c'est à cela que sert la mécanique \@clubpenalty de latex.ltx. Voilà pourquoi un titre isolé en bas de page ne se produit pour ainsi dire jamais en LaTeX d'origine. Si cela arrive, c'est qu'une macro maison a remplacé la commande de sectionnement.