Environnements de tableaux avancés

Un tabular simple donne à chaque colonne la largeur naturelle de son contenu. Dès que l’on veut qu’un tableau occupe exactement la largeur du texte, ou que des colonnes de texte courant aient la même largeur, il devient contraignant. Les packages qui résolvent ce problème sont tabularx (étirer les colonnes jusqu’à une largeur cible), tabulary (répartir la largeur selon la quantité de contenu de chaque colonne) et tabularray, de plus en plus standard (l’environnement tblr, un package moderne qui contrôle tout le tableau par options clé-valeur). Cette page compare les trois et donne un exemple pour chacun.

Le problème de largeur

Dans tabular, les colonnes l, c et r ne se replient jamais, et la colonne p{width} se replie mais vous oblige à calculer la largeur vous-même. Avec trois colonnes censées remplir exactement la largeur du texte \textwidth, deviner p{0.3\textwidth} et ainsi de suite oublie l’épaisseur des filets et l’espace inter-colonnes (\tabcolsep) : le tableau déborde ou reste trop court.

Il faut donc inverser le problème. Fixer d’abord la largeur et laisser les colonnes s’adapter, c’est tabularx. Répartir automatiquement la largeur selon la quantité de contenu de chaque colonne, c’est tabulary. Les deux sont des packages établis de David Carlisle (tabularx fait partie du bundle tools), chargés avec \usepackage{tabularx} ou \usepackage{tabulary}.

tabularx — la colonne X s’étire jusqu’à une largeur fixe

Contrairement à tabular, l’environnement tabularx prend la largeur cible du tableau comme premier argument : \begin{tabularx}{width}{column spec}. La spécification peut utiliser le nouveau type de colonne X, une colonne de type p qui s’étire ou se réduit automatiquement pour remplir la largeur restante. S’il y a plusieurs colonnes X, elles se partagent équitablement la largeur disponible.

Le mécanisme est un peu inhabituel : tabularx trouve les largeurs en composant le tableau plusieurs fois. Il commence par donner à chaque colonne X toute la largeur cible, ce qui rend le tableau trop large ; il divise l’excès par le nombre de colonnes X, réduit chacune d’autant, puis recompose, jusqu’à convergence. Au final, X est remplacé par la colonne définie par \tabularxcolumn, dont la valeur par défaut est :

latex
\newcommand{\tabularxcolumn}[1]{p{#1}}

Ainsi, X est par défaut une colonne de paragraphe alignée en haut. Pour centrer son contenu verticalement, redéfinissez \renewcommand{\tabularxcolumn}[1]{m{#1}}. Le contenu d’une colonne X est justifié par défaut ; pour l’aligner à gauche, préfixez la colonne par >{\raggedright\arraybackslash}X. Le point clé est \arraybackslash : \raggedright, \centering et \raggedleft redéfinissent \\ et entrent en conflit avec le terminateur de ligne d’un tableau ; placer \arraybackslash après ces déclarations rétablit \\ comme fin de ligne.

Si vous réutilisez le même préfixe, \newcolumntype permet de lui donner un alias d’une lettre pour améliorer la lisibilité. L’exemple ci-dessous définit la colonne 1 comme une colonne l à largeur naturelle et les deux autres comme des colonnes Y de même largeur, alignées à gauche et repliables, afin d’adapter tout le tableau à \textwidth.

document.tex
\usepackage{tabularx}
\newcolumntype{Y}{>{\raggedright\arraybackslash}X}
% ...
\begin{tabularx}{\textwidth}{l Y Y}
  \hline
  項目 & 長所 & 短所 \\
  \hline
  tabular  & 単純で速い & 幅を自分で調整する必要がある \\
  tabularx & 表幅を固定でき、列が自動で伸縮する & 試し組みのぶん処理が遅い \\
  \hline
\end{tabularx}

Ce tableau occupe toute la largeur du texte (\textwidth) ; la colonne 1 (« Item ») garde la largeur naturelle de ses mots courts, et les colonnes 2 et 3 reçoivent chacune la moitié de la largeur restante, où leurs descriptions longues se replient. Comme nous utilisons Y, c’est-à-dire un X aligné à gauche, chaque cellule a un bord droit irrégulier. Pour pondérer les colonnes différemment, la syntaxe à coefficients de tabularray, par exemple X[2], est pratique ; tabularx seul n’a pas d’option de coefficient.

Une réserve : comme le corps est développé plusieurs fois, les commandes à effets de bord (incrémenter des compteurs, écrire dans des fichiers, \verb, etc.) peuvent mal se comporter dans tabularx. Une cellule qui doit contenir une note ou \verb doit généralement être d’abord placée dans une boîte.

tabulary — répartir la largeur selon le contenu

tabularx divise l’espace également entre ses colonnes X. Mais lorsque les colonnes contiennent des quantités très différentes, par exemple un libellé court d’un côté et une longue description de l’autre, un partage égal semble maladroit. tabulary répartit plutôt la largeur en proportion de la largeur naturelle du contenu de chaque colonne, puis ajuste le total à la largeur demandée.

La syntaxe reprend celle de tabularx : \begin{tabulary}{width}{column spec}. Il existe quatre types de colonnes, toutes des colonnes de paragraphe à largeur automatique : L à gauche, C centrée, R à droite, J justifiée. On peut mélanger des l, c, r, p{width} ordinaires, etc., qui sont exclus de la mesure et gardés à largeur naturelle. Chaque colonne mesurée est pondérée par la largeur naturelle de sa cellule la plus large et redimensionnée pour que le total atteigne la largeur demandée ; mais une colonne dont la largeur naturelle est déjà plus petite reste telle quelle.

Pour limiter les répartitions extrêmes, deux longueurs encadrent une colonne mesurée : le minimum \tymin (par défaut 10pt) et le maximum \tymax (par défaut 2\textwidth). Elles sont utiles lorsqu’une seule entrée très longue dominerait autrement la largeur d’une colonne.

document.tex
\usepackage{tabulary}
% ...
\begin{tabulary}{\textwidth}{L L}
  \hline
  用語 & 説明 \\
  \hline
  X 列 & 表幅から固定部分を引いた残りを、X 列どうしで均等に分け合う列。 \\
  \hline
\end{tabulary}

Les deux colonnes sont ici L (alignées à gauche), mais la colonne 1 (« Term ») est étroite parce que son contenu est court, tandis que la colonne 2 (« Description ») reçoit une part plus large pour son texte. Avec tabularx et X X, les deux colonnes auraient la même largeur ; tabulary suit le poids du contenu, ce qui donne une proportion naturelle aux tableaux libellé + texte. Notez que tabulary traite aussi le corps deux fois ; les mêmes précautions concernant notes et compteurs que pour tabularx s’appliquent.

tabularray — l’environnement tblr moderne

tabularray est le package de tableaux le plus activement développé ces dernières années, écrit par Jianrui Lyu (lvjr). Il abandonne l’ancienne mécanique fondée sur \halign et analyse puis compose les tableaux directement avec LaTeX3 (expl3). Sa caractéristique majeure est d’unifier dans une seule interface clé-valeur ce qui nécessitait auparavant plusieurs packages, comme array, booktabs, multirow, colortbl ou diagbox, pour les filets, couleurs, fusions de cellules, formatage de paragraphes et largeurs de colonnes. Chargez-le avec \usepackage{tabularray} ; l’environnement principal est tblr.

La structure de tblr diffère légèrement de celle de tabular : avant le corps, on donne un argument d’options clé-valeur séparées par des virgules, la spécification interne, comme dans \begin{tblr}{ … inner spec … }. L’alignement des colonnes se déclare avec la clé colspec. On peut utiliser la forme à une lettre habituelle colspec={lcr}, mais la puissance vient surtout de Q[…] (colonne générique recevant alignement, largeur et autres options entre crochets) et de X[…] (colonne extensible, comme dans tabularx). X[c] est une colonne extensible centrée ; X[2,l] est une colonne extensible alignée à gauche avec coefficient 2, deux fois plus large qu’un X simple.

Lorsque vous utilisez des colonnes X, indiquez la largeur dans laquelle elles s’étendent avec la clé width (par défaut \linewidth). Les espaces entre lignes et colonnes sont contrôlés par rowsep et colsep, dont les valeurs par défaut dans tblr sont rowsep=2pt et colsep=6pt. Les filets sont déclaratifs : hlines / vlines tracent tous les filets horizontaux / verticaux, et hline{n} / vline{n} stylent une ligne précise, par exemple hline{2}={1pt,solid}. On n’écrit jamais \hline dans le corps.

Les fusions de cellules se font dans le corps avec \SetCell. \SetCell[c=2]{c} est une cellule centrée qui couvre 2 colonnes (équivalent de \multicolumn), et \SetCell[r=2]{c} couvre 2 lignes (équivalent de \multirow) ; c= et r= donnent l’étendue en colonnes / lignes, et l’argument entre accolades l’alignement de la cellule. Pour styliser des lignes ou colonnes entières, utilisez \SetRow / \SetColumn ; par exemple, \SetRow{cyan8} colore une ligne en cyan pâle (les noms de couleurs sont intégrés au package).

document.tex
\usepackage{tabularray}
% ...
\begin{tblr}{
  width = \textwidth,
  colspec = {Q[l] X[c] X[2,l]},
  rowsep = 3pt,
  hline{1,Z} = {1pt,solid},
  hline{2} = {0.5pt,solid},
  row{1} = {font=\bfseries},
}
  項目 & 区分 & 説明 \\
  \SetCell[r=2]{l} 表環境 & 固定幅 & 表全体の幅を固定し、X 列が残りを分け合う。 \\
   & 内容幅 & 各列の中身の量に応じて幅を配分する。 \\
  注記 & --- & 罫線・色・結合をキーで一括指定できる。 \\
\end{tblr}

Ce tblr fixe la largeur du tableau à celle du texte avec width=\textwidth. Les trois colonnes sont Q[l] (colonne de base alignée à gauche), X[c] (colonne extensible centrée) et X[2,l] (colonne extensible alignée à gauche avec coefficient 2) ; les deux colonnes X se partagent donc la largeur restante 1 : 2, et la colonne 3 (« Description ») devient la plus large. Aucun \hline n’apparaît dans le corps : les filets viennent seulement des clés hline{…} de la spécification interne (Z est l’indice spécial de la dernière ligne). La première ligne est en gras via row{1}={font=\bfseries}, et la cellule « Table environment » de la première colonne couvre deux lignes avec \SetCell[r=2]{l}. Obtenir tout cela sans charger booktabs, multirow et array est précisément l’intérêt de tabularray.

Pour les tableaux qui s’étendent sur plusieurs pages, il existe longtblr, avec lignes d’en-tête répétées, légendes et notes ; pour un tableau annoté d’une seule page dans l’esprit de threeparttable, utilisez talltblr. Dans ces environnements, la légende, le label, note{…} et éléments similaires se placent dans l’argument optionnel […] avant le corps, la spécification externe.

Lequel choisir

Règle pratique : pour ajuster un tableau à une largeur fixe avec des colonnes de texte de même largeur, utilisez tabularx ; pour fixer la largeur mais la répartir naturellement selon le contenu de chaque colonne, utilisez tabulary ; pour gérer filets, couleurs, fusions de cellules et largeurs de colonnes dans un seul système lors d’un nouveau tableau, utilisez tabularray.

tabularray est riche en fonctions et absorbe le problème de largeur que résolvent tabularx / tabulary, via les colonnes X et la clé width. À l’inverse, tabularx et tabulary sont mûrs, légers et s’intègrent bien au code tabular existant. En pratique : utilisez les anciens packages pour ajouter un contrôle de largeur à un petit tableau existant, et tabularray lorsque vous construisez des tableaux élaborés depuis zéro.

PackageDétermination de la largeurIdéal pour
tabularxTotal fixe ; colonnes X partagées égalementColonnes de texte de même largeur ajustées
tabularyTotal fixe ; réparti selon le contenuTableaux libellé + texte déséquilibrés
tabularrayClé width + colonnes X (avec coefficients)Tableaux modernes avec filets, couleurs et fusions unifiés

Les détails des spécifications de colonnes elles-mêmes (\multicolumn, >{…} du package array, etc.) se trouvent dans la page « spécification des colonnes », les bases de la fusion de cellules dans « fusion de cellules », et les très longs tableaux multipages dans la page « longtable ».