Imprimer une simple barre oblique inverse en LaTeX est plus difficile qu’imprimer un signe intégrale, et ce n’est pas une plaisanterie. Le verbatim — \verb pour un fragment, l’environnement verbatim pour un bloc — est le seul recoin du système qui ne fonctionne qu’en coupant un instant la grammaire de LaTeX elle-même. Toutes les règles qui semblent arbitraires en découlent : pourquoi \verb ne franchit pas un retour à la ligne, pourquoi \end {verbatim} avec une espace à l’intérieur bloque la compilation, et pourquoi \verb placé dans \section{...} ou \footnote{...} échoue sur une erreur qui ne mentionne jamais le verbatim. Cette page couvre l’environnement verbatim et \verb, les formes étoilées qui rendent les espaces visibles, la lecture de fichiers entiers avec \verbatiminput et \VerbatimInput, la variante alltt qui laisse quelques commandes actives, les blocs encadrés et numérotés avec fancyvrb, et la façon de taper une barre oblique inverse ou un tiret bas dans le texte courant.
Ce que l’environnement verbatim désactive réellement
Tout ce qui se trouve entre \begin{verbatim} et \end{verbatim} s’imprime exactement tel que tapé — retours à la ligne et espaces compris — en police à chasse fixe, sans aucun package. Le mécanisme n’est pas un échappement mais une rétrogradation. À l’entrée dans l’environnement, LaTeX réécrit d’un coup le code de catégorie de \, {, }, $, &, #, ^, _, % et ~ en « caractère ordinaire ». Un code de catégorie est l’étiquette de rôle que TeX attache à chaque caractère au moment de la lecture ; elle décide si ce caractère amorce une commande, ouvre un groupe ou n’est que de l’encre. Une barre oblique inverse en verbatim n’amorce donc pas de commande, non parce que les commandes seraient ignorées, mais parce que à cet instant elle n’est plus qu’un signe ayant la forme d’une barre oblique inverse.
\begin{verbatim}
for i in range(3):
print("100% & $5 \n") # none of this is interpreted
\end{verbatim}La mise en œuvre est également pénible pour l’auteur, et cette gêne est conservée dans le source de LaTeX lui-même. Dans latex.ltx, le fichier qui définit LaTeX, la macro qui cherche la fin d’un bloc verbatim est définie avec | comme caractère d’échappement et [ et ] comme accolades. À l’intérieur de cette définition, les trois caractères \, { et } doivent tous être de simples caractères imprimables : le langage ne peut donc pas s’y écrire dans sa notation habituelle. Le temps de cette définition, le source de LaTeX cesse d’être écrit en LaTeX. Les deux lignes se lisent telles quelles dans le latex.ltx livré avec TeX Live 2024.
Deux règles pratiques découlent de cette manière de détecter la fin. D’abord, la chaîne \end{verbatim} ne doit pas apparaître dans l’environnement : LaTeX y voit aussitôt la fin. Ensuite, aucune espace ne doit séparer \end de {verbatim}. Le terminateur est comparé caractère par caractère comme délimiteur d’argument de macro ; \end {verbatim} n’est donc pas reconnu du tout, et TeX poursuit jusqu’à la fin du fichier avant de s’arrêter sur Runaway argument? puis ! File ended while scanning use of \@xverbatim. Un outil de mise en forme du source qui normalise les espaces provoque exactement cette panne. Lorsque le nombre d’espaces compte, l’environnement étoilé verbatim* imprime chacun d’eux sous la forme ␣.
Choisir le délimiteur de \verb, et pourquoi il ne franchit pas une ligne
Pour insérer un court fragment littéral au milieu d’une ligne, on utilise \verb. Un caractère délimiteur suit immédiatement \verb, puis vient le texte à imprimer tel quel, puis le même caractère à nouveau — par exemple \verb|\textbf{x}|. Le délimiteur peut être presque n’importe quel caractère absent du contenu ; si | y figure, on passe à \verb!...!, \verb+...+ ou \verb/.../. Deux caractères sont exclus. Une lettre ne convient pas, car \verbx se lit pour TeX comme un tout autre nom de commande. Et * n’est pas disponible, puisque \verb* est réservé à la forme étoilée qui imprime les espaces sous la forme ␣.
The macro \verb|\textbf{...}| sets bold text;
a pipe in the content needs another delimiter, as in \verb!a|b!.
Count the gaps: \verb*|a b| prints the spaces as visible marks.Une autre limite dure pèse sur \verb : le délimiteur fermant doit se trouver sur la même ligne. Si la fin de ligne arrive d’abord, la compilation s’arrête sur ! LaTeX Error: \verb ended by end of line. La cause réelle est le plus souvent un délimiteur fermant oublié, mais un cas étonnamment fréquent est un éditeur qui a recoupé ou reformaté une longue ligne et coupé l’argument en deux. Dès que le contenu s’allonge, mieux vaut le sortir de \verb et le mettre dans un environnement de bloc. Et s’il ne s’agit que d’une chaîne contenant souvent ~, #, % ou _ — une URL, typiquement —, \url{...} du package url ou hyperref convient mieux : littéral, et capable de couper la ligne à des endroits raisonnables.
Taper une barre oblique inverse ou un tiret bas dans le texte courant
Pour un ou deux caractères, le verbatim est superflu. Une barre oblique inverse s’obtient par \textbackslash et un tiret bas par \_. L’accident le plus fréquent ici : \\ n’est pas une barre oblique inverse mais la commande de retour à la ligne — taper \\ n’imprime rien et coupe la ligne. $\backslash$ en mode mathématique donne bien la forme, mais dans la fonte mathématique ; dans le texte courant, la bonne réponse est \textbackslash. Un tiret bas nu produit ! Missing $ inserted. — pour TeX, _ annonce un indice — et l’échapper en file\_name règle la question.
| Saisie | Sortie | Remarque |
|---|---|---|
\textbackslash | \ | \\ est la commande de retour à la ligne, pas une barre |
\_ | _ | Un _ nu provoque ! Missing $ inserted. |
\% \& \# \$ | % & # $ | Il suffit d’un \ devant chacun |
\{ \} | { } | Imprime les caractères de groupe comme caractères |
\textasciitilde | ~ | Un ~ nu est une espace insécable, pas un tilde |
\textasciicircum | ^ | Un ^ nu annonce un exposant |
Pourquoi \verb échoue dans \section, \footnote et \caption
Ni \verb ni l’environnement verbatim ne peuvent figurer dans l’argument d’une autre commande. La raison n’est pas une interdiction mais une simple chronologie. \verb bascule les codes de catégorie juste avant de lire son propre texte. Or le contenu de \section{...} a déjà été converti en liste de tokens sous les codes de catégorie normaux au moment où \section a été appelée. Quand vient le tour de \verb, \foo a cessé d’être quatre caractères à imprimer pour devenir la commande \foo. Le verbatim ne peut pas relire ce qui a déjà été lu : toute l’affaire tient là.
Le désagrément, c’est que cet échec se manifeste par des erreurs qui ne prononcent jamais le mot verbatim. \section{The \verb|\foo| command} s’arrête sur ! Undefined control sequence. — parce que \foo a bel et bien été lu comme une commande, et qu’elle n’existe pas. Si le contenu ne comporte aucun caractère spécial, comme dans \mbox{\verb|abc|}, on obtient le message étonnamment utile ! LaTeX Error: \verb illegal in argument. Les environnements de bloc se lisent encore moins bien : \footnote{\begin{verbatim} ... \end{verbatim}} donne Runaway argument? puis ! Paragraph ended before \@xverbatim was complete. ; dans \parbox{5cm}{...}, cela devient ! Argument of \@xverbatim has an extra }. ; dans \caption{...}, ! Argument of \@caption has an extra }. Ce sont autant de visages d’une seule et même cause.
Une cellule de tableau, en revanche, n’est pas un argument. Les cellules de tabular sont lues pendant que TeX guette les séparateurs de colonne et de ligne : \verb y fonctionne tel quel, y compris dans une colonne p{4cm}. Dans ce même tableau, en revanche, le troisième argument de \multicolumn{2}{c}{...} est bel et bien un argument, et là cela échoue. La règle à retenir n’est donc pas « pas dans les tableaux » mais « pas dans un argument délimité par des accolades ».
Trois contournements existent. Le premier est le package cprotect (Bruno Le Floch, v1.0e), dont l’unique objet est le verbatim dans les arguments de macro : il suffit de préfixer la commande fautive par \cprotect, et \cprotect\section{The \verb|\foo| command} compile. Il fournit aussi \cprotEnv pour protéger le \begin d’un environnement. Le deuxième est \SaveVerb / \UseVerb de fancyvrb : enregistrer d’abord le texte verbatim sous un nom, puis n’appeler que ce nom dans l’argument. Le troisième ne vaut que pour les notes de bas de page : en déclarant \VerbatimFootnotes de fancyvrb dans le préambule, le verbatim fonctionne dans \footnote. À noter que remplacer \verb par le \Verb de fancyvrb n’aide pas : le problème de chronologie est identique. Et en dernier recours, écrire \texttt{\textbackslash foo} à la main reste le chemin le plus court pour un seul titre.
% Fails: \foo was already a command token before \verb could act
% \section{The \verb|\foo| command} -> Undefined control sequence
% Workaround 1 -- cprotect
\usepackage{cprotect}
\cprotect\section{The \verb|\foo| command}
% Workaround 2 -- save it first, use it later
\usepackage{fancyvrb}
\SaveVerb{cmd}|\foo|
\section{The \UseVerb{cmd} command}
% Workaround 3 -- verbatim inside footnotes
\VerbatimFootnotesLire un fichier entier : \verbatiminput et \VerbatimInput
Avec \usepackage{verbatim} dans le préambule et \verbatiminput{hello.py} dans le corps, chaque ligne du fichier externe est composée verbatim. Contrairement à une copie dans le manuscrit, modifier le fichier source met le PDF à jour automatiquement : code et document ne divergent pas. Si le code présenté doit réellement fonctionner, c’est la méthode la plus sûre.
Une question mérite d’être posée : pourquoi un package nommé verbatim coexiste-t-il avec l’environnement standard verbatim ? La réponse n’est pas \verbatiminput. La documentation de ce package de Rainer Schöpf, membre du bundle Tools de LaTeX, énonce le motif sans détour : l’environnement intégré ne peut sortir la moindre ligne avant d’avoir lu tout ce qui précède \end{verbatim} comme un unique argument de macro ; un long listing risque donc de saturer la mémoire de TeX. Le package remplace l’implémentation par une lecture et une composition ligne par ligne — un procédé que sa documentation attribue à la macro \comment d’AMS-TeX. Dès lors que le verbatim se lit ligne à ligne, \verbatiminput en découle presque gratuitement. Un effet de bord reste visible : le texte tapé sur la même ligne après \end{verbatim} est imprimé par l’environnement intégré mais discrètement supprimé par la version du package. L’écart est délibéré et documenté.
\usepackage{verbatim}
% ...
\verbatiminput{hello.py}
\begin{comment}
This paragraph is skipped entirely -- not printed, not typeset.
\end{comment}Le même package ajoute un environnement comment qui saute tout ce qui se trouve entre \begin{comment} et \end{comment} — non pas une sortie littérale, mais aucune sortie, pratique pour mettre un brouillon de côté. Pour un contrôle plus fin de l’inclusion de fichiers, on emploie \VerbatimInput[options]{filename} de fancyvrb, objet de la section suivante. Contrairement à \verbatiminput, il accepte cadres et numéros de ligne et, avec firstline=10, lastline=25, il n’importe qu’une partie du fichier — exactement ce qu’il faut quand une longue source ne comporte qu’un passage pertinent.
alltt : un verbatim qui exécute encore quelques commandes
Pour mettre en gras ou en couleur seulement une partie d’un exemple de code, le verbatim ordinaire ne laisse aucune prise : toutes les commandes sont désactivées. L’environnement alltt, fourni par le package alltt de la distribution LaTeX standard, offre la sortie. alltt compose le texte en chasse fixe et tel que tapé, presque comme verbatim, à ceci près que trois caractères gardent leur sens habituel : la barre oblique inverse \ et les accolades { et }. L’aspect reste celui du verbatim, mais des commandes LaTeX s’exécutent à l’intérieur.
\usepackage{alltt}
% ...
\begin{alltt}
def \textbf{greet}(name):
return "Hi, " + name \textit{# a comment}
\end{alltt}Dans cet exemple, le nom de fonction greet ressort en gras et le commentaire en italique, tandis que le reste demeure exactement tel que tapé. Le prix est net : pour imprimer les trois caractères \, {, } en tant que caractères, il faut désormais écrire \textbackslash, \{, \}, là où verbatim les imprime directement. alltt est donc un marché : trois caractères de littéralité cédés contre le droit de mettre le reste en forme. Pour une emphase légère posée à la main, alltt ; pour un texte dont pas un caractère ne doit bouger, verbatim.
Numéros de ligne et cadres : l’environnement Verbatim de fancyvrb
Ni numéros de ligne ni cadres ne sont disponibles dans le verbatim intégré. Cette tâche revient au package fancyvrb, dont le cœur est l’environnement Verbatim à V majuscule — à ne pas confondre avec verbatim en minuscules. Les options se passent par environnement, comme \begin{Verbatim}[numbers=left, frame=single], ou deviennent des valeurs par défaut pour tout le document via \fvset{numbers=left, ...} dans le préambule. fancyvrb a été entamé en 1992 par Timothy Van Zandt, auteur également de PSTricks, et est maintenu depuis 2000 par Herbert Voß (la version livrée avec TeX Live 2024 porte le numéro 4.5c). Trois décennies d’options pratiques accumulées expliquent qu’il ait une réponse à presque tout.
| Option | Valeurs typiques | Rôle |
|---|---|---|
numbers | none / left / right | Emplacement des numéros, défaut none ; numbersep règle l’écart |
frame | none / single / lines / leftline / topline / bottomline | Type de cadre, défaut none ; framerule pour l’épaisseur, framesep pour la marge |
fontsize | \small, \footnotesize, etc. | Taille de police ; défaut : celle du corps |
showspaces | true / false | Rend les espaces visibles ; showtabs pour les tabulations, tabsize pour la largeur |
firstline / lastline | entiers | Avec \VerbatimInput, n’inclut qu’une portion du fichier |
commandchars | p. ex. \\\{\} | Désigne le caractère d’échappement et les deux caractères de groupe, réactivant les commandes |
\usepackage{fancyvrb}
\fvset{fontsize=\small} % document-wide default
% ...
\begin{Verbatim}[numbers=left, frame=single]
def greet(name):
return "Hello, " + name
\end{Verbatim}
% only lines 10-25 of an external file, framed
\VerbatimInput[firstline=10, lastline=25, frame=lines]{server.py}Avec commandchars=\\\{\}, les caractères \, {, } redeviennent, à l’intérieur du texte verbatim, le caractère d’échappement et les délimiteurs de groupe : on y insère alors des commandes comme dans alltt. Plutôt que de répéter le même jeu d’options, l’usage est de définir son propre environnement : \DefineVerbatimEnvironment{Code}{Verbatim}{numbers=left, frame=single}, après quoi \begin{Code} suffit. Tout ce qui précède sert toutefois à imprimer le texte tel quel ; rien n’y colore les mots-clés, autrement dit rien n’y fait de coloration syntaxique. Pour du code source coloré et mis en forme, ce sont listings, qui colorie avec les seules macros de TeX, et minted, qui délègue le travail à Pygments en Python — la page connexe « Listes de code » les compare.