uso del pacchetto environ

  • Creatore
    Topic
  • #113537
    Up
    0
    Down
    ::


    Ciao a tutti, sto provando ad utilizzare il pacchetto environ che permette di definire ambienti con la sintassi
    `\NewEnviron{}{}`
    in particolare perché questo mi permette di utilizzare il comando `\BODY` per inserirlo in un “copia e incolla” definito con:
    `\makeatletter
    \def\set#1#2{\global\@namedef{namespacekey@#1}{#2}}
    \def\get#1{%
    \@ifundefined{namespacekey@#1}
    {%CASO INDEFINITO
    ~}
    {\@nameuse{namespacekey@#1}}%
    }
    \makeatother
    % \set{#1}{#2} \get{#1}: stampa #2`
    ma purtroppo non risco ad utilizzare fuori dall’ambiente stesso il comando che ho “inizializzato” all’interno, e io avrei bisogno invece di poterlo fare. Codice minimo di esempio (non funzionante, se si commenta l’ultima riga funziona):
    `\documentclass[12pt,a4paper]{article}
    \usepackage[utf8]{inputenc}

    \usepackage{environ}

    \makeatletter
    \def\set#1#2{\global\@namedef{namespacekey@#1}{#2}}
    \def\get#1{%
    \@ifundefined{namespacekey@#1}
    {%CASO INDEFINITO
    ~}
    {\@nameuse{namespacekey@#1}}%
    }
    \makeatother
    % \set{#1}{#2} \get{#1}: stampa #2

    \NewEnviron{prova}{
    Testo a caso:~\BODY
    \set{random}{\BODY}
    \par Il set è inizializzato su: \get{random}
    }

    \begin{document}

    \begin{prova}
    ciao
    \end{prova}
    \par
    \set{hi}{hallo}
    \get{hi}
    %commentando o decommentando il file compilerà o meno
    \par Il set è inizializzato su: \get{random}

    \end{document}`
    Qualcuno ha qualche suggerimento? Grazie!

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


      La ragione del malfunzionamento è chiara: tu memorizzi nella variabile [tt]random[/tt] non l’espansione della macro [tt]\BODY[/tt] (espansione che, al momento in cui [tt]\set{random}{…}[/tt] viene eseguito, coincide effettivamente con il contenuto dell’ambiente, come dimostra il primo controllo «Il set è inizializzato su…», quello eseguito dentro l’ambiente stesso), bensì un mero riferimento al nome della macro [tt]\BODY[/tt]; pertanto, quando esegui [tt]\get{random}[/tt] fuori dall’ambiente, TeX tenterà di espandere nuovamente una macro di nome [tt]\BODY[/tt], la quale però, a quel punto, non risulterà più definita.

      Potresti provare a rimpiazzare
      `
      \NewEnviron{prova}{
      Testo a caso:~\BODY
      \set{random}{\BODY}
      \par Il set è inizializzato su: \get{random}
      }
      `
      con
      `
      \NewEnviron{prova}{
      Testo a caso:~\BODY
      \xset{random}{\BODY}
      \par Il set è inizializzato su: \get{random}
      }
      `
      dopo aver definito
      `
      \newcommand\xset[2]{%
      \expandafter\xdef \csname namespacekey@#1\endcsname {#2}%
      }
      `
      Il comando [tt]\xset[/tt] espande completamente il suo secondo argomento prima di memorizzarlo nella variabile individuata dal primo; nota bene, tuttavia, che questa espansione completa può, a sua volta, causare altri guai anche grossi: il fatto che sia o no una soluzione adeguata dipende dal problema reale che devi risolvere nella tua particolare applicazione. Potrebbe, per esempio, essere necessaria — o, semplicemente, più appropriata — un’espansione di un solo livello.

      Ciao.


      Gustavo

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

Go to top