Boîtes

LaTeX compose tout, texte, mathématiques et figures, en plaçant d’abord le contenu dans des boîtes, puis en disposant ces boîtes sur la page. Une boîte est un rectangle rigide doté de trois dimensions (largeur, hauteur, profondeur) ; l’algorithme de coupure des lignes ne regarde jamais à l’intérieur et la traite comme une unité indivisible. Une fois cette idée comprise, déplacer, superposer, encadrer ou construire des colonnes devient autant de variantes d’un même mécanisme.

Le modèle de boîte

À l’intérieur de TeX, chaque élément composé est une boîte avec des dimensions. Un caractère est une boîte, un mot est une boîte, une ligne est une boîte, et une page entière aussi. Pour construire les lignes et les paragraphes, LaTeX relie ces boîtes avec des espaces extensibles, puis coupe les lignes et les pages aux meilleurs endroits. Le point essentiel est le suivant : une fois qu’un contenu est placé dans une seule boîte, il n’est plus jamais divisé. Aucun saut de ligne ne se produit à l’intérieur ; la boîte entière passe à la ligne suivante comme une seule unité.

Les boîtes LaTeX se répartissent en deux grandes familles. La première est la boîte LR (left-to-right box) : elle place son contenu sur une seule ligne et ne coupe jamais la ligne ; si elle devient trop large, elle déborde dans la marge. \mbox, \makebox et la boîte encadrée \fbox sont des boîtes LR. La seconde est la boîte de paragraphe : elle replie son contenu dans une largeur fixée à l’avance, ce qui lui permet de contenir plusieurs lignes et même plusieurs paragraphes. \parbox et l’environnement minipage sont des boîtes de paragraphe.

Cette distinction reflète les modes de TeX. L’intérieur d’une boîte LR est en mode LR : l’entrée s’écoule simplement de gauche à droite et ne se coupe pas. Une boîte de paragraphe passe en mode paragraphe (interne), où la coupure des lignes fonctionne comme dans le texte ordinaire. Savoir quelle commande crée quel mode rend beaucoup plus clair pourquoi un contenu refuse de se replier, ou pourquoi une boîte s’allonge vers le bas.

Boîtes LR : tout sur une ligne

La boîte LR la plus élémentaire est \mbox{...}. Elle enferme son contenu dans une seule boîte et interdit à la fois les sauts de ligne et la césure. Placez dans \mbox une expression que vous ne voulez jamais couper, par exemple un nom de produit comme Mac OS X, un numéro de téléphone ou un long nom chimique, et elle restera toujours sur une seule ligne. C’est aussi pratique pour de petites corrections, comme garder une valeur attachée à son unité.

Pour choisir vous-même la largeur, utilisez \makebox[width][position]{text}. [width] fixe la largeur de la boîte, et [position] choisit où placer le contenu à l’intérieur : l aligné à gauche, c centré (valeur par défaut), r aligné à droite, et s étire les espaces entre les mots pour justifier la ligne sur toute la largeur. En plus des longueurs ordinaires comme \textwidth, la largeur peut utiliser des longueurs spéciales représentant la taille naturelle du contenu : \width (sa largeur), \height et \depth, ainsi que \totalheight (hauteur plus profondeur). Ainsi \makebox[2\width]{word} crée une boîte deux fois plus large que le mot.

La boîte de largeur nulle \makebox[0pt][position]{text} est particulièrement puissante. Comme sa largeur vaut 0, LaTeX compose le contenu mais n’avance pas la position horizontale ; ce contenu peut donc se superposer à ce qui suit. Avec [c], il déborde des deux côtés du point courant ; avec [r], vers la gauche ; avec [l], vers la droite. Ce mécanisme sert aux barrés, aux surimpressions et aux notes dans la marge ; les raccourcis \rlap et \llap (boîtes de largeur nulle débordant respectivement à droite et à gauche) fonctionnent de la même façon.

Pour tracer un cadre, utilisez \fbox{text} et \framebox[width][position]{text}, qui dessinent un filet sur les quatre côtés de la boîte. Les arguments [width][position] de \framebox sont exactement ceux de \makebox. L’aspect du cadre dépend de deux longueurs : l’épaisseur du filet \fboxrule (0.4pt par défaut) et l’espace entre le cadre et le contenu \fboxsep (3pt par défaut). On les modifie avec \setlength ; par exemple, \setlength{\fboxsep}{0pt} colle le cadre au contenu. Ce sont des boîtes LR sur une seule ligne ; pour encadrer plusieurs lignes, combinez-les avec les boîtes de paragraphe ci-dessous (pour des cadres plus élaborés, voir « Cadres »).

document.tex
Do not break \mbox{Mac OS X} here.

% a 4cm box, contents flush right, then framed
\framebox[4cm][r]{right} \\[1ex]

% zero-width box: the word overprints what follows
X\makebox[0pt][l]{\,/} Y   % prints an X/ over the gap before Y

Dans cet exemple, l’expression placée dans \mbox reste toujours sur une seule ligne, \framebox[4cm][r] met son contenu à droite dans un cadre de 4 cm, et la boîte de largeur nulle surimprime une barre oblique juste après le X.

Boîtes de paragraphe : parbox et minipage

Lorsque vous voulez fixer une largeur et laisser le contenu se replier, les boîtes de paragraphe prennent le relais. La version légère est \parbox[position]{width}{text} : elle replie son contenu comme un seul paragraphe dans la {width} donnée. [position] indique où la boîte s’aligne par rapport à la ligne environnante : c (par défaut, le centre de la boîte s’aligne sur le centre de la ligne), t (la ligne de base de la première ligne de la boîte s’aligne sur la ligne de base environnante) ou b (celle de la dernière ligne). On peut aller plus loin avec \parbox[position][height][inner-pos]{width}{text} pour fixer une hauteur et un alignement vertical interne (t/c/b/s), mais \parbox ne gère qu’un seul paragraphe : pas de paragraphes multiples ni de listes.

La boîte de paragraphe la plus souple est l’environnement minipage : \begin{minipage}[position][height][inner-pos]{width}\end{minipage}. Ses arguments ont le même sens que ceux de \parbox, mais son contenu se comporte comme une petite page autonome. Elle peut contenir plusieurs paragraphes, des listes comme itemize, et même du verbatim ; c’est l’outil principal parmi les boîtes de paragraphe. À noter : à l’intérieur, l’indentation des paragraphes (\parindent) est remise à 0 ; définissez-la vous-même avec \setlength{\parindent}{1em} si nécessaire.

Une minipage possède aussi sa propre gestion des notes de bas de page. Une \footnote utilisée à l’intérieur n’apparaît pas en bas de la page, mais juste sous la minipage, avec des lettres minuscules a, b, … (grâce au compteur dédié mpfootnote). C’est pratique quand une note doit rester autonome dans un tableau ou un encadré. En revanche, une minipage ne peut pas contenir de flottants (figure/table) et n’est jamais coupée entre deux pages : elle doit tenir sur la page comme une seule boîte.

L’usage le plus courant des minipages est la création de colonnes côte à côte. Placez deux minipages l’une après l’autre avec un espace comme \hfill entre elles, et vous obtenez une mise en page simple sur deux colonnes, idéale pour mettre une figure à côté de sa légende ou deux images côte à côte. En réglant les deux sur [t], les sommets de deux boîtes de hauteurs différentes s’alignent proprement (pour un placement plus avancé, voir « Flottants et placement »).

document.tex
\noindent
\begin{minipage}[t]{0.48\textwidth}
  Left column. This minipage wraps text within 48\%
  of the text width, and can hold several paragraphs,
  lists, and even its own footnote.\footnote{Local note.}
\end{minipage}\hfill
\begin{minipage}[t]{0.48\textwidth}
  Right column, top-aligned with the left one because
  both use the optional \verb|[t]| argument.
\end{minipage}

Chaque minipage occupe 48% de la largeur du texte, et le \hfill placé entre les deux absorbe le reste afin qu’elles couvrent toute la mesure. Comme les deux portent [t], leurs sommets s’alignent même si elles n’ont pas le même nombre de lignes. La \footnote de la boîte gauche apparaît sous la minipage avec une marque minuscule, et non en bas de la page.

Décaler et tracer : raisebox et rule

Pour décaler une boîte verticalement, utilisez \raisebox{lift}[height][depth]{text}. Un {lift} positif élève le contenu, un négatif l’abaisse. L’astuce se trouve dans les arguments optionnels [height] et [depth] : ils demandent à LaTeX de faire comme si la boîte avait cette hauteur et cette profondeur, de sorte que l’interligne environnant est calculé à partir des valeurs déclarées plutôt que de ce qui est réellement dessiné. Par exemple, \raisebox{0pt}[0pt][0pt]{a big symbol} dessine un grand contenu tout en déclarant une hauteur et une profondeur nulles ; on peut ainsi ajouter un ornement sans perturber l’interligne. Les longueurs spéciales \height, \depth et \totalheight fonctionnent ici aussi.

\rule[lift]{width}{height} dessine un rectangle plein, une boîte noire. {width} et {height} fixent ses dimensions, et l’argument optionnel [lift] le décale au-dessus de la ligne de base, ou au-dessous si la valeur est négative. C’est parfait pour les traits horizontaux : \rule{0.5\linewidth}{0.4pt} donne un filet fin de la moitié de la largeur de ligne.

L’autre visage de \rule est le strut. Une \rule{0pt}{height} de largeur nulle est une boîte invisible qui n’imprime rien mais réserve cette hauteur. Elle sert à imposer une hauteur minimale de ligne ou à donner de l’air aux cellules d’un tableau. Placez \rule{0pt}{2.6ex} au début d’une ligne, et cette ligne aura au moins 2.6 ex de hauteur. La commande standard \strut de LaTeX est exactement \rule[-0.3\baselineskip]{0pt}{\baselineskip} : un strut de largeur nulle couvrant toute l’avance de ligne courante au-dessus et au-dessous de la ligne de base. C’est la technique classique pour empêcher le texte de serrer les filets d’un tableau.

latex
% a centered horizontal rule
\noindent\hfil\rule{0.5\linewidth}{0.4pt}\hfil

% a strut forces a taller line / roomier table cell
\begin{tabular}{|l|}
  \hline
  \rule{0pt}{2.6ex}Tall, uncramped row \\
  \hline
\end{tabular}

% align two differently sized boxes on a common baseline
big \raisebox{-0.4ex}{\Huge A} small

Enregistrer et réutiliser des boîtes

Si vous réutilisez plusieurs fois le même contenu, vous pouvez le composer une seule fois, le stocker dans une boîte, puis simplement le rappeler. Déclarez d’abord une boîte de stockage, ou registre, avec \newsavebox{\boxname}. Remplissez-la ensuite avec \sbox{\boxname}{text} ou \savebox{\boxname}[width][position]{text} ; le contenu n’est réellement composé qu’à cet instant unique. Là où vous en avez besoin, \usebox{\boxname} émet la boîte enregistrée telle quelle. Pour un contenu coûteux comme un long tableau ou une figure complexe utilisée à plusieurs endroits, cela accélère le traitement et garantit un rendu strictement identique.

Une boîte de stockage est une boîte LR ; pour conserver un contenu sur plusieurs lignes, enveloppez-le donc d’abord dans une \parbox ou une minipage. Il existe aussi une forme en environnement, \begin{lrbox}{\boxname} … \end{lrbox}, mieux adaptée aux contenus qui incluent du verbatim. Notez que \sbox est robuste tandis que \savebox est fragile : soyez donc prudent avec cette dernière dans un « argument mobile », par exemple un titre de section.

Pour mesurer une boîte, utilisez \settowidth{\len}{text}, \settoheight{\len}{text} et \settodepth{\len}{text}. Ces commandes enregistrent la largeur, la hauteur ou la profondeur du contenu composé dans le registre de longueur indiqué. Elles sont utiles pour des ajustements précis, par exemple tracer un cadre ou un soulignement exactement à la taille d’une boîte.

document.tex
\newsavebox{\mylogo}
\sbox{\mylogo}{\fbox{\textbf{Draft}}}   % typeset once

% reuse the identical box as many times as you like
Header: \usebox{\mylogo} \dots\ Footer: \usebox{\mylogo}

% measure a box into a length, then rule under it
\newlength{\w}
\settowidth{\w}{Signature}
Signature\par\rule{\w}{0.4pt}

La ligne \sbox encadre « Draft » et le compose une seule fois ; les deux appels à \usebox réutilisent exactement cette boîte. Dans la moitié inférieure, \settowidth mesure la largeur de « Signature », puis \rule trace un soulignement exactement de cette largeur.

Les commandes de boîte en un coup d’œil

CommandeTypeRôle
\mboxBoîte LRGarde le contenu sur une seule ligne ; ni coupure ni césure
\makeboxBoîte LRFixe largeur et position ; [0pt] surimprime en largeur nulle
\frameboxBoîte LRUn \makebox encadré (\fbox est la forme sans largeur)
\parboxBoîte de paragrapheUn seul paragraphe replié dans une largeur fixe
minipageBoîte de paragrapheUne petite page pour paragraphes, listes et notes
\raiseboxTransformationDécale le contenu vers le haut ou le bas ; peut simuler hauteur et profondeur
\ruleBoîte pleineUn rectangle plein ; largeur nulle pour un strut
\useboxStockageÉmet une boîte enregistrée avec \newsavebox + \sbox