Come spezzare un argomento di un comando alla virgola

  • Creatore
    Topic
  • #40140
    exedre
    Partecipante
      Up
      0
      Down
      ::


      Posto di avere un comando come il seguente

      `\comando{pippo,pluto,nonna papera}`

      Questi argomenti sono casuali e non scelti all’interno di una lista prefissata (altrimenti sarebbe stato possibile usare xkeyval)

      Vorrei ottenere una cosa sostanzialmente simile alla definizione di:

      `\setcounter{comando@num@argomenti}{3}
      \renewcommand{\comando@primo@argomento}{pippo}
      \renewcommand{\comando@secondo@argomento}{pluto}
      \renewcommand{\comando@terzo@argomento}{nonna papera}
      `

      Si può fare?

      Grazie,
      Emmanuele

    Visualizzazione 5 filoni di risposte
    • Autore
      Risposte
      • #40141
        Up
        0
        Down
        ::

        Posto di avere un comando come il seguente

        `\comando{pippo,pluto,nonna papera}`

        Questi argomenti sono casuali e non scelti all’interno di una lista prefissata (altrimenti sarebbe stato possibile usare xkeyval)

        Vorrei ottenere una cosa sostanzialmente simile alla definizione di:

        `\setcounter{comando@num@argomenti}{3}
        \renewcommand{\comando@primo@argomento}{pippo}
        \renewcommand{\comando@secondo@argomento}{pluto}
        \renewcommand{\comando@terzo@argomento}{nonna papera}
        `

        Certo che si può fare. 😀
        `\documentclass[a4paper]{article}

        \newcounter{nargs}

        \makeatletter
        \def\processlist#1{\def\given@list{#1}%
        \count@=\z@
        \@for\next:=\given@list\do
        {\advance\count@\@ne
        \expandafter\xdef\csname list@arg@\romannumeral\count@\endcsname{\next}%
        }%
        \setcounter{nargs}{\count@}%
        }
        \def\showlistargs{%
        Numero argomenti: \thenargs\par
        \count@=\z@
        \loop\ifnum\count@<\value{nargs}% \advance\count@\@ne \texttt{\expandafter\string\csname list@arg@\romannumeral\count@\endcsname} $\to$ \csname list@arg@\romannumeral\count@\endcsname\par \repeat} \makeatother \begin{document} \processlist{pippo,pluto,nonna papera} \showlistargs \medskip \processlist{a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z} \showlistargs \end{document}` Vedi anche i nomi che vengono assegnati alle macro che contengono i vari elementi della lista; la macro \showlistargs è solo per la dimostrazione del funzionamento. Spiegazione. La costruzione `\@for\next:=\given@list\do{}`
        ha bisogno che \given@list (il nome della macro non è obbligatorio) si espanda a una lista di elementi separati da virgole. Per questo la macro \processlist comincia definendo \given@list come l’argomento che viene passato.

        Per ogni elemento viene eseguito ; qui può contenere \next (anche questo nome è arbitrario) la cui espansione è l’elemento della lista che si sta esaminando. Nel nostro caso, \processlist{pippo,pluto,nonna papera} causa l’esecuzione di tre volte: la prima volta \next si espande a “pippo”, la seconda a “pluto” e la terza a “nonna papera”.

        Il contatore temporaneo \count@ viene inizializzato a 0, a ogni esecuzione di aumenta di uno e il valore di \next diventa il testo di sostituzione di una macro il cui nome è costruito a partire dal valore di \count@: se \count@ vale 1, l’espansione di \romannumeral\count@ è “i”.

        Usiamo \xdef perché così la definizione è globale e viene usata l’espansione di \next, cioè proprio l’elemento della lista che si sta esaminando.

        Ciao
        Enrico

      • #40142
        exedre
        Partecipante
          Up
          0
          Down
          ::


          Grazie, proprio quello che mi serviva.

          E

        • #40143
          exedre
          Partecipante
            Up
            0
            Down
            ::

            Certo che si può fare. 😀
            `\documentclass[a4paper]{article}
            […]
            \begin{document}

            \processlist{pippo,pluto,nonna papera}
            \showlistargs

            […]
            \end{document}`

            E si può fare in modo che funzioni anche questo?

            `
            \def\myargs{pippo,pluto,nonna papera}
            \processlist{\myargs}
            \showlistargs
            `

            che adesso ha come risultato:

            `Numero argomenti: 1
            \list@arg@i → pippo,pluto,nonna papera
            `

            e invece sarebbe bello che fosse:

            `Numero argomenti: 3
            \list@arg@i → pippo
            \list@arg@ii → pluto
            \list@arg@iii → nonna papera
            `

            Grazie,
            Emmanuele

          • #40144
            robitex
            Amministratore del forum
              Up
              0
              Down
              ::

              Certo che si può fare. 😀
              `\documentclass[a4paper]{article}
              […]
              \begin{document}

              \processlist{pippo,pluto,nonna papera}
              \showlistargs

              […]
              \end{document}`

              E si può fare in modo che funzioni anche questo?

              `
              \def\myargs{pippo,pluto,nonna papera}
              \processlist{\myargs}
              \showlistargs
              `

              che adesso ha come risultato:

              `Numero argomenti: 1
              \list@arg@i → pippo,pluto,nonna papera
              `

              e invece sarebbe bello che fosse:

              `Numero argomenti: 3
              \list@arg@i → pippo
              \list@arg@ii → pluto
              \list@arg@iii → nonna papera
              `

              Grazie,
              Emmanuele

              Segnalo il pacchetto etextools.
              Propone una serie completa di comandi per il parsing delle liste.
              Ciao

            • #40145
              exedre
              Partecipante
                Up
                0
                Down
                ::

                Segnalo il pacchetto etextools.
                Propone una serie completa di comandi per il parsing delle liste.
                Ciao

                Wow! Ottimo suggerimento, e pure (sovr)abbondante. Risolve il mio problema reale (con \csvloop)

                Comunque mi piacerebbe capire la questione dell’espansione dell’argomento. Ho pasticciato un po’ con \expandafter senza raggiungere alcun risultato.

              • #40146
                Up
                0
                Down
                ::

                Certo che si può fare. 😀
                `\documentclass[a4paper]{article}
                […]
                \begin{document}

                \processlist{pippo,pluto,nonna papera}
                \showlistargs

                […]
                \end{document}`

                E si può fare in modo che funzioni anche questo?

                `
                \def\myargs{pippo,pluto,nonna papera}
                \processlist{\myargs}
                \showlistargs
                `

                che adesso ha come risultato:

                `Numero argomenti: 1
                \list@arg@i → pippo,pluto,nonna papera
                `

                e invece sarebbe bello che fosse:

                `Numero argomenti: 3
                \list@arg@i → pippo
                \list@arg@ii → pluto
                \list@arg@iii → nonna papera
                `

                Sostituisci la riga
                `\def\processlist#1{\def\given@list{#1}`
                con
                `\def\processlist#1{\toks@=\expandafter{#1}%
                \edef\given@list{\the\toks@}%`
                Ciao
                Enrico

            Visualizzazione 5 filoni di risposte
            • Devi essere connesso per rispondere a questo topic.

            Go to top