[L3] Chiave con valore di default di un’altra chiave

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


      Ciao,
      nel seguente codice LaTeX3 definisco due chiavi, la prima chiamata ‘name’ e la seconda chiamata ‘secname’ (secondo nome).
      L’effetto che vorrei ottenere è che se non specifico un valore per la chiave secname, questa assuma il valore della chiave ‘name’.
      `
      \documentclass{article}
      \usepackage[T1]{fontenc}
      \usepackage[utf8]{inputenc}
      \usepackage[italian]{babel}

      \usepackage{expl3}
      \usepackage{xparse}

      \ExplSyntaxOn
      \keys_define:nn { gdsfamily }
      {
      name .tl_set:N = \g_gds_name_tl,
      name .default:n = Paperino,

      secname .tl_set:N = \g_gds_secname_tl,
      secname .default:V = \g_gds_name_tl % non funziona con .default:n si
      }

      \keys_set:nn { gdsfamily } { name }
      \keys_set:nn { gdsfamily } { secname }

      \NewDocumentCommand { \name } { }
      {
      \tl_use:N \g_gds_name_tl
      }

      \NewDocumentCommand { \secname } { }
      {
      \tl_use:N \g_gds_secname_tl
      }
      \ExplSyntaxOff

      \begin{document}
      Il nome è il seguente: \name{} \secname.
      \end{document}`
      Il codice non funziona, ma se cambio la funzione da .default:V a .default:n funziona, come mai?
      Grazie R.

    Visualizzazione 3 filoni di risposte
    • Autore
      Risposte
      • #80969
        Up
        0
        Down
        ::

        robitex” post=80202Ciao,
        nel seguente codice LaTeX3 definisco due chiavi, la prima chiamata ‘name’ e la seconda chiamata ‘secname’ (secondo nome).
        L’effetto che vorrei ottenere è che se non specifico un valore per la chiave secname, questa assuma il valore della chiave ‘name’.
        `
        \documentclass{article}
        \usepackage[T1]{fontenc}
        \usepackage[utf8]{inputenc}
        \usepackage[italian]{babel}

        \usepackage{expl3}
        \usepackage{xparse}

        \ExplSyntaxOn
        \keys_define:nn { gdsfamily }
        {
        name .tl_set:N = \g_gds_name_tl,
        name .default:n = Paperino,

        secname .tl_set:N = \g_gds_secname_tl,
        secname .default:V = \g_gds_name_tl % non funziona con .default:n si
        }

        \keys_set:nn { gdsfamily } { name }
        \keys_set:nn { gdsfamily } { secname }

        \NewDocumentCommand { \name } { }
        {
        \tl_use:N \g_gds_name_tl
        }

        \NewDocumentCommand { \secname } { }
        {
        \tl_use:N \g_gds_secname_tl
        }
        \ExplSyntaxOff

        \begin{document}
        Il nome è il seguente: \name{} \secname.
        \end{document}`
        Il codice non funziona, ma se cambio la funzione da .default:V a .default:n funziona, come mai?
        Grazie R.

        Con [tt].default:V= \g_gds_name_tl[/tt] imposti il valore di default al valore attuale della variabile che, naturalmente è vuoto perché [tt]name[/tt] non è ancora stata impostata, ma solo definita. Se usi [tt].default:n[/tt] come valore viene presa la variabile [tt]\g_gds_name_tl[/tt]. Se infatti provi senza impostare un valore per [tt]name[/tt] avrai un valore vuoto.

        Devi definire la chiave in modo diverso:
        `\keys_define:nn { gdsfamily }
        {
        secname .code:n =
        \tl_if_empty:nTF { #1 }
        { \tl_gset:NV \g_gds_secname_tl \g_gds_name_tl }
        { \tl_gset:Nn \g_gds_secname_tl { #1 } }
        }`
        Tiratina d’orecchie quotidiana. 🙂 Le variabili globali vanno sempre usate globalmente. Quindi [tt]_gset[/tt], non [tt]_set[/tt].

        Ciao
        Enrico

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

          egreg9″ post=80203

          Ciao,
          nel seguente codice LaTeX3 definisco due chiavi, la prima chiamata ‘name’ e la seconda chiamata ‘secname’ (secondo nome).
          L’effetto che vorrei ottenere è che se non specifico un valore per la chiave secname, questa assuma il valore della chiave ‘name’.
          `
          \documentclass{article}
          \usepackage[T1]{fontenc}
          \usepackage[utf8]{inputenc}
          \usepackage[italian]{babel}

          \usepackage{expl3}
          \usepackage{xparse}

          \ExplSyntaxOn
          \keys_define:nn { gdsfamily }
          {
          name .tl_set:N = \g_gds_name_tl,
          name .default:n = Paperino,

          secname .tl_set:N = \g_gds_secname_tl,
          secname .default:V = \g_gds_name_tl % non funziona con .default:n si
          }

          \keys_set:nn { gdsfamily } { name }
          \keys_set:nn { gdsfamily } { secname }

          \NewDocumentCommand { \name } { }
          {
          \tl_use:N \g_gds_name_tl
          }

          \NewDocumentCommand { \secname } { }
          {
          \tl_use:N \g_gds_secname_tl
          }
          \ExplSyntaxOff

          \begin{document}
          Il nome è il seguente: \name{} \secname.
          \end{document}`
          Il codice non funziona, ma se cambio la funzione da .default:V a .default:n funziona, come mai?
          Grazie R.

          Con [tt].default:V= \g_gds_name_tl[/tt] imposti il valore di default al valore attuale della variabile che, naturalmente è vuoto perché [tt]name[/tt] non è ancora stata impostata, ma solo definita. Se usi [tt].default:n[/tt] come valore viene presa la variabile [tt]\g_gds_name_tl[/tt]. Se infatti provi senza impostare un valore per [tt]name[/tt] avrai un valore vuoto.

          Devi definire la chiave in modo diverso:
          `\keys_define:nn { gdsfamily }
          {
          secname .code:n =
          \tl_if_empty:nTF { #1 }
          { \tl_gset:NV \g_gds_secname_tl \g_gds_name_tl }
          { \tl_gset:Nn \g_gds_secname_tl { #1 } }
          }`
          Tiratina d’orecchie quotidiana. 🙂 Le variabili globali vanno sempre usate globalmente. Quindi [tt]_gset[/tt], non [tt]_set[/tt].

          Ciao
          Enrico

          Questa volta la tiratina d’orecchie, una volta tanto, posso fartela io! 🙂
          Infatti ho modificato la definizione delle chiavi con la tua proposta:
          `\keys_define:nn { gdsfamily }
          {
          name .tl_gset:N = \g_gds_name_tl,
          name .default:n = Paperino,

          secname .code:n =
          \tl_if_empty:nTF { #1 }
          {\tl_gset:NV \g_gds_secname_tl \g_gds_name_tl}
          {\tl_gset:Nn \g_gds_secname_tl { #1 } },
          }
          \keys_set:nn { gdsfamily } { name }
          \keys_set:nn { gdsfamily } { secname }`

          Tutto bene, un codice pulito e semplice: quando assegno la chiave ‘secname’ senza valore essa imposterà la sua corrispondente variabile a quello della variabile in cui è salvato il valore della chiave ‘name’, mentre se passo un valore questo diverrà quello salvato.

          Se però chiamo assegno solamente la chiave ‘name’ la chiave ‘secname’ non prenderà il nuovo valore se non verrà espressa:
          Con questi comandi infatti
          `\NewDocumentCommand { \name } { m }
          {
          \keys_set:nn { gdsfamily } { name = #1 }
          \tl_use:N \g_gds_name_tl
          }

          \NewDocumentCommand { \secname } { }
          {
          \tl_use:N \g_gds_secname_tl
          }`
          e questo codice utente:
          `Il nome è il seguente: \name{Pluto} \secname.`
          Ottengo (ovviamente) non: “Il nome è il seguente: Pluto Pluto.” ma “Il nome è il seguente: Pluto Paperino.”

          L’importante è che LaTeX3 sia in grado di creare un ambiente di programmazione pulito.

          Illustro adesso un codice che funziona (considera che ho le orecchie già abbastanza tirate…).
          Assegno i valori di default con .default:n:
          `\documentclass{article}
          \usepackage[T1]{fontenc}
          \usepackage[utf8]{inputenc}
          \usepackage[italian]{babel}

          \usepackage{expl3}
          \usepackage{xparse}

          \ExplSyntaxOn
          \keys_define:nn { gdsfamily }
          {
          name .tl_gset:N = \g_gds_name_tl,
          name .default:n = Paperino,

          secname .tl_gset:N = \g_gds_secname_tl,
          secname .default:n = \g_gds_name_tl,
          }

          \keys_set:nn { gdsfamily } { name , secname }

          \NewDocumentCommand { \setnames } { m }
          {
          \keys_set:nn { gdsfamily } { #1 }
          }

          \NewDocumentCommand { \getname } { m }
          {
          \tl_use:c { g_gds_#1_tl }
          }
          \ExplSyntaxOff

          \begin{document}
          Se non si impostano le chiavi esse prendono il valore di default: Il nome è il seguente: \getname{name}, il secondo nome è \getname{secname}.

          \setnames{ name = Pluto }

          Adesso, il nome è \getname{name}, e la chiave dovrebbe essere con lo stesso valore che è appunto: \getname{secname}.

          \setnames{secname = Mitico Pippo}
          Dopo aver assegnato anche la chiave del secondo nome lo stampiamo: \getname{secname} (il nome principale è rimasto a \getname{name}).

          \setnames{name = Topolino}
          Se a questo punto modifichiamo anche il primo nome avremo: nome = \getname{name}, secondo nome = \getname{secname}.
          \end{document}
          `

          Alla prossima3.
          Ciao e grazie.
          R.

        • #80971
          Up
          0
          Down
          ::

          robitex” post=80210

          [quote=”robitex” post=80202]Ciao,
          nel seguente codice LaTeX3 definisco due chiavi, la prima chiamata ‘name’ e la seconda chiamata ‘secname’ (secondo nome).
          L’effetto che vorrei ottenere è che se non specifico un valore per la chiave secname, questa assuma il valore della chiave ‘name’.
          `
          \documentclass{article}
          \usepackage[T1]{fontenc}
          \usepackage[utf8]{inputenc}
          \usepackage[italian]{babel}

          \usepackage{expl3}
          \usepackage{xparse}

          \ExplSyntaxOn
          \keys_define:nn { gdsfamily }
          {
          name .tl_set:N = \g_gds_name_tl,
          name .default:n = Paperino,

          secname .tl_set:N = \g_gds_secname_tl,
          secname .default:V = \g_gds_name_tl % non funziona con .default:n si
          }

          \keys_set:nn { gdsfamily } { name }
          \keys_set:nn { gdsfamily } { secname }

          \NewDocumentCommand { \name } { }
          {
          \tl_use:N \g_gds_name_tl
          }

          \NewDocumentCommand { \secname } { }
          {
          \tl_use:N \g_gds_secname_tl
          }
          \ExplSyntaxOff

          \begin{document}
          Il nome è il seguente: \name{} \secname.
          \end{document}`
          Il codice non funziona, ma se cambio la funzione da .default:V a .default:n funziona, come mai?
          Grazie R.

          Con [tt].default:V= \g_gds_name_tl[/tt] imposti il valore di default al valore attuale della variabile che, naturalmente è vuoto perché [tt]name[/tt] non è ancora stata impostata, ma solo definita. Se usi [tt].default:n[/tt] come valore viene presa la variabile [tt]\g_gds_name_tl[/tt]. Se infatti provi senza impostare un valore per [tt]name[/tt] avrai un valore vuoto.

          Devi definire la chiave in modo diverso:
          `\keys_define:nn { gdsfamily }
          {
          secname .code:n =
          \tl_if_empty:nTF { #1 }
          { \tl_gset:NV \g_gds_secname_tl \g_gds_name_tl }
          { \tl_gset:Nn \g_gds_secname_tl { #1 } }
          }`
          Tiratina d’orecchie quotidiana. 🙂 Le variabili globali vanno sempre usate globalmente. Quindi [tt]_gset[/tt], non [tt]_set[/tt].

          Ciao
          Enrico

          Questa volta la tiratina d’orecchie, una volta tanto, posso fartela io! 🙂
          Infatti ho modificato la definizione delle chiavi con la tua proposta:
          `\keys_define:nn { gdsfamily }
          {
          name .tl_gset:N = \g_gds_name_tl,
          name .default:n = Paperino,

          secname .code:n =
          \tl_if_empty:nTF { #1 }
          {\tl_gset:NV \g_gds_secname_tl \g_gds_name_tl}
          {\tl_gset:Nn \g_gds_secname_tl { #1 } },
          }
          \keys_set:nn { gdsfamily } { name }
          \keys_set:nn { gdsfamily } { secname }`

          Tutto bene, un codice pulito e semplice: quando assegno la chiave ‘secname’ senza valore essa imposterà la sua corrispondente variabile a quello della variabile in cui è salvato il valore della chiave ‘name’, mentre se passo un valore questo diverrà quello salvato.

          Se però chiamo assegno solamente la chiave ‘name’ la chiave ‘secname’ non prenderà il nuovo valore se non verrà espressa:
          Con questi comandi infatti
          `\NewDocumentCommand { \name } { m }
          {
          \keys_set:nn { gdsfamily } { name = #1 }
          \tl_use:N \g_gds_name_tl
          }

          \NewDocumentCommand { \secname } { }
          {
          \tl_use:N \g_gds_secname_tl
          }`
          e questo codice utente:
          `Il nome è il seguente: \name{Pluto} \secname.`
          Ottengo (ovviamente) non: “Il nome è il seguente: Pluto Pluto.” ma “Il nome è il seguente: Pluto Paperino.”

          L’importante è che LaTeX3 sia in grado di creare un ambiente di programmazione pulito.

          Illustro adesso un codice che funziona (considera che ho le orecchie già abbastanza tirate…).
          Assegno i valori di default con .default:n:
          `\documentclass{article}
          \usepackage[T1]{fontenc}
          \usepackage[utf8]{inputenc}
          \usepackage[italian]{babel}

          \usepackage{expl3}
          \usepackage{xparse}

          \ExplSyntaxOn
          \keys_define:nn { gdsfamily }
          {
          name .tl_gset:N = \g_gds_name_tl,
          name .default:n = Paperino,

          secname .tl_gset:N = \g_gds_secname_tl,
          secname .default:n = \g_gds_name_tl,
          }

          \keys_set:nn { gdsfamily } { name , secname }

          \NewDocumentCommand { \setnames } { m }
          {
          \keys_set:nn { gdsfamily } { #1 }
          }

          \NewDocumentCommand { \getname } { m }
          {
          \tl_use:c { g_gds_#1_tl }
          }
          \ExplSyntaxOff

          \begin{document}
          Se non si impostano le chiavi esse prendono il valore di default: Il nome è il seguente: \getname{name}, il secondo nome è \getname{secname}.

          \setnames{ name = Pluto }

          Adesso, il nome è \getname{name}, e la chiave dovrebbe essere con lo stesso valore che è appunto: \getname{secname}.

          \setnames{secname = Mitico Pippo}
          Dopo aver assegnato anche la chiave del secondo nome lo stampiamo: \getname{secname} (il nome principale è rimasto a \getname{name}).

          \setnames{name = Topolino}
          Se a questo punto modifichiamo anche il primo nome avremo: nome = \getname{name}, secondo nome = \getname{secname}.
          \end{document}
          `

          Alla prossima3.
          Ciao e grazie.
          R.[/quote]
          Se non imposti il valore di una chiave, non riceverà mai un valore. Se vuoi che, di default, la tua chiave [tt]secname[/tt] abbia come valore il contenuto della variabile [tt]\g_gds_name_tl[/tt] allora usa [tt].default:n=\g_gds_name_tl[/tt] e, come hai fatto nell’ultimo codice, imposta entrambe per avere un valore iniziale.

          Ciao
          Enrico

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


            Speriamo di non avere problemi di espansione.
            Credo di no perché l’uso previsto è quello mostrato e non dovrebbero esserci situazioni nidificate.

            Inoltre stavo ragionando su due punti:
            1 – forse non vale la pena di usare le proprietà come array associativo (nel contesto di un post precedente).
            2 – se si decidesse di cambiare il codice usando al posto di una variabile proprietà un meccanismo più semplice, come fatto in questo posto sfruttando i nomi delle variabili tl, l’utente non dovrebbe cambiare nulla, e questo è un bel vantaggio.

            Adesso sono impegnato nella scrittura del codice di un comando che mostrerò in un prossimo post.
            Un saluto.
            Ciao.

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

        Go to top