Sommario fai date per capire come funziona.

  • Creatore
    Topic
  • #20520
    Up
    0
    Down
    ::


    Studiandomi un po’ il pacchetto minitoc ho pensato di creare un esempio minimale di come produrre un piccolo sommario, esempio che potrebbe essermi utile in casi molto particolari (come creare un piccolo sommario di un articolo molto lungo in una rivista.
    Ho quindi scritto il seguente codice che funziona, ma ha un piccolo difetto, non mi scrive le prime sezioni
    `
    \documentclass[a4paper]{article}
    \usepackage{lipsum}
    \makeatletter
    \newif\@test
    \@testfalse
    \def\apriscrittura{
    \IfFileExists{\jobname2.tex}{\@testtrue}{\@testfalse %\newwrite\@uscita
    \openout15=\jobname2.tex
    \relax
    \immediate\write15{\relax}
    }
    }
    \def\chiudiscrittura{
    \immediate\closeout15}
    \def\newsection#1{\section{#1}
    \if@test %\relax
    sono true\par
    \else
    sono false \par
    \immediate\write15{\hskip 7pt \thesection. #1\hfill \thepage\par}
    \fi
    }

    \makeatother
    \begin{document}
    %\leggi
    \apriscrittura
    \hrule
    \vskip 5pt
    \textsc{Table of Contents}\par
    \InputIfFileExists{\jobname2.tex}{}{}\par
    \vskip 7pt
    \hrule
    %\lipsum
    \newsection{Prova}
    \newsection{provaci}
    \lipsum
    \newsection{prova di nuovo Sam}
    \lipsum[7]
    \newsection{Ancora}
    \lipsum
    %\chiudiscrittura
    \end{document}
    `

    e il risultato nel file \jobname2.tex è
    `
    \hskip 7pt 3. prova di nuovo Sam\hfill 2\par
    \hskip 7pt 4. Ancora\hfill 2\par
    `
    Se invece decommento il primo \lipsum scrive correttamente i 4 paragrafi ma non il primo relax. Credo che sia un problema sul modo in cui apro il file, ma non ne sono sicuro.
    Ho provato a usare \newwrite\uscita, ma poi quando scrivevo \write\uscita mi dava un errore.
    Qualche suggerimento? 🙄

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

      Studiandomi un po’ il pacchetto minitoc ho pensato di creare un esempio minimale di come produrre un piccolo sommario, esempio che potrebbe essermi utile in casi molto particolari (come creare un piccolo sommario di un articolo molto lungo in una rivista.
      Ho quindi scritto il seguente codice che funziona, ma ha un piccolo difetto, non mi scrive le prime sezioni
      `\documentclass[a4paper]{article}
      \usepackage{lipsum}
      \makeatletter
      \newif\@test
      \@testfalse
      \def\apriscrittura{
      \IfFileExists{\jobname2.tex}{\@testtrue}{\@testfalse %\newwrite\@uscita
      \openout15=\jobname2.tex
      \relax
      \immediate\write15{\relax}
      }
      }
      \def\chiudiscrittura{
      \immediate\closeout15}
      \def\newsection#1{\section{#1}
      \if@test %\relax
      sono true\par
      \else
      sono false \par
      \immediate\write15{\hskip 7pt \thesection. #1\hfill \thepage\par}
      \fi
      }

      \makeatother
      \begin{document}
      %\leggi
      \apriscrittura
      \hrule
      \vskip 5pt
      \textsc{Table of Contents}\par
      \InputIfFileExists{\jobname2.tex}{}{}\par
      \vskip 7pt
      \hrule
      %\lipsum
      \newsection{Prova}
      \newsection{provaci}
      \lipsum
      \newsection{prova di nuovo Sam}
      \lipsum[7]
      \newsection{Ancora}
      \lipsum
      %\chiudiscrittura
      \end{document}
      `

      e il risultato nel file \jobname2.tex è
      `
      \hskip 7pt 3. prova di nuovo Sam\hfill 2\par
      \hskip 7pt 4. Ancora\hfill 2\par
      `
      Se invece decommento il primo \lipsum scrive correttamente i 4 paragrafi ma non il primo relax. Credo che sia un problema sul modo in cui apro il file, ma non ne sono sicuro.
      Ho provato a usare \newwrite\uscita, ma poi quando scrivevo \write\uscita mi dava un errore.
      Qualche suggerimento? 🙄

      C’è qualcosa che non va; prima di tutto è meglio se \newif è seguito da un comando che comincia con \if. Prova così:
      `\newif\if@test
      \@testfalse
      \def\apriscrittura{%
      \IfFileExists{\jobname2.tex}
      {\@testtrue}
      {\@testfalse \newwrite\@uscita
      \immediate\openout\@uscita=\jobname2.tex
      \immediate\write\@uscita{\relax}}
      }
      \def\chiudiscrittura{\if@test\else\immediate\closeout\@uscita\fi}
      \def\newsection#1{\section{#1}
      \if@test %\relax
      sono true\par
      \else
      sono false \par
      \write\@uscita{\hskip 7pt \thesection. #1\hfill \thepage\par}%
      \fi}`
      Ma così non funziona proprio: se aggiungi una sezione l’unico modo di compilare correttamente il tutto è di cancellare il file con l’indice.

      Perché non usare \tableofcontents, opportunamente modificato?

      C’è un altro errore, molto importante: il \write in cui usi \thepage non deve essere immediato, perché a quel punto TeX potrebbe non sapere qual è il numero di pagina giusto.

      Ciao
      Enrico

      (Corretto secondo quanto scritto nel mio messaggio successivo)

    • #20522
      Up
      0
      Down
      ::


      Diciamo che la prova è più accademica visto che per il momento non mi serve. Mi rendo conto che è necessario compilare due volte e cancellare il file ogni volta, ma questo è un problema che volevo pormi successivamente.
      Tableofcontents non lo posso usare perché si occupa già di creare l’indice globale di tutti gli articoli presenti. L’uso di queste macro mi servirebbe teoricamente per creare un sommario ad esempio in una review molto lunga, che compare insieme ad altri articoli che invece non necessitano di questo minisommario.
      La prova con \newwrite funziona, ma il risultato è sempre lo stesso come se ci fosse qualcosa che inibisce la scrittura e l’uso di lipsum sblocchi la cosa…

      Se spulcio il file log ritrovo le prime tre righe nel log file, come se il valore passato a \write fosse maggiore di 15. strano perché il log riporta \@uscita=\write3
      [edit]
      Ho risolto. Tutto è imposto da \immediate che costringe il comando a essere svolto immediatamente. Tranne che su \openout, che viene eseguito al momento dello shipout. Quindi i capitoli che compaiono sulla prima pagina non possono essere scritti perché non si sa dove scriverli…

    • #20523
      Up
      0
      Down
      ::

      Diciamo che la prova è più accademica visto che per il momento non mi serve. Mi rendo conto che è necessario compilare due volte e cancellare il file ogni volta, ma questo è un problema che volevo pormi successivamente.
      Tableofcontents non lo posso usare perché si occupa già di creare l’indice globale di tutti gli articoli presenti. L’uso di queste macro mi servirebbe teoricamente per creare un sommario ad esempio in una review molto lunga, che compare insieme ad altri articoli che invece non necessitano di questo minisommario.
      La prova con \newwrite funziona, ma il risultato è sempre lo stesso come se ci fosse qualcosa che inibisce la scrittura e l’uso di lipsum sblocchi la cosa…

      Se spulcio il file log ritrovo le prime tre righe nel log file, come se il valore passato a \write fosse maggiore di 15. strano perché il log riporta \@uscita=\write3
      [edit]
      Ho risolto. Tutto è imposto da \immediate che costringe il comando a essere svolto immediatamente. Tranne che su \openout, che viene eseguito al momento dello shipout. Quindi i capitoli che compaiono sulla prima pagina non possono essere scritti perché non si sa dove scriverli…

      C’era qualcosa che non mi tornava! Devi mettere \immediate prima di \openout; altrimenti l’apertura del file avviene dopo la prima chiamata della routine di output (cioè dopo che è stata composta la prima pagina).

      Ciao
      Enrico

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

Go to top