Pourquoi le mode verbatim ne marche pas toujours ?#

Les commandes de verbatim de fonctionnent en modifiant les codes de catégorie. Donald Knuth dit à propos de ce genre de manipulation qu’« il faut faire attention que le timing soit correct », car une fois que le code de catégorie a été attribué à un caractère, il ne change pas. Ainsi les commandes \verb et \begin{verbatim} doivent obtenir en premier la main sur le texte qu’elles ont en argument. Sinon, aura déjà attribué des codes de catégorie et la commande verbatim n’aura aucune chance de bien fonctionner. Dans l’exemple qui suit, tout se passe bien avec l’affichage du texte « \error » :

\verb+\error+

Maintenant, supposons que vous définissez une commande qui ne fait de restituer son argument (ici \simple) puis que vous l’utilisez avec l’exemple ci-dessus :

\newcommand{\simple}[1]{#1}
\simple{\verb+\error+}

Alors la combinaison ne marche plus : elle tente d’exécuter \error… D’autres erreurs peuvent aussi apparaître : « \verb ended by end of line » (\verb achevé par la fin de la ligne) ou le plus utile « \verb illegal in command argument » (verb illicite dans l’argument de la commande). L’environnement verbatim peut déclencher les mêmes anomalies. En voici un exemple :

\ifthenelse{\boolean{truc}}{%
\begin{verbatim}
truc
\end{verbatim}
}{%
\begin{verbatim}
machin
\end{verbatim}
}

Ce code provoque des erreurs comme « File ended while scanning use of \@xverbatim » (l’analyse de \@xverbatim s’est interrompue à la fin du fichier) car la commande \begin{verbatim} n’arrive pas à trouver la commande complémentaire \end{verbatim}.

C’est pourquoi les ouvrages sur insistent sur le fait que les commandes de verbatim ne doivent apparaître dans l’argument d’aucune autre commande. Ils ne sont pas seulement fragiles : ils sont tout à fait inutilisables dans n’importe quel argument de commande, indépendamment de la protection. D’ailleurs, il faut ici noter que la commande \verb s’efforce de détecter si vous l’utilisez mal. Malheureusement, elle ne peut pas toujours le faire et le message d’erreur qu’elle peut générer n’est donc pas toujours fiable.

1.  Les cas ne nécessitant pas de verbatim#

Avant toute autre démarche, il faut vérifier si le mode verbatim est réellement nécessaire :

  • si la commande \texttt{⟨votre texte⟩} produit le même résultat que \verb+⟨votre texte⟩+, alors vous pouvez vous passer de \verb ;

  • si vous utilisez \verb pour composer une URL ou une adresse e-mail, alors la commande \url de l’extension url vous aidera : elle pose moins de difficultés que \verb bien qu’elle ne ne soit toujours pas robuste. La question « Comment gérer des adresses web (ou URL) ?  » détaille cette solution ;

  • si seul un caractère pose problème (en son absence, vous auriez utilisé \texttt), pensez à utiliser la commande \string. Ainsi, la commande \texttt{mon\string_nom} compose un texte identique à celui de \verb+mon_nom+ et fonctionne dans l’argument d’une commande. Cependant, cela ne fonctionnera pas dans un argument mobile et l’utilisation de la protection n’y changera rien. Une alternative robuste est alors de passer par la commande \chardef. Une telle définition est « naturellement » robuste. La construction `\⟨caractère⟩ peut être utilisée pour tout caractère gênant (bien que ce ne soit pas nécessaire pour des caractères comme les pourcents pour lesquels fournit déjà des commandes robustes). En voici un exemple :

\chardef\us=`\_
...
\section{... \texttt{mon\us nom}}

2.  Le mode verbatim dans une boîte#

Si vous mettez \verb dans l’argument d’une commande de boîte (comme \fbox), pensez à utiliser l’environnement lrbox :

\newsavebox{\mybox}
...
\begin{lrbox}{\mybox}
  \verb!Texte du mode verbatim!
\end{lrbox}
\fbox{\usebox{\mybox}}

3.  L’extension « cprotect »#

Si vous ne pouvez éviter le mode verbatim, la commande \cprotect tirée de l’extension cprotect pourrait vous aider. En effet, en préfixant votre commande de \cprotect, son argument en mode verbatim sera lu de manière « assainie » :

\cprotect\section{Utilisation de \verb|verbatim|}

L’extension fonctionne dans ce cas simple et mérite d’être testée dans de nombreux autres cas. La documentation de l’extension donne plus de détails.

4.  L’extension « xparse »#

Une autre solution consiste à utiliser l’un des « types d’arguments » de la commande \NewDocumentCommand de l’extension expérimentale xparse :

La commande \verb+\bidouille+ n'est pas définie.

Cette méthode permet d’avoir pour une même commande :

  • des arguments obligatoires normaux, désignés par l’argument m (pour mandatory) ;

  • des arguments en mode verbatim, désignés par l’argument v.

Le caractère | peut être n’importe quel caractère qui n’entre pas en conflit avec le contenu de l’argument.

Cette méthode est plutôt intéressante (même si le verbatim est dans un argument qui lui est propre) mais elle présente l’inconvénient d’accéder à l’environnement de programmation expérimental (l3kernel), un ensemble assez vaste et complexe.

5.  Du verbatim dans une note en bas de page#

5.1.  Avec l’extension « fancyvrb »#

Certaines extensions proposent des commandes conçues pour permettre du mode verbatim dans leurs arguments. Ainsi, l’extension fancyvrb définit une commande \VerbatimFootnotes (qui redéfinit la commande \footnotetext et donc le comportement de la commande \footnote) de manière à pouvoir inclure les commandes \verb dans son argument. Cette approche pourrait en principe être étendue aux arguments d’autres commandes, mais elle peut entrer en conflit avec d’autres extensions : par exemple, \VerbatimFootnotes interagit mal avec l’option para de l’extension footmisc.

5.2.  Avec la classe « memoir »#

La classe memoir définit sa propre commande \footnote afin qu’elle accepte des éléments en verbatim dans ses arguments, sans utiliser d’extension.

6.  Du verbatim sauvegardé#

6.1.  Avec l’extension « fancyvrb »#

L’extension fancyvrb définit une commande \SaveVerb et une commande \UseVerb, qui vous permet d’enregistrer puis de réutiliser le contenu de l’argument de \SaveVerb. Pour plus de détails sur cette fonction extrêmement puissante, consultez la documentation de l’extension.

6.2.  Avec l’extension « verbdef »#

L’extension verbdef est plus simple avec sa commande \verbdef qui définit une commande (robuste) qui se développe en son argument en mode verbatim.

6.3.  Avec l’extension « newverbs »#

L’extension newverbs fournit une fonction similaire à celle de \verbdef ainsi que plusieurs autres fonctions connexes.

6.4.  Avec l’extension « verbatimbox »#

Dans la même veine, l’extension verbatimbox permet de mettre du matériel en mode verbatim dans une boîte :

    \begin{verbbox}
    some exotic _&$ stuff
    \end{verbbox}
    \theverbbox

Cette opération met en forme des élements dans une boîte dont le contenu peut être récupéré en utilisant la commande \theverbbox. Cette opération rappelle fortement la commande \verbdef mentionnée ci-dessus. L’extension définit d’autres commandes similaires.

6.5.  Avec l’extension « tcolorbox »#

L’extension tcolorbox fournit une fonctionnalité similaire.

7.  Du verbatim sauvegardé dans un fichier#

7.1.  Avec l’extension « tcolorbox »#

Une autre solution consiste enfin à mettre des éléments en mode verbatim dans un fichier externe. Elle peut être un peu plus fastidieuse mais le fichier peut être réutilisé plusieurs fois dans un même document. L’extension tcolorbox permet d’écrire dans le fichier nommé :

\begin{tcbverbatimwrite}{⟨nom du fichier⟩}
...
\end{tcbverbatimwrite}

Charger le contenu enregistré s’obtient en utilisant \input{⟨nom de fichier⟩}.

Un deuxième environnement place vos éléments en mode verbatim dans un fichier temporaire (apparemment) anonyme :

\begin{tcbwritetemp}{⟨nom du fichier⟩}
...
\end{tcbverbatimwrite}

Dans ce cas, vous utilisez le fichier anonyme avec la macro \tcbusetemp. Vous pouvez d’ailleurs changer le nom utilisé pour le fichier anonyme, si sa valeur par défaut s’avère gênante.

7.2.  Avec l’extension « moreverb »#

L’extension moreverb fournit une commande \verbatimwrite, qui ne fournit pas de fichier anonyme.

7.3.  Avec l’extension « verbatim »#

Des commandes, pour obtenir le même effet, sont décrites dans la documentation de l’extension verbatim. Les commandes utilisent les fonctionnalités de l’exntesion, mais l’utilisateur doit écrire sa propre extension pour les utiliser.