Bonjour, ma précédente et éphémère question a été retirée car il s'agissait une erreur bête de ma part, mais là j'aurais un souci (ou une demande) que je n'arrive pas à gérer simplement...

J'essaye, pour compléter mes recherches en LaTeX3, de créer une macro pour traiter une liste d'éléments et d'accéder à ses éléments. La commande de lecture peut spécifier un séparateur personnalisé, et la commande d'accès peut afficher ou stocker.

Là où j'ai été confronté à un souci que je n'imaginais pas, c'est la gestion des éléments de la liste, que je dois pouvoir donner sous forme brute, ou sous forme d'une macro (latex2 ou latex3), et là je n'arrive pas à gérer les possibilités, je dois spécifier (version étoilée) que je travaille avec l'une ou l'autre des capacités...

Mon code est le suivant :

\documentclass{article}
\usepackage{amsmath}

\ExplSyntaxOn
\NewDocumentCommand\pflcreatelistsingle{ s O{,} m m }
    {
      % #1 = étoilé => mode argument, sinon mode macro (à voir :-/)
      % #2 = séparateur principal (par défaut: ,)
      % #3 = nom de la structure (ex: maliste)
      % #4 = contenu de la liste

      % Stocker le séparateur principal
      \tl_if_exist:cF { g__pfl_#3_mainsep_tl }
        { \tl_new:c { g__pfl_#3_mainsep_tl } }
      \tl_gset:cn { g__pfl_#3_mainsep_tl } { #2 }
      %liste à construire
      \seq_if_exist:cF { g__pfl_#3_main_seq }
        { \seq_new:c { g__pfl_#3_main_seq } }
      \seq_clear:c { g__pfl_#3_main_seq }
      %gestion arg/macro ?
      \IfBooleanTF{#1}
      {
        %expansion de la liste, si besoin
        \tl_set:Nn \l_tmpmylist_tl { #4 }
        \seq_set_split:NnV \l_tmpa_seq { #2 } { \l_tmpmylist_tl }
      }
      {
        \seq_set_split:NnV \l_tmpa_seq { #2 } { #4 }
      }
      % Toujours utiliser une seq, même pour les virgules
      \seq_gset_eq:cN { g__pfl_#3_main_seq } \l_tmpa_seq

      % Stocker le nombre d'éléments
      \int_if_exist:cF { g__pfl_#3_count_int }
        { \int_new:c { g__pfl_#3_count_int } }
      \int_gset:cn { g__pfl_#3_count_int } { \seq_count:c { g__pfl_#3_main_seq } }
    }

    \NewDocumentCommand\pflgetfromlistsingle{ s m m O{\myelt} }
    {
      % #2 = nom, #3 = index, #4 = macro
      \int_set:Nn \l_tmpa_int { \int_eval:n { #3 } }
      \tl_clear:N \l_tmpa_tl
      \tl_set:Nx \l_tmpa_tl { \seq_item:cn { g__pfl_#2_main_seq } { \int_use:N \l_tmpa_int } }

      \IfBooleanTF{#1}
      {
        \tl_if_exist:NF \g__pfleltlistsingle_result_tl
        { \tl_new:N \g__pfleltlistsingle_result_tl }
        \tl_gset_eq:NN \g__pfleltlistsingle_result_tl \l_tmpa_tl
        \tl_use:N \l_tmpa_tl
      }
      {
        \tl_set_eq:NN #4 \l_tmpa_tl
      }
    }
\ExplSyntaxOff

\begin{document}

%si argument en 'dur', version non étoilée fonctionne
\pflcreatelistsingle{maliste}{ {1+\dfrac{1}{x}} , { \sqrt{x+61} } }
Élément 1 : $\pflgetfromlistsingle*{maliste}{1}$\\
Élément 2 : \pflgetfromlistsingle{maliste}{2}[\myelt]$\myelt$\\
Élément 3 : $\pflgetfromlistsingle*{maliste}{3}$

%si argument macro, version non étoilée fonctionne
\def\maliste{ {1+\dfrac{1}{x}} , { \sqrt{x+61} } }
\pflcreatelistsingle{maliste}{ \maliste }
Élément 1 : $\pflgetfromlistsingle*{maliste}{1}$\\
Élément 2 : \pflgetfromlistsingle{maliste}{2}[\myelt]$\myelt$

%si argument en dur avec imbrication, version étoilée obligatoire
\pflcreatelistsingle*{maliste}{ AAA , { BBB,CCC } }
Élément 1 : $\pflgetfromlistsingle*{maliste}{1}$\\
Élément 2 : \pflgetfromlistsingle{maliste}{2}[\myelt]$\myelt$

\end{document}

J'ai globalement compris le fonctionnement de l'expansion en latex3, mais j'ai l'impression que l'interaction latex2/latex3 est moins explicite que je l'aurais envisagé...

Posée 28 Oct, 18:38

cpierquet's gravatar image

cpierquet
36615
Taux d'acceptation : 12%

Modifiée 30 Oct, 11:03

Pathe's gravatar image

Pathe ♦♦
7.8k68218263

1

Supposons que l'on a exécuté : \def\blabla{un,deux,trois}. On applique ensuite \pflcreatelistsingle{maliste}{\blabla}. Comment LaTeX pourra-t-il savoir si la liste à stocker dans maliste est une liste de longueur 1 (avec comme unique composante \blabla) ou bien une liste de longueur 3 (avec comme composantes un, deux et trois) ? Il faut donc bien deux syntaxes.

(28 Oct, 20:51) fpantigny fpantigny's gravatar image

Pour préciser un peu, et après quelques tests supplémentaires, j'ai constaté que le traitement de mon argument (en brut ou via une macro) était différent : 1/ suivant la présence ou non du séparateur dans les éléments e1 , e2 , e3 , ... 2/ suivant ou non l'utilsation d'une macro comme argument

Je pensais que la gestion des arguments dans des macros l3 pourrait être transparente, mais je me rends compte que pour des cas particuliers (tordus ?) cela n'est pas aussi simple :-)

Pour préciser un peu, il semblerait que le fait de protéger les éléments d'une liste par des accolades puisse aider

(29 Oct, 21:09) cpierquet cpierquet's gravatar image
1

La plupart des langages de programmation classiques s'appuient sur un processus d'évaluation des expressions et, en particulier, d'évaluation des arguments d'une fonction avant application de la fonction elle-même. Mais TeX ne propose rien d'équivalent. L'expansion au sens de TeX n'est pas une évaluation mais une macro-expansion (comme le système de macros du précompilateur C).

(30 Oct, 15:18) fpantigny fpantigny's gravatar image

Dans le cas présent, le moyen de se rapprocher le plus d'une évaluation classique serait de protéger les éléments des listes avec des \exp_not:n {...} puis de faire une expansion complète (de type e) de l'argument de la macro.

(30 Oct, 15:18) fpantigny fpantigny's gravatar image

J'ai 'réussi' (je mets des guillemets car je pense que ça va soulever d'autres soucis...) en utilisant une expansion de type 'o' (avec la variante créée), ce qui semble à la fois gérer les arguments classiques et les arguments type macro.... Mais je me doute que mes travaux et avancées sont sur une base fragile :-)

(30 Oct, 15:22) cpierquet cpierquet's gravatar image
Soyez le premier à répondre à cette question !
(dés)activer l'aperçu

Suivre cette question

Par courriel :

Une fois que vous serez enregistré, vous pourrez souscrire à n'importe quelle mise à jour ici

Par flux RSS :

Réponses

Réponses et commentaires

Bases de Markdown

  • *italique* ou _italique_
  • **gras** ou __gras__
  • Lien ::[texte](http://url.com/ "Titre ")
  • Image : ?![alt texte](/path/img.jpg "Titre ")
  • Liste numérotée : 1. Foo 2. Bar
  • Pour ajouter un passage à la ligne, ajoutez deux espaces à l'endroit où vous souhaitez que la ligne commence.
  • Les balises HTML de base sont également prises en charge.