Loop per comporre molti file in unico documento.

  • Creatore
    Topic
  • #101218
    Up
    0
    Down
    ::


    Salve a tutti amici del forum. Dopo un lunghissimo periodo di assenza sono tornato (capirai che ve po’ fregà) anche se non ho mai smesso di essere lettore e frequentatore del forum, ma veniamo al sodo.

    Il problema è il seguente che più che risolvere, in quanto una soluzione “pezzotta” sono riuscito a trovarla già, vorrei implementare e migliorare con i vostri utilissimi commenti al fine di farci magari un bell’articolo sul mio blog. L’esigenza nasce dal fatto che ho trovato poco in rete ed anche su stackexchange le soluzioni proposte sono, a mio avviso, disumane per un utente normale: troppo complesse per me.

    Un caro amico economista che lavora con STATA si è trovato di fronte alla esigenza di dover esportare da quest’ultimo diversi dati, sotto forma di file .tex contente ciascuno una grossa tabella.

    Il punto è che ogni file che contiene la tabella, è un file con un preambolo necessario e sufficiente ad rendere pronto il file per essere compilato. Il mio amico mi ha chiesto “siccome i modelli sono tanti, ognuno dei quali con variazioni, io voglio poter esportare tutti gli output di ogni singolo modello e poi avere un master file che compilato mi restituisca un grosso PDF contenente tutte le tabelle”

    Al di là di discussioni tipografiche o sulla natura del codice LaTeX prodotto in automatico da software, questa esigenza, sopratutto nella fase iniziale in cui un modello viene stimato ed adattato un sacco di volte, è molto sentita ed in effetti mi sono messo di impegno per cercare di risolvere.

    Prendendo spunto un po’ in rete ho fatto questo pastrocchio di codice che però pare funzionare.

    `
    \documentclass{article}
    \usepackage{pgffor}
    \usepackage{standalone}

    \begin{document}

    prova:

    \foreach \i in {1, 2, …,1999} {%
    \edef\FileName{file\i}%
    \IfFileExists{\FileName}{%
    \input{\FileName}%
    } }

    \end{document}

    `

    Dove all’interno della stessa cartella devono esserci n file .tex denominati filen con n che va da 1 a 1999. Ovviamente se ce ne sono solo due con n = {1,2} il programma compila solo questi. (non si badi alle tabelle che vengono tagliate, questo penso sia facile da risolvere)

    Ho usato il pacchetto standalone per bypassare il preambolo del generico file ennesimo ed il pacchetto pgffor per abilitare la macro foreach.

    Successivamente il mio amico sulla base di questo codice ha prodotto il seguente:

    `
    \documentclass[]{article}
    \setlength{\pdfpagewidth}{8.5in} \setlength{\pdfpageheight}{11in} % Adatto pagina alla tabella (comando prodotto da STATA)
    \usepackage{rotating} % Pacchetto per ruotare le pagine
    \usepackage{pgffor} % Attiva la macro ” \foreach ”
    \usepackage{standalone} % Esclude il preambolo dei sotto-file che richiamo con “input”

    \begin{document}

    % Scrivere il nome delle Variabili Dipendenti ATTENZIONE ALLA SINTASSI!!!
    \newcommand{\TypeFE}{StateFE} % Scegliere: “StateFE” oppure “CountyFE”

    \newcommand{\TypeModel}{LRM} % Scegliere: “LRM” oppure “Poisson” oppure “NegBin”

    \foreach \i in {MURDER, RAPE, AGASSLT, ROBBERY, BURGLRY, LARCENY, MVTHEFT} {%
    \edef\FileName{Tab\TypeModel_\TypeFE_\i} % The here are necessary to eliminate any
    \IfFileExists{\FileName}{ % spurious spaces that may get inserted
    \begin{sidewaystable} % Prima di introdurre la tabella, ruoto il foglio
    \input{\FileName}
    \end{sidewaystable}
    } }

    \end{document}

    `

    Dove il nome di un generico file da includere anziché file01, file02 eccetera è dato da ” TabLRM_StateFE_BURGLRY.tex ” perché per riconoscere tutti gli output in effetti può essere più comodo e sopratutto per rinominare il modello in base al reato (in questo caso BURGLRY) eccetera.

    Ovviamente il generico (o i generici) file da includere potrebbero essere come quelli prodotti da STATA e cioè complesse tabelle, ma anche un semplice:

    `
    \documentclass{minmal}
    begin{document}
    Prova di \LaTeX.
    \end{document}
    `

    A questo punto vorrei le vostre opinioni. Alcune cose non mi sono chiare. Ad esempio l’uso che il mio amico ha fatto del comando \newcommand{\TypeFE}{StateFE} ad esempio è banale e di fatto il loop gira e produce l’output ma non so se è una trovata geniale del mio amico o semplicemente perché non aveva idea di cosa sia un \newcommand 😀 non che io sia Leslie Lamport però non avrei mai pensato di usarlo in quel modo, non mi pare corretto come codice anche se a funzionare funziona perché così facendo, con queste apposite macro, all’interno del loop i nomi dei file da comporre vengono “costruiti” secondo le convenzioni volute dal mio amico e da esso usate in STATA per nominare i modelli.

    Opinioni, consigli, problemi dubbi.

    Grazie.

Visualizzazione 5 filoni di risposte
  • Autore
    Risposte
    • #101219
      robitex
      Amministratore del forum
        Up
        0
        Down
        ::

        Otacon” post=100978Salve a tutti amici del forum. Dopo un lunghissimo periodo di assenza sono tornato (capirai che ve po’ fregà) anche se non ho mai smesso di essere lettore e frequentatore del forum, ma veniamo al sodo.

        Il problema è il seguente che più che risolvere, in quanto una soluzione “pezzotta” sono riuscito a trovarla già, vorrei implementare e migliorare con i vostri utilissimi commenti al fine di farci magari un bell’articolo sul mio blog. L’esigenza nasce dal fatto che ho trovato poco in rete ed anche su stackexchange le soluzioni proposte sono, a mio avviso, disumane per un utente normale: troppo complesse per me.

        Un caro amico economista che lavora con STATA si è trovato di fronte alla esigenza di dover esportare da quest’ultimo diversi dati, sotto forma di file .tex contente ciascuno una grossa tabella.

        Il punto è che ogni file che contiene la tabella, è un file con un preambolo necessario e sufficiente ad rendere pronto il file per essere compilato. Il mio amico mi ha chiesto “siccome i modelli sono tanti, ognuno dei quali con variazioni, io voglio poter esportare tutti gli output di ogni singolo modello e poi avere un master file che compilato mi restituisca un grosso PDF contenente tutte le tabelle”

        Al di là di discussioni tipografiche o sulla natura del codice LaTeX prodotto in automatico da software, questa esigenza, sopratutto nella fase iniziale in cui un modello viene stimato ed adattato un sacco di volte, è molto sentita ed in effetti mi sono messo di impegno per cercare di risolvere.

        Prendendo spunto un po’ in rete ho fatto questo pastrocchio di codice che però pare funzionare.

        `
        \documentclass{article}
        \usepackage{pgffor}
        \usepackage{standalone}

        \begin{document}

        prova:

        \foreach \i in {1, 2, …,1999} {%
        \edef\FileName{file\i}%
        \IfFileExists{\FileName}{%
        \input{\FileName}%
        } }

        \end{document}

        `

        Dove all’interno della stessa cartella devono esserci n file .tex denominati filen con n che va da 1 a 1999. Ovviamente se ce ne sono solo due con n = {1,2} il programma compila solo questi. (non si badi alle tabelle che vengono tagliate, questo penso sia facile da risolvere)

        Ho usato il pacchetto standalone per bypassare il preambolo del generico file ennesimo ed il pacchetto pgffor per abilitare la macro foreach.

        Successivamente il mio amico sulla base di questo codice ha prodotto il seguente:

        `
        \documentclass[]{article}
        \setlength{\pdfpagewidth}{8.5in} \setlength{\pdfpageheight}{11in} % Adatto pagina alla tabella (comando prodotto da STATA)
        \usepackage{rotating} % Pacchetto per ruotare le pagine
        \usepackage{pgffor} % Attiva la macro ” \foreach ”
        \usepackage{standalone} % Esclude il preambolo dei sotto-file che richiamo con “input”

        \begin{document}

        % Scrivere il nome delle Variabili Dipendenti ATTENZIONE ALLA SINTASSI!!!
        \newcommand{\TypeFE}{StateFE} % Scegliere: “StateFE” oppure “CountyFE”

        \newcommand{\TypeModel}{LRM} % Scegliere: “LRM” oppure “Poisson” oppure “NegBin”

        \foreach \i in {MURDER, RAPE, AGASSLT, ROBBERY, BURGLRY, LARCENY, MVTHEFT} {%
        \edef\FileName{Tab\TypeModel_\TypeFE_\i} % The here are necessary to eliminate any
        \IfFileExists{\FileName}{ % spurious spaces that may get inserted
        \begin{sidewaystable} % Prima di introdurre la tabella, ruoto il foglio
        \input{\FileName}
        \end{sidewaystable}
        } }

        \end{document}

        `

        Dove il nome di un generico file da includere anziché file01, file02 eccetera è dato da ” TabLRM_StateFE_BURGLRY.tex ” perché per riconoscere tutti gli output in effetti può essere più comodo e sopratutto per rinominare il modello in base al reato (in questo caso BURGLRY) eccetera.

        Ovviamente il generico (o i generici) file da includere potrebbero essere come quelli prodotti da STATA e cioè complesse tabelle, ma anche un semplice:

        `
        \documentclass{minmal}
        begin{document}
        Prova di \LaTeX.
        \end{document}
        `

        A questo punto vorrei le vostre opinioni. Alcune cose non mi sono chiare. Ad esempio l’uso che il mio amico ha fatto del comando \newcommand{\TypeFE}{StateFE} ad esempio è banale e di fatto il loop gira e produce l’output ma non so se è una trovata geniale del mio amico o semplicemente perché non aveva idea di cosa sia un \newcommand 😀 non che io sia Leslie Lamport però non avrei mai pensato di usarlo in quel modo, non mi pare corretto come codice anche se a funzionare funziona perché così facendo, con queste apposite macro, all’interno del loop i nomi dei file da comporre vengono “costruiti” secondo le convenzioni volute dal mio amico e da esso usate in STATA per nominare i modelli.

        Opinioni, consigli, problemi dubbi.

        Grazie.

        Ciao.
        L’uso di \newcommand è corretto perché è inteso come un segnaposto (anche se poi usato una volta sola).
        Ho dei dubbi sul formato di pagina perché si agisce su primitive e non si utilizza il pacchetto geometry. Poi si usa ruotare la tabella invece che la pagina.
        Per il problema centrale, quello di richiamare più file mi sembra che l’uso di \foreach sia inutile perché devo comunque digitare le parti finali dei nomi dei file.
        Per questo userei una macro in Lua con il formato LuaLaTeX. La macro cercherebbe tutti i file presenti nella cartella e li includerebbe in automatico.
        In questo modo non devo più cambiare il main che di fatto dipende solamente dai file presenti nella cartella.

        In pratica in una cartella separata basterebbe copiare i “file tabella” da includere e ricompilare il main.
        Così:
        1 cancello tutti i precedenti file tabella
        2 copio quelli corretti
        3 compilo il main

        Oppure, ancora meglio, basterebbe includere nel nome del sorgente la cartella contenente i file tabella da includere.
        Saluti.
        R.

      • #101220
        Up
        0
        Down
        ::


        Grazie per la risposta.

        L’uso di newcommand come segnato, non l’ho capito. Puoi essere più chiaro su cosa intendi con “segnaposto”? ho l’impressione di perdermi in un bicchiere d’acqua ma davvero non ho ben chiaro cosa intendi.

        Si, sulla tabella avevo già parlato col mio amico. Su questi dettagli io non mi soffermerei però per ora, voglio concentrarmi sul nucleo del problema ossia: automatizzare la compilazione di un documento composto a sua volta da molti documenti ogni compilabile stand alone.

        Sulla parte finale del nome da digitare, col codice che ho fornito non c’è bisogno perché di fatto quel \i viene di volta in volta sostituito con uno degli elementi che ci sono in

        \foreach \i in {MURDER, RAPE, AGASSLT, ROBBERY, BURGLRY, LARCENY, MVTHEFT}

        Di fatto mi funziona in effetti.

        Per quanto riguarda Lua a stento so di cosa si tratta 😀 ma in effetti una soluzione praticabile e non una idea di come fare in via teorica non c’è, almeno da quello che mi dici tu.

        Se poi vogliamo parlare di soluzioni teoriche ne ho lette diverse in giro ma ovviamente come ho detto, assai difficili da realizzare per me e per un utente avanzato del PC perché magari uno può essere bravo con LaTeX o qualche linguaggio di programmazione (io un po’ me la cavo con R) ma se mi viene proposta una soluzione in C# mi pare impraticabile.

        Sempre nel mondo teorico qualche soluzione letta in giro prevede questi passaggi:

        • cerca i file .tex in una data directory
        • aggiungi i nomi ad un file in modo tale da creare un elenco con i nomi di questi
        • includi i file e compilali prendendo i nomi dal file con l’elenco creato in precedenza

        A parole ovviamente è tutto molto bello però per ora mi tengo la mia soluzione fortunosa che nonostante tutto produce il risultato desiderato.

        Speriamo questa discussione si arricchisca di altri pareri perché ripeto, secondo me non è affatto da sottovalutare quest problema.

      • #101221
        OldClaudio
        Partecipante
          Up
          0
          Down
          ::


          LA cosa non mi sembra incomprensibile`\newcommand{\TypeFE}{StateFE} % Scegliere: “StateFE” oppure “CountyFE”

          \newcommand{\TypeModel}{LRM} % Scegliere: “LRM” oppure “Poisson” oppure “NegBin”

          \foreach \i in {MURDER, RAPE, AGASSLT, ROBBERY, BURGLRY, LARCENY, MVTHEFT} {%
          \edef\FileName{Tab\TypeModel_\TypeFE_\i} % The here are necessary to eliminate any
          `anzi mi pare di una chiarezza lampante.
          I primi due statement eseguiti con \newcommand (sempre prudente usare \newcommand piuttosto che \def; non si rischia di ridefinire comandi interni di pacchetti, di classi o peggio ancora del nucleo di LaTeX, perché \def esegue la ridefinizione di brutto, mentre \newcommand verifica che il suo argomento sia definibile, quindi non esista ancora nella memoria del particolare programma che si sta eseguendo) assegnano ai due comandi il testo sotitutivo costituto da una stringa per ciascuno. quando poi si esegue il comando \edef per definire \FileNAme, si usano tre macro \TabModel, \TypeFE e \i; ciascuna viene sostituita dal suo testo sostitutivo, quindi al primo giro \TypeFE contiene la stringa StateFE, \TypeModel contiene la stringa LRM e \i contiene la stringa MURDER. la definizione sviluppata (expanded definition, \edef) agglutina le varie stringe sostitutive e le stringhe contenute nella definizione per produrre il nome del file .tex TabLRM_StateFE_MURDER; al secondo giro \i non vale più MURDER, ma RAPE, e quindi il nome di nuovo verrà ridefinito come TabLRM_StateFE_Rape; e così via di seguito finché la lista dei valori da assegnare a \i è finita.

          Non so se questo ti spieghi quello che non riuscivi a spiegarti da solo, ma il comando \newcommand non viene usato in modo strano. Può essere ingannevole il commento [tt]% Scegliere: “LRM” oppure “Poisson” oppure “NegBin”[/tt]; ma non è che \newcommand scelga quel stringa usare come testo sostitutivo; è l’utente che deve mettere al stirnga giusta a mano dentro l’argomento della definizione.

        • #101222
          Up
          0
          Down
          ::


          Si grazie ora mi è chiaro. In realtà io sapevo come funzionava, non pensavo si potesse usare un \newcommand semplicemente per far si che restituisca del semplice testo.

          Per quanto riguarda la implementazione del loop invece, visto che non arrivano soluzioni alternative o più eleganti, penso scriverò un post con quello che ho fatto fino ad ora, qualora dovessero saltare fuori altre idee le aggiungerò; speriamo.

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


            Ciao.
            Ma le idee che ti ho proposto nel post precedente sono diverse dalle tue?
            R.

          • #101224
            Up
            0
            Down
            ::


            No no sono ok, solo che sono totalmente a digiuno di Lua.

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

        Go to top