Tester l'existence d'un compteur

Bonjour,

J'ai besoin de créer un index classique et un "glossaire" où les mots clé seraient regroupés par thème par exemple
Les chaines
len p 32 longueur de la chaine

Les lites
append p 38 ......


Ne sachant pas si c'était faisable automatiquement, je me suis lancé dans la création manuelle : j'ai une commande glossaire qui mémorise le numéro de page, que je rappelle dans mon glossaire. Le problème c'est que lorsque je ne compile qu'un chapitre, certains compteurs n'existent pas et ça ne fonctionne pas, je voudrais donc pouvoir tester l’existence de ce dernier, voici ce que j'ai fait
\newcommand{\glossaire}[1]{
\newcounter{CGloss#1}
\setcounter{CGloss#1}{\thepage}
}

\newcommand{\affichepage}[1]{
\ifcsname c@CGloss#1\endcsname \theCGloss#1 \else
XXX\fi
}

Mais il n'apprécie pas le \theCGloss#1 ... pourtant si je mets YYY, il retourne bien XXX ou YYY selon existence ou non.

Avez-vous vous des idées sur la raison ?

D'avance merci,
Vincent

Réponses

  • Bonjour,

    Peut-être en écrivant :
    \csname theCGloss#1\endcsname
    
  • Parfait, merci beaucoup, je n'ai pas compris la subtilité, mais ça fonctionne et c'est déjà ça.

    Merci pour la réponse rapide,

    Vincent
  • @Vincent

    Avec le code que tu as posté, lorsque ta commande \affichepage (une macro) est développée, elle met le lexème (token) \theCGloss suivi du paramètre. Autrement dit, l'argument #1 ne fait pas partie du nom de la commande \theCGloss, il vient après. La méthode d'Audeo évite cet écœil : \csname ... \endcsname fabrique un nom de commande (un control sequence token) à partir de ce qu'il y a dans les '...'.

    Cela dit, je crains que ton approche ne se heurte à des problèmes plus embêtants :
    1. Si j'ai bien compris, tu vas faire un compteur par terme du glossaire. Ça ne “scale” pas : un beau jour, tu auras épuisé tous les compteurs disponibles (moins de 255 avec un TeX de base, même pas sûr qu'eTeX ou d'autres moteurs plus modernes aient augmenté cette valeur). Une solution serait d'utiliser une “property list” (proplist) LaTeX3. C'est ce que les matheux appelleraient une application : il s'agit d'une structure de données permettant d'enregistrer et récupérer des associations (clé, valeur) (à chaque clé est associée une valeur).
    2. Mais il y a un autre problème. Au moment où ta macro contenant \thepage est développée, \thepage a pour valeur le numéro $n$ de la page sur laquelle TeX est en train de travailler, autrement la première dont le point de coupure n'a pas encore été déterminé. Mais comme TeX traite chaque paragraphe comme un ensemble et non ligne par ligne (les résultats sont bien meilleurs ainsi), si par exemple \thepage est développé au milieu d'un paragraphe, il aura la valeur $n$ que je viens de décrire alors que la ou les lignes contenant les caractères le précédant et le suivant dans le paragraphe pourrai(en)t très bien se retrouver sur la page $n+1$, voire plus loin si des insertions passent avant la suite du paragraphe (figures, footnotes gigantesques...).

      Donc l'utilisation naïve de \thepage n'est pas une bonne méthode pour produire des choses telles qu'un index. Pour ça, Knuth a implémenté le mécanisme des whatsit dans TeX. Il y a notament les commandes \openout, \write et \closeout qui produisent des whatsit. Ce qui se passe, c'est que \write enregistre une liste de tokens passée en argument dans un whatsit en l'associant à un fichier ouvert avec \openout, mais ne va développer cette liste de tokens que lorsque la liste horizontale, verticale ou mathématique contenant ce whatsit se retrouve définitivement sur une page (i.e., dans une boîte contenue dans une boîte contenue dans ... une boîte qui est passée à \shipout, la commande TeX qui sort une page à partir d'une boîte). Au moment où cela se produit, TeX connaît donc le bon numéro de page et le développement de \thepage produira l'effet escompté. Si tu veux aprofondir ça, lis le chapitre 21 du TeXbook (Making Boxes).

    Bref, mon conseil serait d'utiliser une solution toute faite, quitte à passer un peu de temps pour la mise en place. En utilisant « moteur de recherche préféré », on trouve le package glossaries. Je ne l'ai pas testé. Il s'appuie apparemment sur makeindex ou xindy ; je conseillerais xindy qui est plus moderne (support d'UTF-8...).
  • Bonsoir,

    Merci pour toutes ces précisions, le premier point n'était pas un problème car j'utilisai des noms de compteur style chaineLen ou listeAppend... Par contre en effet, le problème de \thepage risque d’entrainer quelques mauvaises surprises. En effet, je pense que ça vaut le coup de se plonger dans ce package.

    Merci pour les liens.

    Vincent
  • Bonsoir,

    Je crois que tu te trompes dans ta première phrase :
    % latexdef newcounter
    
    \newcounter:
    macro:#1->\expandafter \@ifdefinable \csname c@#1\endcsname {\@definecounter {#1}}\@ifnextchar [{\@newctr {#1}}{}
    
    % latexdef @definecounter
    
    \@definecounter:
    macro:#1->\expandafter \newcount \csname c@#1\endcsname \setcounter {#1}\z@ \global \expandafter \let \csname cl@#1\endcsname \@empty \@addtoreset {#1}{@ckpt}\global \expandafter \let \csname p@#1\endcsname \@empty \expandafter \gdef \csname the#1\expandafter \endcsname \expandafter {\expandafter \@arabic \csname c@#1\endcsname }
    
    %
    
    Autrement dit, derrière tout \newcounter LaTeX se cache un \newcount TeX. Tes jolis noms de compteurs sont automatiquement transformés en entiers correspondant aux numéros des registres \count de TeX. Chaque nouveau compteur LaTeX donne lieu à l'allocation d'un registre \count TeX ; tu ne pourras donc pas créer plus de compteurs qu'il n'y a de registres \count libres (256 au total dans le moteur TeX de Knuth, dont un certain nombre sont utilisés d'office pour le fonctionnement normal de TeX ; il y en a 32768 dans $\varepsilon$-$\TeX$, mais bon, dans le principe, c'est quand-même pas terrible de se limiter de la sorte quand on peut faire autrement).
Connectez-vous ou Inscrivez-vous pour répondre.