[Risolto] Definizione variabili

  • Creatore
    Topic
  • #38428
    Up
    0
    Down
    ::


    Buongiorno a tutti.
    Mi presento, sono Paolo. E’ un po’ di tempo che vi seguo nel fantastico mondo di LaTeX e finora grazie anche ai vostri messaggi sono sempre riuscito a cavarmela. Ora però sono bloccato! Il problema è il seguente: dovendo lavorare su più file che contengono variabili che si ripetono vorrei scrivere in un file un elenco di tali variabili nella forma Variabile=Valore. Poi vorrei che in fase di lettura LaTeX mi definisse un comando \Variabile da poter usare in tutti i miei file. Navigando in rete ho trovato del codice che sembra fare quello che vorrei, ma non riesco a compilare (uso MiKTeX 2.8 e pdflatex). Il codice è il seguente:
    \newcommand*\Var[1]{%
    \ifcsname Var/#1\endcsname
    \@nameuse{Var/#1}%
    \else
    \ClassError{…}{Variable `#1′ undefined}{…}%
    \fi
    }
    \def\Var@ParseLine#1=#2\@nil{%
    \@namedef{Var/#1}{#2}%
    }
    \newread\Var@InputStream
    \edef\Restore@Endlinechar{\endlinechar=\the\endlinechar\relax}
    \endlinechar\m@ne
    \openin\Var@InputStream=Variables.tex
    \loop\unless\ifeof\Var@InputStream
    \read\Var@InputStream to \Var@Line
    \expandafter\Var@ParseLine\Var@Line\@nil
    \repeat
    \closein\Var@InputStream
    \Restore@Endlinechar

    Grazie a tutti in anticipo.
    Paolo

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


      Il problema che riscontro in compilazione è dato da loop. Se cancello il ciclo il codice legge solo la prima riga del file Variables.tex e costruisce correttamente la variabile (\Var{Variabile}) restituendomi Valore quando la inserisco nel testo. L’errore che leggo nel log è:
      \@nil \relax \expandafter \iterate \fi \let \iterate \relax \closein \ETC.
      ! File ended while scanning use of \Var@ParseLine.

      Come posso risolvere?
      Buon anno a tutti.
      Paolo

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

        Buongiorno a tutti.
        Mi presento, sono Paolo. E’ un po’ di tempo che vi seguo nel fantastico mondo di LaTeX e finora grazie anche ai vostri messaggi sono sempre riuscito a cavarmela. Ora però sono bloccato! Il problema è il seguente: dovendo lavorare su più file che contengono variabili che si ripetono vorrei scrivere in un file un elenco di tali variabili nella forma Variabile=Valore. Poi vorrei che in fase di lettura LaTeX mi definisse un comando \Variabile da poter usare in tutti i miei file. Navigando in rete ho trovato del codice che sembra fare quello che vorrei, ma non riesco a compilare (uso MiKTeX 2.8 e pdflatex). Il codice è il seguente:
        \newcommand*\Var[1]{%
        \ifcsname Var/#1\endcsname
        \@nameuse{Var/#1}%
        \else
        \ClassError{…}{Variable `#1′ undefined}{…}%
        \fi
        }
        \def\Var@ParseLine#1=#2\@nil{%
        \@namedef{Var/#1}{#2}%
        }
        \newread\Var@InputStream
        \edef\Restore@Endlinechar{\endlinechar=\the\endlinechar\relax}
        \endlinechar\m@ne
        \openin\Var@InputStream=Variables.tex
        \loop\unless\ifeof\Var@InputStream
        \read\Var@InputStream to \Var@Line
        \expandafter\Var@ParseLine\Var@Line\@nil
        \repeat
        \closein\Var@InputStream
        \Restore@Endlinechar

        Grazie a tutti in anticipo.
        Paolo

        Non sono abbastanza esperto di TeX per capire cosa non funziona del codice ma mi sembra che esista una soluzione più semplice:
        `\documentclass{article}

        \usepackage[utf8]{inputenc}% cambia se sei sotto Windows o Mac
        \usepackage[T1]{fontenc}
        \usepackage[italian]{babel}

        \newcommand{\addvar}[2]{% #1 name, #2 value
        \expandafter\def\csname varmacro#1\endcsname{#2}
        }

        \newcommand{\var}[1]{%
        \csname varmacro#1\endcsname
        }

        \addvar{Pi}{3.14}
        \addvar{e}{2.71}
        \addvar{newyear}{2010}

        \begin{document}
        Valore di \( \pi=\var{Pi} \), mentre il valore di \(e\), il numero di Nepero è \var{e}.

        I comandi funzionano sia in modalità matematica sia testo.
        Auguri di Buon anno \var{newyear}!!
        \end{document}`

        Ecco come funziona: il comando \addvar{nome_variabile}{valore} crea una macro chiamata \varmacronome_variabile che viene espansa in valore.

        Quindi basta richiamare la variabile con il secondo comando \var{nome_variabile}.

        Se vuoi puoi inserire le definizioni di \addvar in un file a parte ed inserirli nel sorgente con \input{vardef_file}.

        Ciao.

      • #38431
        Up
        0
        Down
        ::


        Risolto!!
        Il problema era che il loop leggeva una volta in più del necessario, ho risolto inserendo un if che controlla se ci sono righe vuote nel file.
        Il codice, che adesso definisce un nuovo comando \Variabile leggendo dal file esterno è il seguente:
        \makeatletter
        \def\Var@ParseLine#1=#2\@nil{%
        \@namedef{#1}{#2}%
        }
        \newread\Var@InputStream
        \edef\Restore@Endlinechar{\endlinechar=\the\endlinechar\relax}
        \endlinechar\m@ne
        \openin\Var@InputStream=Variables.tex
        \count@=\z@
        \loop\unless\ifeof\Var@InputStream
        \read\Var@InputStream to \Var@Line
        \if\Var@Line\par
        \else
        \expandafter\Var@ParseLine\Var@Line\@nil
        \fi
        \repeat
        \closein\Var@InputStream
        \Restore@Endlinechar
        \makeatother

        Buon 2010 a tutti!!!

      • #38432
        Up
        0
        Down
        ::

        Risolto!!
        Il problema era che il loop leggeva una volta in più del necessario, ho risolto inserendo un if che controlla se ci sono righe vuote nel file.
        Il codice, che adesso definisce un nuovo comando \Variabile leggendo dal file esterno è il seguente:
        `\makeatletter
        \def\Var@ParseLine#1=#2\@nil{%
        \@namedef{#1}{#2}%
        }
        \newread\Var@InputStream
        \edef\Restore@Endlinechar{\endlinechar=\the\endlinechar\relax}
        \endlinechar\m@ne
        \openin\Var@InputStream=Variables.tex
        \count@=\z@
        \loop\unless\ifeof\Var@InputStream
        \read\Var@InputStream to \Var@Line
        \if\Var@Line\par
        \else
        \expandafter\Var@ParseLine\Var@Line\@nil
        \fi
        \repeat
        \closein\Var@InputStream
        \Restore@Endlinechar
        \makeatother`
        Buon 2010 a tutti!!!

        Auguri a te. Hai scoperto che ogni file che viene letto con \read ha una riga vuota implicita alla fine. Purtroppo il tuo trucco non funziona: infatti se per caso una riga è del tipo
        `XXX=21`
        il test \if\Var@Line\par risulterà vero. 🙁 Infatti \if espande ciò che segue; la macro \Var@Line, in quel caso, si espande a “XXX=21” e il test diventa
        `\if XXX=21\par`
        che è effettivamente vero, perché i primi due token non espandibili sono due X. Il test corretto è
        `\ifx\Var@Line\@empty`
        Ciao
        Enrico

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

    Go to top