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.
Avant toute autre démarche, il faut vérifier si le mode verbatim est réellement nécessaire :
\texttt{⟨votre texte⟩}
produit le même résultat que \verb+⟨votre texte⟩+
, alors vous pouvez vous passer de \verb
;\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 ;\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}}
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}}
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.
Une autre solution consiste à utiliser l'un des « types d'arguments » de la commande \NewDocumentCommand
de l'extension expérimentale LaTeX3 xparse :
\NewDocumentCommand\cmd{ m v m }{#1 #2 #3} \cmd{La commande }|\bidouille|{ n'est pas définie.}
Cette méthode permet d'avoir pour une même commande :
m
(pour mandatory) ;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 LaTeX3 (l3kernel), un ensemble assez vaste et complexe.
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.
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.
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.
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.
L'extension newverbs fournit une fonction similaire à celle de \verbdef
ainsi que plusieurs autres fonctions connexes.
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.
L'extension tcolorbox fournit une fonctionnalité similaire.
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.
L'extension moreverb fournit une commande \verbatimwrite
, qui ne fournit pas de fichier anonyme.
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.