--- myst: html_meta: keywords: LaTeX,programming" --- # Comment modifier une commande existante ? La réponse dépend ici de la complexité de la modification (ou du *patch*) que vous souhaitez appliquer à cette commande. ## Pour les "cas simples" Par "cas simples" sont désignés ici les modifications visant à placer du code avant ou après l'intégralité du code de la commande à modifier. ### Avec les commandes de base Supposons que nous voulons définir une version d'une commande qui réalise une action avant que ne s'exécute sa version originale. Nous écrirons alors naturellement : ```{noedit} \renewcommand{\truc}{\machin\truc} ``` Cependant, cela ne fonctionnerait pas : un appel à `\truc` exécuterait `\machin`, puis appellerait à nouveau `\truc` avec sa nouvelle définition... qui appelerait `\machin` puis `\truc``et ainsi de suite. Il s'agit d'une *boucle récursive infinie* qui épuiserait rapidement la mémoire de TeX. Heureusement, la commande primitive TeX `\let` vient ici à notre secours ; elle nous permet de prendre un "instantané" de la définition actuelle d'une commande, que nous pouvons ensuite utiliser dans la redéfinition de la commande. Ainsi la commande suivante effectue le correctif requis, en toute sécurité. ```{noedit} \let\AncienTruc\truc \renewcommand{\truc}{\machin\AncienTruc} ``` L'ajout de commandes à la fin d'une commande fonctionne de la même manière. Si `\truc` prend des arguments, il faut les transmettre : ```{noedit} \let\AncienTruc\truc \renewcommand{\truc}[2]{\machin\AncienTruc{#1}{#2}}} ``` ### Avec l'extension Le problème vu ci-dessus se complique si `\truc` prend un argument optionnel. La structure de la commande est si complexe que la commande `\let` ne conserve pas les détails nécessaires. Dans ce cas, nous avons besoin de l'extension qui connaît toutes sortes de commandes LaTeX et sait comment les reproduire. Supposons que nous ayons une commande définie comme : ```{noedit} \newcommand{\truc}[1][\defaut]{...} ``` Elle présente un argument optionnel (remplacé par `\defaut` s'il n'est pas présent) ainsi qu'un argument simple. Dans ce cas, nous la copions en utilisant ```{noedit} \LetLtxMacro{\AncienTruc}{\truc} ``` Puis nous répétons la technique décrite ci-dessus : ```{noedit} \renewcommand{\truc}[1][\nouveau]% {\machin\AncienTruc[{#1}]{#2}} ``` Nous voyons ici que, pour des raisons fastidieuses de correspondance d'arguments, il est nécessaire de fournir des accolades autour de l'argument optionnel transmis. ### Avec l'extension L'extension peut traiter le cas simple mais limite l'ensemble des commandes que vous pouvez modifier ; vous ne pouvez modifier aucune commande qui a un argument optionnel, bien qu'il traite le cas des commandes définies avec `\DeclareRobustCommand`. L'extension définit une commande `\patchcommand` qui prend trois arguments : la commande à modifier, du code à placer au début de sa définition, et du code à placer à la fin de sa définition. En voici un exemple : ```{noedit} \def\b{b} \patchcmd\b{a}{c} ``` Cet exemple va nous créer une nouvelle version de `\b` définie commee `abc`. ## Pour les "cas complexes" Par "cas complexes" sont désignés ici les modifications visant à modifier le code même de la commande. ### Avec les commandes de base On peut ici utiliser la commande LaTeX `\CheckCommand`. Celle-ci compare une commande existante avec la définition que vous lui donnez, et émet un avertissement si les deux ne correspondent pas. Elle s'utilise pour notre besoin de la manière suivante : ```{noedit} \CheckCommand{\truc}{⟨défintion originale⟩} \renewcommand{\truc}{⟨nouvelle définition⟩} ``` Cette technique est évidemment plus laborieuse car elle vous fait citer tout le code original de la commande pour en vérifier qu'il est tel que vous l'attendez (puis donner l'intégralité de votre version alternative du code de la commande). Cependant, si la commande originale provient d'une source susceptible d'être modifiée par une autre personne, elle vous avertit au moins que votre correctif est susceptible de mal tourner. ### Avec l'extension L'extenion est un "éditeur de liste de tokens" fournissant une commande `\substitute` qui corrige le contenu d'une commande, en plaçant son résultat dans une liste de tokens, ou (avec la forme `\Substitute*`) en utilisant son résultat pour (re)définir une commande. L'exemple suivant définit une commande simple, puis modifie sa définition : ```{noedit} \newcommand{\mafonte}% {\Large\sffamily\selectfont} \Substitute*[\renewcommand{\mafonte}]{\mafonte}% {\Large\sffamily}{\huge\itshape} ``` La définition de la commande est maintenant : ```{noedit} \huge\itshape\selectfont ``` L'extension propose également une commande ``ShowTokens``, qui affiche le contenu de son argument, un token par ligne, avec des détails sur le [catcode](../syntaxe/catcodes/que_sont_les_catcodes.md) du token, etc. Cette commande est recommandée comme outil de débogage. ### Avec l'extension L'extension (qui fournit à l'utilisateur un accès aux facilités de programmation de [eTeX](../../1_generalites/glossaire/etex.md)) fournit une commande `\patchcmd` très similaire à `\Substitute`, sauf qu'elle ne remplace qu'une seule instance du ou des tokens dans son modèle de recherche. Comme toutes les commandes ne peuvent pas être corrigées de cette manière, `\patchcmd` prend des arguments supplémentaires pour les cas de *succès* et d'*échec*. L'extension fournit également des commandes qui ajoutent du code avant (`\pretocmd`) ou ajoutent après (``apptocmd``) une définition d'une commande. Toutes les commandes ne peuvent pas être modifiées de cette manière ; l'extension fournit une commande `\ifpatchable` qui vérifie les pré-requis et qui vérifie que le corps de la commande cible inclut bien le code supplémentaire que vous proposez d'utiliser (la commande `\ifpatchable*` omet le test sur la chaîne de correctifs). ### Avec l'extension L'extension traite des cas inaccessibles avec . Elle utilise l'extension gérant les expressions régulières de [LaTeX3](../../1_generalites/histoire/c_est_quoi_latex3.md) pour trouver le code que vous souhaitez corriger. Cette extension connaît également la notion de commandes robustes et . ### Avec l'extension Enfin, citons également une extension (à peu près) utilisable mais pas vraiment recommandable : . Celle-ci vous offre un mécanisme ingénieux (et difficile à comprendre) et se présente sous la forme d'un fichier de commandes LaTeX documenté à l'ancienne, qui ne peut plus être traité pour [produire de la documentation formatée](../../1_generalites/documentation/documents/documents_extensions/documentation_des_packages3.md) Heureusement, ce fichier (`patch.doc`) contient le code et sa documentation. En gros, on donne à la commande un ensemble d'instructions analogues aux substitutions `sed`, et elle régénère la commande ainsi modifiée. À moins que vous ne puissiez faire votre travail autrement, est à éviter. :::{sources} [Patching existing commands](faquk:FAQ-patch) :::