Les colonnes ne relèvent pas du style maison : ce sont une aide à la lecture. Une ligne de texte dans un article composé en 10 points fait 345pt de large, soit environ 78 caractères en anglais, alors que le typographe Robert Bringhurst situe la plage confortable entre 45 et 75 caractères et tient la ligne de 66 pour l’idéal. Que l’on découpe cette page en deux colonnes, et chaque ligne retombe dans la plage. C’est pour cela que revues, actes de congrès et journaux sont composés en colonnes, et LaTeX propose pour cela deux outils de tempéraments très différents : l’option de classe twocolumn et l’environnement multicols du paquet multicol. Ils semblent interchangeables ; ils ne le sont pas. Cette page suit les différences qui font vraiment mal : le nombre de colonnes possible, l’équilibrage ou non de la dernière page, et les deux manières bien distinctes dont une figure peut disparaître sans un mot.
twocolumn ou multicol : lequel choisir
twocolumn convient quand le document entier est à deux colonnes et comporte des figures ; multicol convient quand seule une partie doit être en colonnes, quand il en faut trois ou plus, ou quand la dernière page doit se terminer à égalité. La ligne de partage passe par les flottants. twocolumn laisse intact le mécanisme de flottants de LaTeX : une figure flotte toujours dans sa colonne et figure* couvre la page. multicol, lui, remplace entièrement la routine de sortie et, en échange de l’équilibrage, renonce complètement aux flottants à l’intérieur des colonnes. Presque tout ce qui suit sur cette page découle de ce seul échange.
| Forme | Colonnes | Effet |
|---|---|---|
twocolumn | 2 | Option de classe ; tout le corps passe à deux colonnes, la dernière page reste inégale |
\twocolumn[⟨text⟩] | 2 | Employé dans le corps ; force un saut de page, puis compose ⟨text⟩ pleine largeur au-dessus des colonnes |
\onecolumn | 1 | Employé dans le corps ; force un saut de page et revient à une colonne |
multicols | 2 à 10 | Environnement ; commence et se termine en milieu de page et équilibre les colonnes finales |
multicols* | 2 à 10 | Idem, mais les colonnes finales sont remplies depuis la gauche et laissées inégales |
Composer tout le document en deux colonnes avec twocolumn
Il suffit d’ajouter twocolumn aux options de classe : \documentclass[twocolumn]{article} compose tout le corps en deux colonnes (le défaut est onecolumn). Beaucoup de classes académiques sont conçues en interne autour de cette option. Pour changer de mode en cours de document, on appelle \twocolumn et \onecolumn dans le corps — avec deux réserves. Les deux commandes commencent une nouvelle page, le nombre de colonnes ne change donc jamais en milieu de page. Et \twocolumn produit toujours exactement deux colonnes. Dès qu’il en faut une troisième, cet outil est à bout.
\documentclass[twocolumn]{article}Ce \twocolumn accepte un argument optionnel, et c’est le plus souvent lui qui donne son visage à un article. \twocolumn[⟨matériel pleine largeur⟩] compose ce seul matériau en une colonne, sur toute la largeur au-dessus du texte à deux colonnes. Titre, auteurs, affiliation et résumé étalés sur la page, puis le corps qui s’écoule en deux colonnes dessous : la mise en page que porte tout article de conférence tient dans cette ligne.
\documentclass[twocolumn]{article}
\begin{document}
\twocolumn[%
\begin{center}
{\LARGE A Study of Narrow Measures}\\[4pt]
A. Author \quad Institute of Typography
\end{center}
\vspace{1em}
]
The body starts here and is set in two columns.
\end{document}L’écart entre les colonnes est la longueur \columnsep et l’épaisseur du filet qui s’y loge est \columnseprule. Dans les classes standard, \columnsep vaut 10pt par défaut et \columnseprule vaut 0pt, c’est-à-dire aucun filet. Avec des chiffres, l’argument d’ouverture devient concret : un article en 10 points a une \textwidth de 345pt, donc une colonne mesure (345 − 10) ÷ 2 = 167.5pt, soit environ 38 caractères en anglais. Cela tombe juste sous la fourchette de 40 à 50 que Bringhurst recommande pour le travail multicolonne : chaque point ajouté à \columnsep est pris à une justification qui n’a rien à céder. Le filet est souvent le meilleur échange : il sépare les colonnes à l’œil, ce qui permet de garder l’écart étroit.
\setlength{\columnsep}{20pt} % wider gap between the columns
\setlength{\columnseprule}{0.4pt} % thin vertical rule inside the gapÉtendre une figure sur les deux colonnes : figure* et table*
Il faut employer les environnements étoilés. \begin{figure*} et \begin{table*} produisent un flottant qui couvre les deux colonnes sur toute la justification de la page. Une distinction à l’intérieur évite la plupart des accidents : \columnwidth est la largeur d’une colonne, tandis que \textwidth est celle du bloc de texte entier — les deux colonnes plus l’écart. Une image destinée à une colonne prend width=\columnwidth, une image à cheval prend width=\textwidth. Inversées, elles donnent soit une boîte débordante, soit une figure bizarrement petite.
\documentclass[twocolumn]{article}
\usepackage{graphicx}
\begin{document}
% one column wide: an ordinary float
\begin{figure}
\centering
\includegraphics[width=\columnwidth]{plot}
\caption{Fits inside a single column.}
\end{figure}
% spans both columns: starred float, default placement is [tp]
\begin{figure*}[t]
\centering
\includegraphics[width=\textwidth]{wide-plot}
\caption{Spans the full text width.}
\end{figure*}
\end{document}Se plaindre qu’un figure* « n’apparaît pas là où je l’ai écrit » ou « a sauté trois pages plus loin » prend tout son sens dès qu’on connaît son défaut. Les sources du noyau LaTeX indiquent explicitement que tous les flottants double colonne ont pour placement par défaut tp. \begin{figure*} est donc traité en silence comme [tp] — haut de page ou page de flottants dédiée — et jamais comme htbp. De plus, comme le note le manuel de référence LaTeX2e, b n’est pas autorisé pour les flottants pleine largeur en sortie à deux colonnes. Si le haut de la page suivante est déjà pris, le flottant continue de glisser. Pour en placer un en pied de page malgré tout, charger stfloats ou dblfloatfix rend b opérant.
Cette file d’attente a longtemps abrité un défaut assez savoureux. Avant la version de 2015, LaTeX gérait les flottants en attente dans deux listes distinctes : une pour les flottants d’une colonne, une pour ceux de deux colonnes. Deux files, cela veut dire des dépassements : une Figure 3 d’une colonne pouvait doubler une Figure 2 pleine largeur écrite plus tôt et s’imprimer avant elle. Le correctif est d’abord paru sous forme du paquet fixltx2e, qui fusionnait les deux listes en une seule. En 2015, tous les correctifs de fixltx2e ont été intégrés au noyau lui-même : sur une installation TeX actuelle, il n’y a plus rien à charger. Devant un vieux billet sur des figures dans le désordre, commencez par en regarder la date.
Trois colonnes ou plus, et des colonnes qui finissent à égalité : multicol
On charge \usepackage{multicol}, on entoure la zone d’un environnement multicols et on passe le nombre de colonnes en argument. Cela seul donne accès à 2 à 10 colonnes (le plafond de dix existe depuis la version 1.5) ; l’environnement commence et se termine en milieu de page et, en se refermant, égalise lui-même les hauteurs. Les environnements multicols peuvent même s’imbriquer. Comme rien ne force de saut de page, glisser un glossaire ou un index sur trois colonnes au milieu d’un texte à une colonne se fait tout naturellement.
\usepackage{multicol}
% ... later, in the body
\begin{multicols}{3}
This text is broken into three balanced columns.
\end{multicols}multicol doit son existence à un index. En 1989, alors qu’il écrivait les macros du paquet doc, Frank Mittelbach voulait faire tenir l’index et la bibliographie d’un fichier de documentation sur une même page. Le mode deux colonnes standard ne le permet pas : \twocolumn commence toujours une nouvelle page, et la dernière s’achève sur une colonne de droite à moitié vide. Dans la documentation du paquet, il note que la première version lui a coûté un week-end entier et qu’il est parti de l’algorithme de la page 417 du TeXbook — en précisant que la remarque date de la version initiale et que plusieurs centaines d’heures ont été investies depuis. L’équilibrage n’a donc pas été conçu comme un ornement, mais comme un moyen d’économiser du papier.
multicols accepte deux arguments optionnels après le nombre de colonnes. Le premier, [⟨texte introductif⟩], est un titre ou une entrée en matière composés pleine largeur juste au-dessus des colonnes. Le second, [⟨longueur⟩], est l’espace libre minimal qui doit rester en bas de page pour que les colonnes y commencent ; il remplace pour cette seule fois le défaut \premulticols (50pt). S’il reste moins que cela, l’environnement démarre sur une page neuve. Omis après un long préambule, le paquet peut s’arrêter sur l’erreur Error saving partial page, suivie de Some text may be lost! — et de la consigne d’augmenter \premulticols.
\begin{multicols}{3}
[\section{Glossary}
This heading and this sentence run the full text width.]
[6cm]
Everything after the optional arguments is split into three columns.
\end{multicols}Pourquoi la dernière page d’un document twocolumn ne s’équilibre pas
Parce que LaTeX termine chaque colonne avant de savoir qu’il y en aura une suivante. En mode deux colonnes, la routine de sortie \@outputdblcol s’exécute une fois par colonne : quand la colonne de gauche est pleine, son contenu est rangé dans une boîte nommée \@leftcolumn et la composition reprend ; ce n’est qu’une fois la colonne de droite pleine que la page est assemblée et expédiée. À aucun instant LaTeX ne tient le texte restant et n’a le loisir de décider comment le partager en deux. Ce qui reste à \end{document} se déverse donc dans la colonne de gauche et s’y arrête, laissant la droite courte. Ce n’est pas un défaut : c’est ce que produit nécessairement une construction de page séquentielle.
multicol renverse cet ordre, et tout le tour est là. Sa documentation décrit deux étapes : rassembler d’abord le matériau de l’environnement, puis équilibrer en arrivant à la fin. Parce que la collecte précède, le paquet peut découper la boîte obtenue avec \vsplit et essayer différentes hauteurs jusqu’à ce que les colonnes soient presque égales. La version 1.5 y a ajouté un contrôle de qualité : chaque candidat est mesuré sur l’échelle de badness de TeX (0 est parfait, 10000 infiniment mauvais) et les solutions plus mauvaises que le compteur columnbadness — 10000 par défaut — sont rejetées. Un compteur jumeau, finalcolumnbadness à 9999, juge qu’une dernière colonne peu remplie vaut mieux courte qu’étirée jusqu’à la laideur.
\raggedcolumns— ne pas aligner le pied des colonnes ; le défaut,\flushcolumns, les aligne- compteur
unbalance— allonger toutes les colonnes sauf la dernière de N lignes ; remis à zéro à la fin de chaque environnement - compteur
minrows(défaut 1) — nombre minimal de lignes dans la première colonne, pour éviter les colonnes d’une ligne - compteur
columnbadness(défaut 10000) — rejeter toute solution dont la badness dépasse cette valeur - compteur
finalcolumnbadness(défaut 9999) — au-delà, une dernière colonne courte reste courte au lieu d’être étirée \maxbalancingoverflow(défaut 12pt) — si les colonnes équilibrées dépassent de plus que cela, l’équilibrage est abandonné et une page ordinaire est produite
En pratique, il reste trois gestes. Pour rester sur twocolumn et n’égaliser que la dernière page, les paquets balance et flushend corrigent la routine de sortie dans ce but. La TeX FAQ prévient toutefois que tous deux se laissent facilement dérouter par les flottants et qu’un ajustement manuel des figures peut alors s’imposer. Les solutions les plus solides consistent à n’envelopper que la fin du document dans un environnement multicols, ou à accepter une colonne de droite courte : la plupart des styles de revue s’en accommodent.
Choisir où la colonne se coupe : \columnbreak et le filet de séparation
\columnbreak termine la colonne courante exactement là où il est posé et pousse la suite dans la suivante ; il est apparu en version 1.5u. Depuis la 1.9, il accepte un argument optionnel calqué sur celui de \pagebreak, de \columnbreak[0] (préférence légère) à \columnbreak[4] (forcé). La même version 1.9 a ajouté \newcolumn, qui coupe la colonne et la laisse courte. Pourquoi ne pas recourir à \pagebreak ici ? C’est tout aussi net : dans multicols, il mettrait fin à la phase de collecte elle-même et refermerait d’un coup toutes les colonnes de la page.
\setlength{\columnsep}{1.5em} % gap between columns
\setlength{\columnseprule}{0.4pt} % show a rule in the gap
\renewcommand{\columnseprulecolor}{\color{gray}}
\begin{multicols}{2}
Text of the left column.
\columnbreak % push the rest into the next column
Text of the right column.
\end{multicols}L’écart et le filet obéissent aux mêmes \columnsep et \columnseprule que sous twocolumn, et multicol y ajoute \columnseprulecolor (défaut \normalcolor, la couleur du texte). Ces réglages se font avant d’entrer dans l’environnement. Le paquet modifie encore un paramètre sans le dire : la tolérance de coupure des lignes. La \tolerance habituelle de LaTeX vaut 200, la valeur derrière \fussy, bien trop sévère pour une justification de 38 caractères. Dans l’environnement, multicol bascule donc sur \multicoltolerance (défaut 9999), à un pas des 10000 qui signifient « tout est permis » : un compromis pragmatique pour des colonnes étroites. Si le texte justifié bâille encore, les remèdes classiques sont \raggedright dans l’environnement ou de meilleurs motifs de césure pour la langue employée.
Pourquoi une figure disparaît dans multicols
Parce que les flottants ordinaires n’y sont pas implémentés et que tout ce qu’on y place est jeté. Écrivez un environnement figure ou table — ou un \marginpar — dans multicols, et le journal porte l’avertissement Floats and marginpars not allowed inside 'multicols' environment!. La documentation du paquet est directe sur la conséquence : de tels flottants disparaissent. Elle en donne aussi la raison. Implémenter les flottants supposerait de réécrire entièrement la routine de sortie de LaTeX, bien au-delà du week-end qu’a coûté la première version. Comme il s’agit d’un avertissement et non d’une erreur, le document se compile quand même. Quand une figure manque et que rien d’autre ne cloche dans le journal, c’est cette ligne qu’il faut chercher d’abord.
| Construction | en mode twocolumn | dans multicols |
|---|---|---|
figure / table | flotte normalement dans sa colonne | interdit ; un avertissement paraît et le flottant disparaît |
figure* / table* | couvre la page ; défaut [tp], b indisponible | fonctionne ; t, b et p s’appliquent, mais jamais sur la page où il est écrit |
\marginpar | fonctionne | interdit ; disparaît avec le même avertissement |
\columnbreak | absent ; seul le saut de page reste | termine la colonne à cet endroit (depuis 1.5u) |
\pagebreak | ferme la page | met fin à la phase de collecte, donc toutes les colonnes de la page se ferment ensemble |
\columnseprule | filet vertical dans l’écart ; défaut 0pt | idem, avec en plus \columnseprulecolor pour la couleur |
Les flottants étoilés fonctionnent bien dans multicols, mais autrement que sous twocolumn. D’après la documentation, un figure* y est traité à peu près comme un flottant ordinaire sur une page à une colonne : t, b et p s’appliquent tous, et c’est \topfraction qui compte, non \dbltopfraction. Une restriction est toutefois absolue : il n’apparaîtra jamais sur la page où il a été écrit. La première place possible est le haut de la page suivante, ce qui rend h sans objet. De là vient l’inversion curieuse : b est indisponible sous twocolumn et disponible dans multicols.
Comment, alors, placer une petite image dans une colonne ? La réponse : n’en faites pas un flottant. Un \includegraphics posé directement dans un environnement center reste exactement là où il a été écrit (dans l’environnement, \linewidth vaut la largeur de colonne, width=\linewidth s’impose donc). S’il faut une légende numérotée, \captionof{figure}{…} du paquet caption la fournit en préservant numérotation et renvois. Pour habiller le texte autour, wrapfig reste l’autre voie. Mais dès qu’il apparaît que des flottants dans les colonnes sont nécessaires tout au long du document, c’est le signal de choisir twocolumn plutôt que multicol.
\usepackage{multicol}
\usepackage{graphicx}
\usepackage{caption} % provides \captionof
% ... in the body
\begin{multicols}{2}
Text before the picture.
\begin{center}
\includegraphics[width=\linewidth]{plot}
\captionof{figure}{Not a float, so it stays where it is written.}
\end{center}
Text after the picture.
\end{multicols}