--- myst: html_meta: keywords: LaTeX, programmation, argument, clé-valeur --- # Comment définir des arguments de forme "clé-valeur" ? Lorsque nous avons abordé la question "[](definir_une_macro_a_plus_de_9_arguments.md)", nous avons suggéré qu'un grand nombre d'arguments, distingués uniquement par leur position, n'était pas très agréable pour l'utilisateur et qu'une extension telle que offrait une interface utilisateur plus pratique permettant de faire des commandes comme celle-ci : ```{noedit} \instancefleur{espece=Primula veris, famille=Primulaceae, localisation=Coldham's Common, typeemplacement=Paturage, date=24/04/1995, nombre=50, typesol=alkaline } ``` Nous examinons ici les extensions utilisables pour créer une telle interface utilisateur. ## Avec l'extension L'extension la plus simple (pour LaTeX, du moins) pour obtenir des arguments "clé-valeur" reste . Elle dispose : - d'une commande `\define@key` pour déclarer une clé et sa définition ; - d'une macro `\setkeys` pour donner des valeurs aux paramètres d'une ou plusieurs clés. Ainsi : ``` \documentclass{article} \usepackage{lmodern} % Caractères plus lisibles \pagestyle{empty} % N'affiche pas de numéro de page \usepackage{keyval} \makeatletter \define@key{idee}{soitx}{soit $x$ = #1 } \define@key{idee}{soity}[0]{soit $y$ = #1 } \makeatother \begin{document} Voici nos conclusions : \setkeys{idee}{soitx=3,soity}. Elles diffèrent de : \setkeys{idee}{soity = 1, soitx=2} Et plus encore de : \setkeys{idee}{soitx=1}. \end{document} ``` Ici, deux clés, `soitx` et `soity`, ont été définies pour la famille `idee`, et ont ensuite été exécutées avec la commande `\setkeys` : - au premier appel, on peut observer l'effet de l'argument par défaut de `soity` ; - au deuxième appel, on peut noter que l'ordre d'appel des clés est important ; - au dernier appel, on peut noter que seules les clés appelées sont exécutées. En fait, les deux appels à `define@key` sont simplement des commandes de définition (quoique cette définition soit un peu plus élaborée pour `\KV@idee@soity`) : ```{noedit} \newcommand{\KV@idee@soitx}[1]{soit $x$ = #1} ``` La commande `\setkeys` sait comment trouver ces commandes quand elle doit traiter chaque clé. Pour cela, elle reconstitue le nom de la commande : - il commence toujours par `KV@` avec  ; - il se poursuit avec le nom de la famille (`idee`, ici) suivi d'un autre `@` ; - et il s'achève avec le nom de la clé souhaitée. Ces commandes simples sont suffisantes, en fait, pour traiter l'exemple botanique proposé en début de cet article, ceci en remplacement des commandes à arguments multiples vues à la question "[](definir_une_macro_a_plus_de_9_arguments.md)". De même, ces commandes suffisent à gérer les arguments optionnels de la commande `\includegraphics` de l'extension (de fait, a été conçu pour cet usage). Cependant, l'extension s'avère trop limitée si nous voulons créer des options de extensions sous la forme de "clé-valeur". Des extensions comme présentent des options d'extension extrêmement compliquées et nécessitent un traitement de ces clés lorsque la commande`\ProcessOptions` s'active : ne peut pas faire cela tout seul. ### Pour aller un peu plus loin avec L'extension , de Heiko Oberdiek, nous vient ici en aide : elle permet au programmeur de déclarer des options de classe ou d'extension qui fonctionnent comme des paires clé/valeur. L'extension définit les commandes : - `\DeclareBoolOption` pour les options dont la valeur doit être soit `true` (vrai) soit `false` (faux) ; - `\DeclareStringOption` pour toutes les autres options qui ont une valeur. Les clés sont déclarées à l'aide de et peuvent rester disponibles pour être utilisées dans le document, ou peuvent être "annulées" pour éviter toute confusion. Si vous avez chargé , l'option `\DeclareOption` de LaTeX devient `\DeclareVoidOption` (c'est une option sans valeur), et `\DeclareOption*` devient \DeclareDefaultOption`. Heiko fournit également l'extension  : elle propose une version plus robuste et plus pratique de la commande `\setkeys`. ## Avec l'extension L'extension , de Hendri Adriaens, offre plus de flexibilité et de robustesse que . Comme , l'extension propose aussi des mécanismes pour permettre des options de classe et d'extension sous forme "clé-valeur" (avec les commandes `\DeclareOptionX`, `\ExecuteOptionsX` et `\ProcessOptionsX`). Les extensions de la famille utilisent un dérivé de appelé pour leur propre système "clé-valeur". ## Avec l'extension L'extension graphique (ou pgf) possède sa propre extension dédiée au système "clé-valeur", appelée . La [documentation](texdoc:tikz) de cette extension (incluse dans l'énorme manuel de , en partie VII) contient une comparaison utile avec d'autres systèmes clé-valeur, ce qui permet entre autres de noter quelques différences notables : - les clés sont organisées en une structure arborescente, alors que et associent tous deux les clés à une famille ; - prend en charge les codes de clé à plusieurs arguments ; - et peut prendre en charge les fonctions de rappel (*call-backs*) lorsqu'une clé inconnue apparaît (ces éléments sont appelés des gestionnaires ou *handlers*). Les clés sont organisées dans un arbre qui rappelle l'arbre des fichiers d'Unix. Une clé typique peut être `/tikz/coordinate system/x` ou simplement `/x`. Lorsque vous spécifiez des clés, vous pouvez fournir le chemin complet de la clé, mais, en général, vous ne fournissez que le nom de la clé et le "chemin" est ajouté automatiquement. Ainsi, une commande ``pgfkeys`` pourrait être : :::{todo} Faire un exemple compilable. ::: ```{noedit} \pgfkeys{/ma cle=salut,/votre cle/cle principale=une valeur, cle sans chemin= autre valeur} ``` Pour chaque clé mentionnée, le code associé sera exécuté, ce dernier étant également configuré à l'aide de `\pgfkeys` : ```{noedit} \pgfkeys{/ma clé/.code=La valeur est "#1".} ``` Après quoi ```{noedit} \pgfkeys{/ma cle=coucou !} ``` va juste produire ```text La valeur est "coucou !". ``` Le manuel continue en montrant comment définir une clé avec deux arguments, comment fournir une valeur par défaut pour une clé et comment définir des alias pour des séquences de clés particulières (appelées "styles"). Dans l'ensemble, il s'agit d'un système bien pensé, offrant une grande flexibilité qui n'est pas disponible avec les autres extensions traitant des paires "clé-valeur". Cependant, il ne semble pas y avoir de mécanisme permettant d'utiliser les clés dans les options d'une autre extension, comme le fait . ## Avec l'extension [l3keys](ctanpkg:l3kernel) L'ensemble pour [LaTeX3](faquk:FAQ-LaTeX3) inclut l'extension [l3keys](ctanpkg:l3kernel). Inspiré par , il fournit au programmeur une méthode pour créer des clés. Comme pour et ses dérivés, [l3keys](ctanpkg:l3kernel) utilise des commandes distinctes pour définir et paramétrer les clés. L'extension permet de traiter les options des classes et des extensions LaTeX2e à l'aide de [l3keys](ctanpkg:l3kernel). Le code [L3kernel](ctanpkg:l3kernel) peut être utilisé dans des documents LaTeX2e existants, de sorte que [l3keys](ctanpkg:l3kernel) est "directement" disponible pour le programmeur LaTeX2e. ## Avec l'extension Une autre extension de système "clé-valeur" appartenant à un ensemble plus large est  : elle utilise les fonctionnalités de pour construire une large gamme de commandes, à l'origine pour une utilisation dans l'ensemble [KOMA-script](ctanpkg:koma-script). L'extension s'appuie sur les commandes de ou de et possède une structure de la "famille de clés". L'utilisateur peut définir les "membres" d'une famille et les clés sont définies par rapport aux membres. Par exemple, l'extension fait partie de l'ensemble [KOMA-script](ctanpkg:koma-script). Ses clés sont donc toutes membres de la famille [scrbase](ctanpkg:scrbase) au sein de la famille [KOMA](ctanpkg:koma-script). La commande `\FamilyProcessOptions` permet au programmeur de traiter les options d'extension en fonction de famille de clés de l'extension. Notez qu'il n'y a pas de traitement dédié pour les options d'extension traditionnelles, comme dans le paquetage . :::{todo} Revoir ce point, avec un éventuel exemple (car la source décrit une situation ancienne). ::: ## Avec l'extension Toutes les extensions citées auparavant sont destinées à un usage avec LaTeX. Il existe également une extension pensée pour [Plain TeX](../../1_generalites/glossaire/plain_tex.md), . Elle utilise une syntaxe inspirée de celle de primitives TeX telles que `\hrule` et `\hbox` et nous permet l'exemple suivant, extrait du [manuel](texdoc:getoptk) de l'extension : ```{noedit} \begindisplay file {chapter1} literal offset 20pt ``` :::{sources} [Key-value input for macros and package options](faquk:FAQ-keyval) :::