Espansione chiavi in xkeyval

  • Creatore
    Topic
  • #29295
    robitex
    Amministratore del forum
      Up
      0
      Down
      ::


      Il problema è questo: le chiavi sono memorizzati in una macro, quindi in \setkeys non avviene la corretta lettura delle chiavi perché il token è espanso ma non correttamente riconosciuto come sequenza di caratteri.

      Ecco il codice:
      `\expandafter\edef\csname ctref@#1\endcsname{\ctref@temp}
      \define@key{ctfamLabel}{#1}[]{
      \setkeys{ctfamLabel}[id]{\csname ctref@#1\endcsname}
      }`

      Ottengo l’errore:
      Package xkeyval Error: `id=tot,c,s’ undefined in families `ctfamLabel’.

      Se nel codice inserisco i caratteri dell’espansione funziona tutto correttamente:

      `\expandafter\edef\csname ctref@#1\endcsname{\ctref@temp}
      \define@key{ctfamLabel}{#1}[]{
      \setkeys{ctfamLabel}[id]{id=tot,c,s}%\csname ctref@#1\endcsname}
      }`

      Come posso espandere la macro ctref@ in puri caratteri da far lavorare correttamente \setkeys?

      Il codice fa parte di un pacchetto a cui sto lavorando. Mi scuso se il post riguarda una questione poco utile agli altri utenti.
      Grazie

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

        Il problema è questo: le chiavi sono memorizzati in una macro, quindi in \setkeys non avviene la corretta lettura delle chiavi perché il token è espanso ma non correttamente riconosciuto come sequenza di caratteri.

        Ecco il codice:
        `\expandafter\edef\csname ctref@#1\endcsname{\ctref@temp}
        \define@key{ctfamLabel}{#1}[]{
        \setkeys{ctfamLabel}[id]{\csname ctref@#1\endcsname}
        }`

        Ottengo l’errore:
        Package xkeyval Error: `id=tot,c,s’ undefined in families `ctfamLabel’.

        Se nel codice inserisco i caratteri dell’espansione funziona tutto correttamente:

        `\expandafter\edef\csname ctref@#1\endcsname{\ctref@temp}
        \define@key{ctfamLabel}{#1}[]{
        \setkeys{ctfamLabel}[id]{id=tot,c,s}%\csname ctref@#1\endcsname}
        }`

        Come posso espandere la macro ctref@ in puri caratteri da far lavorare correttamente \setkeys?

        Il codice fa parte di un pacchetto a cui sto lavorando. Mi scuso se il post riguarda una questione poco utile agli altri utenti.

        Mi pare che tu ti stia complicando la vita, ma sono affari tuoi. 🙂

        Se sei sicuro che l’espansione di \ctref@ siano solo caratteri, dovresti ottenere ciò che desideri con
        `\expandafter\edef\csname ctref@#1\endcsname{\ctref@temp}
        \define@key{ctfamLabel}{#1}[]{%
        \edef\next{\noexpand\setkeys{ctfamLabel}[id]{\csname ctref@#1\endcsname}}
        \next
        }`
        Ciao
        Enrico

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

          Se sei sicuro che l’espansione di \ctref@ siano solo caratteri, dovresti ottenere ciò che desideri con
          `\expandafter\edef\csname ctref@#1\endcsname{\ctref@temp}
          \define@key{ctfamLabel}{#1}[]{%
          \edef\next{\noexpand\setkeys{ctfamLabel}[id]{\csname ctref@#1\endcsname}}
          \next
          }`

          Si funziona, anche se definire un comando temporaneo con \edef che espande la definizione all’interno della quale troviamo un \noexpand, è proprio un paradosso.

          L’ipotesi che faccio sul perché funziona è questa: \edef espande la definizione ma incontra un \noexpand ed inserisce il token \setkeys come è, ma espande tutto quello che segue, con il risultato dell’espansione in caratteri degli argomenti del comando.

          Mi pare che tu ti stia complicando la vita, ma sono affari tuoi. 🙂

          Veramente penso che questo sia il modo più semplice per implementare la chiave id anche per il comando \add (vedi “una tabella che fa calcoli”), ovvero salvare in una macro le chiavi di selezione volute dall’utente per ottenere la somma e riprodurle poi con \setkeys nel momento in cui l’utente stesso voglia operare su quella somma. Nient’altro.

          Grazie Prof.

        • #29298
          Up
          0
          Down
          ::

          Se sei sicuro che l’espansione di \ctref@ siano solo caratteri, dovresti ottenere ciò che desideri con
          `\expandafter\edef\csname ctref@#1\endcsname{\ctref@temp}
          \define@key{ctfamLabel}{#1}[]{%
          \edef\next{\noexpand\setkeys{ctfamLabel}[id]{\csname ctref@#1\endcsname}}
          \next
          }`

          Si funziona, anche se definire un comando temporaneo con \edef che espande la definizione all’interno della quale troviamo un \noexpand, è proprio un paradosso.

          L’ipotesi che faccio sul perché funziona è questa: \edef espande la definizione ma incontra un \noexpand ed inserisce il token \setkeys come è, ma espande tutto quello che segue, con il risultato dell’espansione in caratteri degli argomenti del comando.

          Esattamente, con il trucco di mettere ciò che si vuole espandere nel testo di sostituzione di \edef\next, inibendo però l’espansione di \setkeys ottengo la lista di token che desidero; poi basta espandere \next. Ricordarsi sempre che \edef è una brutta bestia, però. 🙂

          Ciao
          Enrico

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


            Benissimo, tuttavia ho scoperto che facendo una ricerca nel forum con \setkeys avrei scoperto un post che mi avrebbe indirizzato sulla soluzione con \edef.
            Sperando che questa discussione non sia del tutto inutile per il forum, vorrei domandare il perchè una normale espansione come questa non funziona:`\expandafter\expandafter\expandafter\space\csname ctref@#1\endcsname`

            L’ultimo \expandafter espande \csname e quindi viene creato il token complesso con uno \space davanti (xkeyval ignora gli spazi iniziali e finali), il secondo \expandafter espande il token complesso e quindi ricava i caratteri.
            Al termine rimane un \space da far digerire a \setkeys.

            Forse è proprio quel \space?

          • #29300
            Up
            0
            Down
            ::

            Benissimo, tuttavia ho scoperto che facendo una ricerca nel forum con \setkeys avrei scoperto un post che mi avrebbe indirizzato sulla soluzione con \edef.
            Sperando che questa discussione non sia del tutto inutile per il forum, vorrei domandare il perchè una normale espansione come questa non funziona:`\expandafter\expandafter\expandafter\space\csname ctref@#1\endcsname`

            L’ultimo \expandafter espande \csname e quindi viene creato il token complesso con uno \space davanti (xkeyval ignora gli spazi iniziali e finali), il secondo \expandafter espande il token complesso e quindi ricava i caratteri.
            Al termine rimane un \space da far digerire a \setkeys.

            Forse è proprio quel \space?

            Dove la metteresti? Dentro un \edef? Occorre già avere a disposizione qualcosa da mettere al posto di #1, altrimenti sei nei pasticci.

            Ciao
            Enrico

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

              Benissimo, tuttavia ho scoperto che facendo una ricerca nel forum con \setkeys avrei scoperto un post che mi avrebbe indirizzato sulla soluzione con \edef.
              Sperando che questa discussione non sia del tutto inutile per il forum, vorrei domandare il perchè una normale espansione come questa non funziona:`\expandafter\expandafter\expandafter\space\csname ctref@#1\endcsname`

              L’ultimo \expandafter espande \csname e quindi viene creato il token complesso con uno \space davanti (xkeyval ignora gli spazi iniziali e finali), il secondo \expandafter espande il token complesso e quindi ricava i caratteri.
              Al termine rimane un \space da far digerire a \setkeys.

              Forse è proprio quel \space?

              Dove la metteresti? Dentro un \edef? Occorre già avere a disposizione qualcosa da mettere al posto di #1, altrimenti sei nei pasticci.

              Ciao
              Enrico

              Non dentro un \edef ma direttamente come argomento di \setkeys:
              `% attenzione, non funziona
              \setkeys{ctfamLabel}[id]{\expandafter\expandafter\expandafter\space\csname ctref@#1\endcsname} `

              Solo per chiarire 🙄 .

              PS. il codice sta all’interno di una \define@key quindi per #1 si intende il valore che l’utente inserisce come valore della chiave id.

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

          Go to top