Commandes à arguments illimités

, par Maïeul

J’ai eu récemment besoin de créer une commande dont le nombre d’arguments serait illimité. Il s’agissait de permettre d’indiquer une série de référence biblique associée à un passage. Voici comment, sur conseil du TeXnicien de surface.

Problème

Le texte que j’étudie fait allusion par moment à des passages bibliques. Je souhaite ajouter une note de bas de page indiquant :

Cf. Passage 1 ; Passage 2 ; Passage n. etc

Évidemment, je pourrais le faire à la main, mais utiliser une commande spécifique permet d’uniformiser les styles. C’est pourquoi j’ai voulu créer une commande :

\bibeall{passage1}{passage2}{passagen}

J’avais affaire à deux problèmes :

  • Techniquement une commande LaTeX ne peut prendre que 9 arguments au maximum.
  • Pour chaque passage, je devais indiquer le livre séparément du chapitre, afin de pouvoir utiliser les possibilités de bibleref-french. En outre, je souhaitais pouvoir préciser la version entre parenthèse (LXX, Vulgate, BHS etc.). Ce qui faisait que j’étais réduit à au mieux 3 passages.

Solution : principe

La solution consiste alors à proposer une commande à un seul argument, mais qui pourrait se décomposer sous forme de liste. J’ai choisi d’utiliser le + comme séparateur d’élément de liste, car la , a un sens spécifique lorsque l’on utilise bibleref-french [1]

Pour séparer le livre du passage et le passage de la version, j’ai décidé d’utiliser le symbole | (pipe).

Ainsi, si je souhaite faire référence à Isaïe, livre 1 chapitre 1, dans la version LXX et BHS, je met :

\bibleall{Is|1:1|BHS+Is|1:1|LXX}

Et j’obtiens en note de note de bas de page :

Cf. Is 1,1 (BHS) ; Is 1,1 (LXX).

Mise en œuvre

Je crée une commande \bibleall qui se contente pour l’essentiel d’appeler une commande \bibleref.

\newcommand*{\bibleall}[1]{%
	%#1 : passage
	\footnote{\emph{Cf}. \bibleref{#1}}%
	}

Ceci permet d’appeler \bibleref depuis une autre commande \bible :

\newcommand*{\bible}[2]{%
	%#1 : passage
	%#2 : texte
	\emph{#2}\footnote{\bibleref{#1}}%
}

La commande \bibleref va se servir des outils du package etoolbox pour parcourir les listes. On se sert également du package xstring, qui nous permet de savoir le nombre de | dans chaque élément de la liste :

  • 1 si on n’indique pas la version.
  • 2 si on indique la version.

J’ai déjà mis des commentaires, qui devraient permettre de comprendre l’essentiel. Mais complétons un peu.

  • l. 3 : la commande \passage est une commande TeX et non pas LaTeX comme le prouve sa définition par \def et non par \newcommand. Voici quelques précisions sur sa définition :
    • ##1|##2|##3| signifie que ces arguments sont passés immédiatement après le nom de la commande, chaque argument étant suivi d’une pipe. Ainsi on appelle la commande de la forme suivante : \passage Is|1:1|LXX.
    • Cependant cette commande ne peut être appelée directement dans le corps du fichier. En effet, nous l’avons définie à l’intérieur de la commande \bibleref : sa portée, c’est à dire l’endroit où il est appellable, se limite donc à l’intérieur de \bibleref. Le fait que nous ayons défini \passage dans \bibleref explique que nos arguments aient 2 # et non un seul.
    • Nous passons les deux premiers arguments à la commande \bibleverse, selon la syntaxe de celle-ci. Puis si le troisième argument n’est pas vide, nous le mettons entre parenthèse.
  • l. 5. Nous définissons une commande vide \passages. Cette commande sera remplie par etoolbox pour constituer une liste que nous pourrons manipuler.
  • l. 6. Nous définissons un nombre \nbpassages qui nous servira à compter le nombre de passages. Un nombre est une sorte de compteur propre au passage etoolbox. L’avantage d’utiliser un nombre plutôt qu’un compteur est double :
    • Un nombre peut avoir une portée locale, alors qu’un compteur est global. Autrement dit, à chaque fois que nous appelons \bibleref, nous réinitialisons \nbpassages et il est impossible d’avoir accès à la valeur de \nbpassages en dehors de \bibleref
    • Un nombre est plus facile à manipuler avec etoolbox qu’un compteur.
  • l. 7 : nous indiquons que la commande \trouvepassages va nous permettre de manipuler un liste dont les éléments sont séparés par des +.
  • l. 8 : nous parcourons le texte passé en argument à \bibleref (#1), pour déterminer les éléments de la liste. Pour chaque élément de la liste : -
    • \numdef\nbpassages{\nbpassages+1} indique que nous augmentons d’une unité la valeur de \nbpassages.
    • \listadd\passages indique que nous ajoutons l’élément courant à la liste \passages.
  • Après la l. 10 nous allons désormais travailler non plus sur la liste #1 mais sur la liste \passages.
  • L. 11 : nous avons besoin d’un autre nombre, \cptpassage pour savoir combien d’éléments nous avons parcourus.
  • L. 12 à 18, nous définissons ce que nous ferons pour chaque élément de la liste :
    • L. 13 : incrémenter \cptpassage d’une unité.
    • L. 14 : tester le nombre | présent dans l’élément courant (##1) est au moins égal à 2 :
      • L. 15 : si c’est le cas, nous avons affaire à quelque chose du style Is|1:1|LXX. Dans ce cas, nous appelons \passage en lui passant une chaîne constitué de l’élément courant (##1) suivi de |. Dans notre exemple, c’est comme si nous faisions \passage Is|1:1|LXXL.
      • L. 16 : s’il y a moins de deux |, nous avons affaire à quelque chose du style Is|1:1. Dans ce cas, nous appelons \passage en lui passant une chaîne constitué de l’élément courant (##1) suivi de ||. Dans notre exemple, c’est comme si nous faisions \passage Is|1:1||.
    • Grâce au test de la ligne 14, nous pouvons indifféremment préciser ou non la version.
    • L. 17 : nous testons si \cptpassage est égal à \nbpassages, c’est à dire si nous avons affaire au dernier élément de la liste. Si tel est le cas, nous mettons un point final, sinon un ;.
    • L. 19 : nous exécutons ce que nous avons défini dans \do pour chaque élément de la liste \passages.

Ouf, ça y est. Le commentaire est fini. Il peut paraître un peu « lourd », mais mieux vaut être trop précis que pas assez.

Notes

[1Elle sert à indiquer la sélection de plusieurs versets discontinus.