Le & que l’on tape dans un tableau n’est pas une esperluette du point de vue de LaTeX. C’est un caractère doté d’un code de catégorie particulier — le numéro 4, que TeX appelle alignment tab. D’où l’erreur ! Extra alignment tab has been changed to \cr. lorsque le nombre de colonnes ne tombe pas juste : elle est formulée avec un mot qui n’apparaît nulle part à l’écran. Cette page parcourt les trois conventions de l’environnement tabular — séparer les cellules par &, fermer une ligne par \\, tracer un filet avec \hline — ainsi que la mécanique qui les porte. Une fois celle-ci visible, les deux erreurs que tout débutant rencontre, Extra alignment tab et Misplaced \noalign, cessent d’être des énigmes pour devenir des consignes.
Les trois symboles de tabular : &, \\ et \hline
Trois symboles seulement ont un sens dans le corps d’un tabular. & sépare les cellules d’une même ligne, \\ ferme une ligne, et \hline trace à cet endroit un filet horizontal sur toute la largeur du tableau. \begin{tabular} prend immédiatement après lui un argument obligatoire : la spécification des colonnes. \begin{tabular}{ccc} déclare « trois colonnes centrées », et le nombre de colonnes fixé là constitue l’ossature du tableau entier. Les espaces autour de & sont ignorés : rien n’empêche de les utiliser dans la source pour aligner visuellement les cellules.
\begin{tabular}{ccc}
\hline
A & B & C \\
D & E & F \\
\hline
\end{tabular}\\ n’est pas un symbole propre aux tableaux : c’est la commande de saut de ligne générale de LaTeX. Le même symbole sert de séparateur de lignes dans pmatrix et dans align, si bien que le réflexe « aligner les colonnes avec &, passer à la ligne avec \\ » se transporte tel quel des tableaux aux formules. Le \\ après la dernière ligne peut être omis, mais pour tracer un filet sous cette ligne il faut d’abord la fermer par \\ et seulement ensuite écrire \hline — sans quoi on tombe droit sur le Misplaced \noalign traité plus loin. \\ accepte aussi un argument optionnel entre crochets : \\[2pt] ajoute une espace verticale supplémentaire sous la ligne, une valeur négative la resserre.
\begin{tabular} accepte aussi, avant la spécification des colonnes, un argument optionnel de position verticale entre crochets. \begin{tabular}[t]{…} aligne le haut du tableau sur la ligne de base environnante, [b] son bas ; par défaut, c’est le centre vertical qui s’aligne. Un piège guette toutefois : si le tableau commence ou se termine par \hline, l’alignement se fait au niveau du filet et le résultat n’est pas celui attendu. Le package array prévoit précisément \firsthline et \lasthline pour ce symptôme — écrits à la place de \hline, ils font tomber l’alignement sur la première ou la dernière ligne de texte.
Extra alignment tab has been changed to \cr — le nombre de colonnes ne colle pas
Cette erreur ne signifie qu’une chose : il y a plus de & dans la ligne que la spécification n’a déclaré de colonnes. Écrivez A & B & C dans un tableau déclaré {ll} et elle apparaîtra à coup sûr. TeX se rattrape en lisant le & excédentaire comme une fin de ligne (\cr) et poursuit : rien ne disparaît, on obtient un tableau décalé. L’erreur de comptage est la cause habituelle, mais trois autres reviennent souvent : un & dans une ligne où \multicolumn{3}{c}{…} a déjà consommé les trois colonnes ; un \\ tapé à l’intérieur d’une cellule ; et le >{\raggedright} d’array appliqué à la dernière colonne. Ce dernier mord parce que \raggedright redéfinit \\ : le terminateur de ligne cesse d’agir, le & de la ligne suivante déborde et produit la même erreur — >{\raggedright\arraybackslash} règle le problème.
À l’inverse, avoir trop peu de & ne dit rien du tout. Les cellules manquantes sont simplement composées vides, sans erreur ni avertissement ; lorsqu’un tableau est visiblement décalé mais compile sans broncher, le premier soupçon va donc à un & oublié. Autre indice : si l’on écrit une lettre inconnue dans la spécification, la formulation de l’erreur dépend du package chargé. LaTeX seul annonce ! LaTeX Error: Illegal character in array arg., alors qu’avec array chargé on obtient ! Package array Error: Illegal pream-token. Laquelle des deux apparaît indique sur quelle implémentation tourne réellement le tableau.
Misplaced \noalign — \hline ne tient qu’entre deux lignes
Cette erreur vient presque toujours d’une seule chose : avoir écrit \hline sans avoir fermé la ligne par \\. Oubliez le \\ après la dernière ligne, enchaînez sur \hline, et le journal de TeX Live 2024 affiche trois erreurs en cascade — ! Misplaced \noalign., ! You can't use \hrule here except with leaders. et ! Missing number, treated as zero.. Les trois découlent d’une même cause. Elle tient à la définition même de \hline : dans latex.ltx on lit \def\hline{\noalign{…\hrule \@height \arrayrulewidth …}}. \noalign est une primitive de TeX qui signifie uniquement « insérer ce matériel entre les lignes d’un alignement ». Appelée au milieu d’une ligne, elle n’a nulle part où aller : \noalign, puis son contenu prévu \hrule, débordent l’un après l’autre.
% WRONG: the last row was never closed, so \hline has no gap to sit in
\begin{tabular}{ll}
A & B \\
C & D
\hline
\end{tabular}
% RIGHT: close the row first, then draw the rule
\begin{tabular}{ll}
A & B \\
C & D \\
\hline
\end{tabular}Pour la même raison, un \hline écrit à l’intérieur d’une cellule produit exactement le même trio d’erreurs. À l’inverse, un \hline seul, juste après un \\, est toujours sans danger, et même \hline \\, qui crée une ligne vide, n’est pas une erreur : cela ajoute simplement de l’espace visible. Autre message omniprésent autour de tabular : ! LaTeX Error: \caption outside float., résultat classique d’un \caption placé dans un tabular — comme l’explique la section suivante, la légende est l’affaire de table. Un \end{tabular} oublié donne le plus obligeant ! LaTeX Error: \begin{tabular} on input line N ended by \end{document}., qui livre jusqu’au numéro de ligne.
Tracer des filets, et ceux qu’il vaut mieux ne pas tracer
Les filets horizontaux viennent de \hline, les verticaux d’un | inscrit dans la spécification des colonnes. {|l|c|r|} place des lignes aux bords extérieurs et entre les trois colonnes ; avec \hline, chaque cellule devient une case d’une grille. \hline\hline donne un double filet, l’écart entre les deux valant la longueur \doublerulesep (2 pt par défaut). L’épaisseur du filet est la longueur \arrayrulewidth, 0,4 pt dans les classes standard. \cline{2-3} prend une plage de numéros de colonnes et ne trace que sur une partie de la largeur. Voilà l’ensemble des filets que LaTeX standard sait tracer.
| Notation | Rôle | Remarques |
|---|---|---|
& | Sépare les cellules d’une ligne | Code de catégorie 4 ; en excès, Extra alignment tab |
\\ | Ferme une ligne | Même rôle dans align et pmatrix |
\\[2pt] | Ajoute une espace sous la ligne | Une valeur négative resserre |
\hline | Filet horizontal pleine largeur | Épaisseur : \arrayrulewidth (0,4 pt) |
\hline\hline | Double filet horizontal | Écart : \doublerulesep (2 pt) |
\cline{2-3} | Filet des colonnes 2 à 3 seulement | L’usage sous les cellules fusionnées |
| | Filet vertical, écrit dans la spécification | À éviter dans les tableaux formels |
|| | Double filet vertical | L’écart est là encore \doublerulesep |
Or, parmi les outils qui viennent d’être listés, la typographie professionnelle tient que filets verticaux et doubles filets ne devraient pas être employés du tout. Le manuel de booktabs, Publication quality tables in LaTeX de Simon Fear (la version fournie avec TeX Live 2024 est révisée le 12 janvier 2020), énonce deux principes : « 1. Never, ever use vertical rules. 2. Never use double rules. » L’auteur va jusqu’à écrire que si la moitié gauche d’un tableau diffère au point d’appeler une ligne de séparation, mieux vaut faire deux tableaux — et ajoute honnêtement avoir travaillé pour un éditeur qui exigeait un double filet fin au-dessus d’une ligne de totaux, « but this would not have been my choice ». Ce qu’il recommande à la place : des filets horizontaux d’épaisseurs différentes, avec de l’air au-dessus et au-dessous.
L’essentiel est que ces principes ne valent pas pour tous les tableaux. Fear trace une frontière explicite entre la formal table — un ensemble de valeurs dans des colonnes étiquetées — et le tableau, cette mise en page ponctuelle qui sera sans doute couverte d’icônes et fera aussi appel à la couleur ; les deux principes visent expressément la première. La mise en page d’un tableau formel, écrit-il, s’est établie au fil des siècles et ne devrait être modifiée que dans des circonstances extraordinaires. Lu à l’envers : encadrer un emploi du temps ou un schéma d’interface ne relève tout simplement pas de ces principes. Pour un tableau de chiffres dans un article, l’usage moderne est booktabs avec \toprule, \midrule et \bottomrule, traité en détail dans « Filets et tableaux de qualité publication ».
Quand les lignes paraissent à l’étroit et que les filets semblent toucher les lettres, le remède le plus rapide est d’augmenter le multiplicateur de hauteur avec \renewcommand{\arraystretch}{1.2} (la valeur par défaut est 1). L’espace entre colonnes est la longueur \tabcolsep, 6 pt de chaque côté par défaut, donc 12 pt au total entre deux colonnes. Si le package array est chargé, on dispose en plus de \setlength{\extrarowheight}{2pt}, qui n’ajoute qu’à la hauteur de chaque ligne et laisse la profondeur intacte — exactement ce qu’il faut contre les filets qui frôlent le sommet des capitales.
tabular et table : un tableau n’est pas un flottant
tabular compose le contenu d’un tableau, et rien d’autre : ni numéro, ni légende, ni voix au chapitre sur le placement. Il est traité comme un morceau de texte, donc il peut se trouver au milieu d’un paragraphe, dans un élément de liste, voire dans une note de bas de page. table, lui, est un flottant. On l’enroule autour d’un tabular et il fournit un titre numéroté automatiquement via \caption{…}, des références croisées via \label{…} et \ref{…}, ainsi que des spécificateurs de placement comme [htbp]. Écrire \caption dans un tabular donne ! LaTeX Error: \caption outside float. : cette répartition des rôles, transformée en message d’erreur.
\begin{table}[htbp]
\centering
\caption{Quarterly sales}
\label{tab:sales}
\begin{tabular}{lrr}
\hline
Quarter & Sales & YoY \\
\hline
Q1 & 1{,}200 & +5\% \\
Q2 & 1{,}350 & +8\% \\
\hline
\end{tabular}
\end{table}
% ... and refer to it from the running text:
See Table~\ref{tab:sales}.La raison d’en faire un flottant tient moins à la numérotation qu’au fait qu’un tabular ne peut pas se couper entre deux pages. Il est composé comme une grande boîte : s’il n’entre pas dans ce qui reste de la page, il bascule en bloc sur la suivante et laisse un blanc derrière lui. Placée dans un table, cette boîte peut être déplacée par LaTeX en haut d’une page ultérieure, le blanc étant comblé par du texte. [htbp] est une liste de souhaits — ici, haut de page, bas de page, page dédiée — et LaTeX essaie les positions dans cet ordre. Un tableau trop haut pour tenir sur une page ne peut pas être un flottant du tout : c’est l’affaire de longtable, qui se coupe d’une page à l’autre.
Un tableau avec du texte long : sans p{width}, il déborde de la page
Les trois spécificateurs l, c et r n’élargissent la colonne qu’à la largeur naturelle de son contenu et ne se replient jamais dans la ligne. Mettez une longue description directement dans une colonne l et celle-ci s’étire à la largeur de cette unique ligne, poussant le tableau hors de la justification. Ce que l’on obtient est l’avertissement Overfull \hbox (…pt too wide) — un avertissement, pas une erreur : le document compile quand même et l’on ne s’en aperçoit qu’en regardant le PDF. C’est ce qui rend ce défaut agaçant. S’il faut un repli, tabular seul n’offre qu’un spécificateur : p{width}. Il compose la cellule en boîte de paragraphe de la largeur donnée, et ce qui dépasse passe automatiquement à la ligne suivante.
\begin{tabular}{l p{5cm} r}
\hline
Item & Description & Price \\
\hline\hline
Apple & A large honey-cored variety, popular as a gift. & 380 \\
Orange & A small, sweet citrus that peels by hand. & 120 \\
\hline
\end{tabular}La colonne 1 est alignée à gauche à sa largeur naturelle, la colonne 3 à droite, et seule la colonne 2 est une colonne p de 5 cm. La longue description se replie à ces 5 cm : cette cellule seule devient multiligne et la ligne grandit d’autant. La même phrase dans une colonne l s’étire simplement de côté sans se replier — la différence décisive qu’apporte p{width}. Sous l’en-tête figure un double filet \hline\hline ; des filets simples \hline ferment le haut et le bas. Le contenu d’une colonne p est par défaut aligné en haut et justifié, et l’indentation \parindent y vaut 0. Vouloir la cellule centrée ou alignée en bas verticalement, ou composée au fer à gauche plutôt que justifiée, mène au territoire d’array, traité dans « spécificateurs de colonnes en détail ».