Comment modifier des marges en cours de document ?#
Il faut distinguer plusieurs opérations :
Création d’un paragraphe ou d’un ensemble de paragraphes dont la largeur ne correspond pas à celle du texte principal (comme le fait l’environnement
quote
) ;Ajout ou suppression de quelques lignes à la fin d’une page ;
Changement de la mise en page du document au cours d’une page ;
Changement de la mise en page d’une page à l’autre, en conservant une mise en page uniforme à l’intérieur de chaque page (par exemple pour déplacer légèrement la zone de texte afin qu’elle ne se retrouve pas dans la reliure au milieu du livre).
Pour toutes ces opérations, on peut généralement utiliser soit des commandes de base, soit l’extension changepage.
Avertissement
Il existe aussi une extension chngpage, à la syntaxe un peu différente, qui est classée comme obsolète. L’une des raisons est que, contrairement à changepage, elle ne prend pas en charge la classe memoir.
1. Modification de la largeur d’un paragraphe ou d’un groupe de paragraphes#
1.1. Avec des commandes de base de TeX#
La solution la plus simple reste d’utiliser les dimensions de TeX
\leftskip
et \rightskip
, qui définissent l’espacement supplémentaire
à gauche et à droite du paragraphe.
\documentclass{article}
\usepackage{lipsum}
\newenvironment{retrecir}[2]{
\begingroup
\leftskip=\dimexpr\leftskip#1\relax
\rightskip=\dimexpr\rightskip#2\relax
}
{\endgroup}
\begin{document}
\lipsum[1]
\begin{retrecir}{+2cm}{+1cm}
\lipsum[2]
\end{retrecir}
\lipsum[3]
\end{document}
Bien sûr, on peut élargir le paragraphe en donnant des arguments négatifs.
1.2. Avec des commandes de base de LaTeX#
Pour ajuster la largeur du texte en cours de document, la méthode suivante passe par un environnement
changemargin
dont les arguments indiquent la modification à effectuer
sur les marges de gauche et de droite respectivement.
Voici sa définition avec un exemple d’utilisation :
\documentclass{article}
\usepackage{lipsum}
\newenvironment{changemargin}[2]{%
\begin{list}{}{%
\setlength{\topsep}{0pt}%
\setlength{\leftmargin}{#1}%
\setlength{\rightmargin}{#2}%
\setlength{\listparindent}{\parindent}%
\setlength{\itemindent}{\parindent}%
\setlength{\parsep}{\parskip}%
}%
\item[]}
{\end{list}}
\begin{document}
\lipsum[1]
\begin{changemargin}{-1cm}{-1cm}
\lipsum[2]
\end{changemargin}
\end{document}
Cet environnement (qui est proche de l’environnement LaTeX quote
)
ne change pas la largeur du texte à l’échelle du document, c’est-à-dire \hsize
ou \textwidth
,
mais il insère son texte dans un environnement list
, qui lui-même utilise
\parshape
, une primitive de TeX qui permet de composer un paragraphe
de n’importe quelle forme. J’ignore pourquoi la FAQ anglophone
recommande une solution aussi contournée alors qu’il est très simple
d’ajuster \leftskip
et \rightskip
.
1.3. Avec l’extension changepage#
L’extension changepage fournit un environnement adjustwidth
qui est équivalent à l’environnement changemargin
défini ci-dessus.
2. Modification de la longueur de la page, donc du nombre de lignes#
2.1. Avec des commandes de base#
Changer les dimensions verticales d’une page est assez simple :
la commande LaTeX \enlargethispage
ajuste la taille de la page courante en fonction de son argument.
Voici un exemple courant augmentant la longueur de la page de la hauteur d’un ligne de texte :
\enlargethispage{\baselineskip}
Et voici l’opération opposée, réduisant la longueur de la page de la hauteur d’un ligne de texte :
\enlargethispage{-\baselineskip}
2.2. Avec l’extension addlines#
Le processus est (dans une certaine mesure) simplifié par l’extension addlines.
Sa commande \addlines
prend comme argument le nombre de lignes à ajouter à la page (plutôt qu’une longueur) :
la documentation de l’extension présente une analyse du moment où la commande peut fonctionner ou pas.
3. Changement de la mise en page du document avec effet immédiat au milieu de la page#
changepage fournit deux commandes qui modifient la mise en page à la volée.
Elles peuvent toutes deux être utilisées en plein milieu d’une page.
Dans ces deux commandes, les arguments indiquent non pas des valeurs absolues,
mais les modifications à apporter (donc 2cm
est équivalent à +2cm
) :
\changetext{<hauteur>}{<largeur>}{<marge extérieure>}{<marge intérieure>}{<séparation de colonnes>}
: Cette commande modifie les marges pour l’ensemble de la page courante, mais elle modifie la largeur du texte uniquement à partir de l’endroit où elle est invoquée.\changepage
prend les mêmes arguments que\changetext
avec les mêmes effets, mais ajoute en outre{<marge supérieure>}{<hauteur de l'en-tête>}{<espace sous l'en-tête>}{<espace au-dessus du pied de page>}
.
Attention : les paragraphes qui suivent cette commande seront alignés à gauche
au même niveau que les paragraphes qui précèdent : le paramètre <largeur>
affecte uniquement l’alignement à droite !
Si vous souhaitez que l’alignement à gauche soit décalé (comme dans l’environnement quote
),
utilisez l’environnement adjustwidth
présenté plus haut
ou, si vous souhaitez que le changement soit définitif ou sur plusieurs pages,
ajustez \leftskip
et \rightskip
.
4. Changement programmé de la mise en page d’une page à l’autre#
La technique exposée ci-dessous s’applique particulièrement à un cas (même si on peut en imaginer d’autres!) : lorsque l’on imprime un gros livre en dos carré collé, la marge intérieure des pages centrales disparaît en partie dans la reliure, si bien que, dans les cas extrêmes, une partie du texte peut disparaître. L’idéal serait donc de décaler progressivement la zone de texte vers la droite à mesure que l’on se rapproche du milieu du livre afin de conserver une marge intérieure satisfaisante. Pour que cette modification reste insensible, il faut qu’elle se fasse petit à petit, sur l’ensemble des pages.
Pour cela, on peut modifier l’output routine, c’est-à-dire l’ensemble de macros qui détermine comment la page est composée, notamment l’emplacement de la zone de texte principale et des paratextes.
Le document minimal suivant montre comment s’y prendre. Deux remarques sur cet exemple :
Pour les besoins de la démonstration, le décalage est largement exagéré : en réalité, il faut le calculer en fonction du nombre de pages, de l’épaisseur du papier et de sa rigidité. Normalement, il est de l’ordre de la fraction de millimètre ;
Cette technique fonctionne aussi avec l’option
twoside
. Elle est omise ici pour que l’on voie mieux le décalage d’une page à l’autre.
\documentclass[11pt,latin]{article}
\usepackage[a5paper]{geometry}
\usepackage{babel}
\usepackage{lipsum}
\usepackage{ifthen}
\newlength\offset
\setlength\offset{5mm} % À ajuster.
\newcommand*\adjustmargins{
% Cette macro décale la zone de texte vers l'extérieur
% à mesure que l'on s'approche du milieu du livre,
% puis la décale à nouveau vers l'intérieur
% une fois que l'on a dépassé le milieu.
\ifthenelse{\thepage<\numexpr\PreviousTotalPages/2}{
\global\addtolength\oddsidemargin\offset
\global\addtolength\evensidemargin{-\offset}
}{
\global\addtolength\oddsidemargin{-\offset}
\global\addtolength\evensidemargin\offset
}
% À ajouter si l'on utilise la classe memoir.
% \global\spinemargin=\oddsidemargin\relax
% \global\foremargin=\evensidemargin\relax
}
% On exécute ces modifications une fois que TeX a composé la page.
% Les valeurs modifiées seront donc utilisées pour la page suivante.
\AddToHook{shipout/after}\adjustmargins
\begin{document}
\lipsum[1-20]
% Le nombre total de pages n'est connu
% qu'à partir de la deuxième compilation :
% la ligne suivante sert uniquement à éviter
% que le document ne soit compilé qu'une fois.
\label{dummy}
\end{document}
Si l’on a une version ancienne de LaTeX qui ne fournit pas \AddToHook
,
on peut remplacer la ligne correspondante par \AtBeginShipout\adjustmargins
,
ce qui suppose de charger l’extension atbegshi.
Le décalage sera opéré dès la première page en procédant ainsi,
mais comme il est infime, les conséquences n’en seront pas perceptibles.
De même, si la macro \PreviousTotalPages
n’est pas définie,
le plus simple est encore de renseigner manuellement le nombre de pages de votre document.
Attention
Les extensions lastpage, totpages et count1to
ne permettent pas d’obtenir le nombre de pages total sous la forme
d’une valeur brute, ce qui est nécessaire pour opérer la division par deux
dans \ifthenelse
.
Si vous tenez à automatiser le calcul tout en conservant une version
de LaTeX qui ne fournit pas \PreviousTotalPages
,
il faudra utiliser zref (en particulier \zref@extract
)
avec abspage
.
Sources
Changing margins « on the fly » (à corriger en partie)
Thomas Savary et Didier Verna sur gut@ens.fr