Funzioni LaTeX3 annidate

  • Creatore
    Topic
  • #85784
    Up
    0
    Down
    ::


    Ciao a tutti, mi sono imbattuto in un problema riguardante l’utilizzo di funzioni LaTeX annidate.

    Una sezione di un mio documento riporta un elenco progressivo di delibere (numero, soggetto deliberante e descrizione); ho pensato di generalizzare la composizione di questo elenco attraverso la definizione di un ambiente (McsDelibere). Siccome si tratta sostanzialmente di una tabella, ho pensato di riutilizzare una tabella generica già precedente costruita (McsTabGen). Ora, quando uso la tabella da sola, tutto bene. Quando la uso nell’ambiente McsDelibere, nella tabella confluiscono solo gli ultimi valori forniti.

    Il codice di seguito (ridotto all’osso) evidenzia il problema: la seconda tabella (quella dell’ambiente McsDelibere) replica per ogni riga i valori dell’ultima riga:
    `
    \documentclass{book}
    \usepackage[utf8]{inputenc}
    \usepackage[italian]{babel}
    \usepackage{calc}
    \usepackage{booktabs}
    \usepackage{xparse}
    \usepackage{lipsum}

    \newcommand\McsTcw[1]{#1\textwidth-2\tabcolsep}

    \ExplSyntaxOn
    %
    % Tabella generica
    %
    \keys_define:nn { McsTabDefs } {%
    testata .tl_set:N = \l_McsTab_Testata_tl,
    col1 .tl_set:N = \l_McsTab_HColA_tl,
    col2 .tl_set:N = \l_McsTab_HColB_tl,
    col3 .tl_set:N = \l_McsTab_HColC_tl,
    dim1 .tl_set:N = \l_McsTab_DimColA_tl,
    dim2 .tl_set:N = \l_McsTab_DimColB_tl,
    dim3 .tl_set:N = \l_McsTab_DimColC_tl,
    }
    \tl_new:N \l_McsTab_TabContens_tl
    \NewDocumentEnvironment{ McsTabGen } { m } {%
    \keys_set:nn { McsTabDefs } { #1 }
    \begin{center}
    \small
    \tl_put_right:No \l_McsTab_TabContens_tl {%
    \begin{tabular} { p{ \l_McsTab_DimColA_tl } p{ \l_McsTab_DimColB_tl } p{ \l_McsTab_DimColC_tl } }
    }
    \tl_put_right:Nn \l_McsTab_TabContens_tl {%
    \toprule
    \multicolumn{3}{c}{\l_McsTab_Testata_tl} \\ \midrule
    \l_McsTab_HColA_tl &
    \l_McsTab_HColB_tl &
    \l_McsTab_HColC_tl \\
    }
    }{
    \tl_use:N \l_McsTab_TabContens_tl
    \bottomrule
    \end{tabular}
    \end{center}
    }
    \NewDocumentCommand{\McsRigaTabGen} { mmm } {%
    \tl_put_right:Nn \l_McsTab_TabContens_tl { \midrule #1 & #2 & #3 \\ }
    }

    \keys_define:nn { McsDeliberaDefs } {%
    deliberante .tl_set:N = \l_McsDel_Deliberante_tl,
    descrdelibera .tl_set:N = \l_McsDel_DescrDelibera_tl,
    }
    \int_new:N \l_McsDel_NumDel_tl
    \NewDocumentCommand{\McsStartDelibere} {} {\int_set:Nn \l_McsDel_NumDel_tl { 1 }}
    \NewDocumentCommand{\McsRigaDelibera} { m } {%
    \keys_set:nn { McsDeliberaDefs } { #1 }
    \McsRigaTabGen
    {\int_use:N \l_McsDel_NumDel_tl}
    {\l_McsDel_Deliberante_tl}
    {\l_McsDel_DescrDelibera_tl}
    \int_incr:N \l_McsDel_NumDel_tl
    }
    \ExplSyntaxOff

    %
    % Ambiente per tabella delibere
    %
    \newenvironment{McsDelibere}{%
    Di seguito vengono elencate le delibere e/o assunzioni relative ai procedimenti attivati.
    \McsStartDelibere
    \begin{McsTabGen} {
    testata=Delibere e/o assunzioni,
    col1=M., dim1=\McsTcw{.1},
    col2=Proponente, dim2=\McsTcw{.3},
    col3=Descr., dim3=\McsTcw{.6}
    }
    }
    { \end{McsTabGen} }

    \begin{document}
    \lipsum[4]
    \begin{McsTabGen} {
    testata=Delibere e/o assunzioni,
    col1=N., dim1=\McsTcw{.05},
    col2=Deliberante, dim2=\McsTcw{.2},
    col3=Descrizione, dim3=\McsTcw{.75} }
    \McsRigaTabGen{1}{Consiglio di Gestione}{\lipsum[2]}
    \McsRigaTabGen{2}{Consiglio di Sorveglianza}{\lipsum[3]}
    \McsRigaTabGen{3}{Consiglio di Amministrazione}{\lipsum[4]}
    \end{McsTabGen}
    \lipsum[5]
    \begin{McsDelibere}
    \McsRigaDelibera{ deliberante=Consiglio di Gestione, descrdelibera=\lipsum[2] }
    \McsRigaDelibera{ deliberante=Consiglio di Sorveglianza, descrdelibera=\lipsum[3] }
    \McsRigaDelibera{ deliberante=Consiglio di Amministrazione, descrdelibera=\lipsum[4] }
    \end{McsDelibere}
    \end{document}
    `
    Qualcuno sa darmi una dritta?

    Grazie

    a

Visualizzazione 2 filoni di risposte
  • Autore
    Risposte
    • #85785
      Up
      0
      Down
      ::

      Amedeo” post=85215Ciao a tutti, mi sono imbattuto in un problema riguardante l’utilizzo di funzioni LaTeX annidate.

      Una sezione di un mio documento riporta un elenco progressivo di delibere (numero, soggetto deliberante e descrizione); ho pensato di generalizzare la composizione di questo elenco attraverso la definizione di un ambiente (McsDelibere). Siccome si tratta sostanzialmente di una tabella, ho pensato di riutilizzare una tabella generica già precedente costruita (McsTabGen). Ora, quando uso la tabella da sola, tutto bene. Quando la uso nell’ambiente McsDelibere, nella tabella confluiscono solo gli ultimi valori forniti.

      Il codice di seguito (ridotto all’osso) evidenzia il problema: la seconda tabella (quella dell’ambiente McsDelibere) replica per ogni riga i valori dell’ultima riga:
      `
      \documentclass{book}
      \usepackage[utf8]{inputenc}
      \usepackage[italian]{babel}
      \usepackage{calc}
      \usepackage{booktabs}
      \usepackage{xparse}
      \usepackage{lipsum}

      \newcommand\McsTcw[1]{#1\textwidth-2\tabcolsep}

      \ExplSyntaxOn
      %
      % Tabella generica
      %
      \keys_define:nn { McsTabDefs } {%
      testata .tl_set:N = \l_McsTab_Testata_tl,
      col1 .tl_set:N = \l_McsTab_HColA_tl,
      col2 .tl_set:N = \l_McsTab_HColB_tl,
      col3 .tl_set:N = \l_McsTab_HColC_tl,
      dim1 .tl_set:N = \l_McsTab_DimColA_tl,
      dim2 .tl_set:N = \l_McsTab_DimColB_tl,
      dim3 .tl_set:N = \l_McsTab_DimColC_tl,
      }
      \tl_new:N \l_McsTab_TabContens_tl
      \NewDocumentEnvironment{ McsTabGen } { m } {%
      \keys_set:nn { McsTabDefs } { #1 }
      \begin{center}
      \small
      \tl_put_right:No \l_McsTab_TabContens_tl {%
      \begin{tabular} { p{ \l_McsTab_DimColA_tl } p{ \l_McsTab_DimColB_tl } p{ \l_McsTab_DimColC_tl } }
      }
      \tl_put_right:Nn \l_McsTab_TabContens_tl {%
      \toprule
      \multicolumn{3}{c}{\l_McsTab_Testata_tl} \\ \midrule
      \l_McsTab_HColA_tl &
      \l_McsTab_HColB_tl &
      \l_McsTab_HColC_tl \\
      }
      }{
      \tl_use:N \l_McsTab_TabContens_tl
      \bottomrule
      \end{tabular}
      \end{center}
      }
      \NewDocumentCommand{\McsRigaTabGen} { mmm } {%
      \tl_put_right:Nn \l_McsTab_TabContens_tl { \midrule #1 & #2 & #3 \\ }
      }

      \keys_define:nn { McsDeliberaDefs } {%
      deliberante .tl_set:N = \l_McsDel_Deliberante_tl,
      descrdelibera .tl_set:N = \l_McsDel_DescrDelibera_tl,
      }
      \int_new:N \l_McsDel_NumDel_tl
      \NewDocumentCommand{\McsStartDelibere} {} {\int_set:Nn \l_McsDel_NumDel_tl { 1 }}
      \NewDocumentCommand{\McsRigaDelibera} { m } {%
      \keys_set:nn { McsDeliberaDefs } { #1 }
      \McsRigaTabGen
      {\int_use:N \l_McsDel_NumDel_tl}
      {\l_McsDel_Deliberante_tl}
      {\l_McsDel_DescrDelibera_tl}
      \int_incr:N \l_McsDel_NumDel_tl
      }
      \ExplSyntaxOff

      %
      % Ambiente per tabella delibere
      %
      \newenvironment{McsDelibere}{%
      Di seguito vengono elencate le delibere e/o assunzioni relative ai procedimenti attivati.
      \McsStartDelibere
      \begin{McsTabGen} {
      testata=Delibere e/o assunzioni,
      col1=M., dim1=\McsTcw{.1},
      col2=Proponente, dim2=\McsTcw{.3},
      col3=Descr., dim3=\McsTcw{.6}
      }
      }
      { \end{McsTabGen} }

      \begin{document}
      \lipsum[4]
      \begin{McsTabGen} {
      testata=Delibere e/o assunzioni,
      col1=N., dim1=\McsTcw{.05},
      col2=Deliberante, dim2=\McsTcw{.2},
      col3=Descrizione, dim3=\McsTcw{.75} }
      \McsRigaTabGen{1}{Consiglio di Gestione}{\lipsum[2]}
      \McsRigaTabGen{2}{Consiglio di Sorveglianza}{\lipsum[3]}
      \McsRigaTabGen{3}{Consiglio di Amministrazione}{\lipsum[4]}
      \end{McsTabGen}
      \lipsum[5]
      \begin{McsDelibere}
      \McsRigaDelibera{ deliberante=Consiglio di Gestione, descrdelibera=\lipsum[2] }
      \McsRigaDelibera{ deliberante=Consiglio di Sorveglianza, descrdelibera=\lipsum[3] }
      \McsRigaDelibera{ deliberante=Consiglio di Amministrazione, descrdelibera=\lipsum[4] }
      \end{McsDelibere}
      \end{document}
      `
      Qualcuno sa darmi una dritta?

      Grazie

      a

      L’errore è che quando esegui [tt]\McsRigaDelibera[/tt] sei già in una cella di tabella e quindi le assegnazioni locali spariscono. Devi usare assegnazioni globali. Ho fatto anche altre correzioni.
      `\documentclass{book}
      \usepackage[utf8]{inputenc}
      \usepackage[italian]{babel}
      \usepackage{calc}
      \usepackage{booktabs}
      \usepackage{xparse}
      \usepackage{lipsum}

      \newcommand\McsTcw[1]{#1\textwidth-2\tabcolsep}

      \ExplSyntaxOn
      %
      % Tabella generica
      %
      \keys_define:nn { McsTabDefs }
      {
      testata .tl_set:N = \l_McsTab_Testata_tl,
      col1 .tl_set:N = \l_McsTab_HColA_tl,
      col2 .tl_set:N = \l_McsTab_HColB_tl,
      col3 .tl_set:N = \l_McsTab_HColC_tl,
      dim1 .tl_set:N = \l_McsTab_DimColA_tl,
      dim2 .tl_set:N = \l_McsTab_DimColB_tl,
      dim3 .tl_set:N = \l_McsTab_DimColC_tl,
      }
      \tl_new:N \l_McsTab_TabContens_tl
      \NewDocumentEnvironment{ McsTabGen } { m }
      {
      \keys_set:nn { McsTabDefs } { #1 }
      \begin{center}
      \small
      \tl_put_right:Nn \l_McsTab_TabContens_tl
      {
      \begin{tabular}
      {
      p{ \l_McsTab_DimColA_tl }
      p{ \l_McsTab_DimColB_tl }
      p{ \l_McsTab_DimColC_tl }
      }
      \toprule
      \multicolumn{3}{c}{\l_McsTab_Testata_tl} \\ \midrule
      \l_McsTab_HColA_tl &
      \l_McsTab_HColB_tl &
      \l_McsTab_HColC_tl \\
      }
      } % end of “start”
      {
      \tl_use:N \l_McsTab_TabContens_tl
      \bottomrule
      \end{tabular}
      \end{center}
      } % end of “end”

      \NewDocumentCommand{\McsRigaTabGen} { mmm }
      {
      \tl_put_right:Nn \l_McsTab_TabContens_tl { \midrule #1 & #2 & #3 \\ }
      }

      \keys_define:nn { McsDeliberaDefs }
      {
      deliberante .tl_gset:N = \g_McsDel_Deliberante_tl,
      descrdelibera .tl_gset:N = \g_McsDel_DescrDelibera_tl,
      }
      \int_new:N \g_McsDel_NumDel_int
      \NewDocumentCommand{\McsStartDelibere} {} {\int_gset:Nn \g_McsDel_NumDel_int { 1 }}
      \NewDocumentCommand{\McsRigaDelibera} { m }
      {
      \keys_set:nn { McsDeliberaDefs } { #1 }
      \McsRigaTabGen {\int_use:N \g_McsDel_NumDel_int}
      {\g_McsDel_Deliberante_tl}
      {\g_McsDel_DescrDelibera_tl}
      \int_gincr:N \g_McsDel_NumDel_int
      }
      \ExplSyntaxOff

      %
      % Ambiente per tabella delibere
      %
      \newenvironment{McsDelibere}
      {%
      Di seguito vengono elencate le delibere e/o assunzioni relative ai procedimenti attivati.
      \McsStartDelibere
      \begin{McsTabGen} {
      testata=Delibere e/o assunzioni,
      col1=M., dim1=\McsTcw{.1},
      col2=Proponente, dim2=\McsTcw{.3},
      col3=Descr., dim3=\McsTcw{.6}
      }
      }
      { \end{McsTabGen} }

      \begin{document}
      \lipsum[4]
      \begin{McsTabGen} {
      testata=Delibere e/o assunzioni,
      col1=N., dim1=\McsTcw{.05},
      col2=Deliberante, dim2=\McsTcw{.2},
      col3=Descrizione, dim3=\McsTcw{.75} }
      \McsRigaTabGen{1}{Consiglio di Gestione}{\lipsum[2]}
      \McsRigaTabGen{2}{Consiglio di Sorveglianza}{\lipsum[3]}
      \McsRigaTabGen{3}{Consiglio di Amministrazione}{\lipsum[4]}
      \end{McsTabGen}
      \lipsum[5]
      \begin{McsDelibere}
      \McsRigaDelibera{ deliberante=Consiglio di Gestione, descrdelibera=\lipsum[2] }
      \McsRigaDelibera{ deliberante=Consiglio di Sorveglianza, descrdelibera=\lipsum[3] }
      \McsRigaDelibera{ deliberante=Consiglio di Amministrazione, descrdelibera=\lipsum[4] }
      \end{McsDelibere}
      \end{document}`
      Ciao
      Enrico

    • #85786
      Up
      0
      Down
      ::


      Uhm… mi potrei accontentare della tua risposta ma se non capisco il perchè, rischio nuove empasse e nuove domande. Tu mi dici che “le assegnazioni locali spariscono”, ma locali a cosa? Le variabili di McsDeliberaDefs e McsTabDefs sono diverse. L’effetto che ottengo è di avere celle tutte uguali all’ultima riga inserita, come se (lasciami passare l’esempio) \tl_put_right ponesse in lista il puntatore alla variabili di McsDeliberaDefs anzichè i loro valori, con il risultato che alla fine \tl_use compone una tabella in cui sono presenti gli ultimi valori forniti.

      Grazie per la pazienza

      a

    • #85787
      Up
      0
      Down
      ::

      Amedeo” post=85244Uhm… mi potrei accontentare della tua risposta ma se non capisco il perchè, rischio nuove empasse e nuove domande. Tu mi dici che “le assegnazioni locali spariscono”, ma locali a cosa? Le variabili di McsDeliberaDefs e McsTabDefs sono diverse. L’effetto che ottengo è di avere celle tutte uguali all’ultima riga inserita, come se (lasciami passare l’esempio) \tl_put_right ponesse in lista il puntatore alla variabili di McsDeliberaDefs anzichè i loro valori, con il risultato che alla fine \tl_use compone una tabella in cui sono presenti gli ultimi valori forniti.

      Grazie per la pazienza

      a

      Prova questo:
      `
      \newcommand{\foo}{FOO}
      \begin{tabular}{cc}
      \renewcommand{\foo}{BAR} X & abc \\
      \foo & def
      \end{tabular}
      `
      Se controlli, troverai che la seconda riga riporta “FOO def”. Il problema è lo stesso che nella tua domanda. Ogni cella di una tabella forma un gruppo e le assegnazioni locali perdono valore quando il gruppo finisce.

      Non ho nemmeno provato questo codice. 😉

      Ciao
      Enrico

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

Go to top