plain: \write e \output. Comportamento incomprensibile

  • Creatore
    Topic
  • #81128
    Up
    0
    Down
    ::


    Incomprensibile per me, ovviamente.

    La mia intenzione è di salvare in un file il numero di pagine di un documento, per poi usare quel dato durante una seconda compilazione.
    Sembra semplice, il codice minimo è il seguente:
    `\input plipsum

    \newtoks\everypage
    \output{\the\everypage\plainoutput}

    \everypage{\savepageno}

    \newwrite\pagesfile
    \def\savepageno{\openout\pagesfile=\jobname.aux%
    \write\pagesfile{\noexpand\def\string\lastpage{\the\pageno}}%
    \closeout\pagesfile}

    \lipsum 1,21
    \bye`

    Pur non sembrando che ci siano chiamate ricorsive, il codice ha un comportamento ricorsivo, nel senso che emette pagine senza fermarsi mai.

    Dov’è l’errore?

    Grazie, ciao.

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

      Sam Qasbah” post=80357Incomprensibile per me, ovviamente.

      La mia intenzione è di salvare in un file il numero di pagine di un documento, per poi usare quel dato durante una seconda compilazione.
      Sembra semplice, il codice minimo è il seguente:
      `\input plipsum

      \newtoks\everypage
      \output{\the\everypage\plainoutput}

      \everypage{\savepageno}

      \newwrite\pagesfile
      \def\savepageno{\openout\pagesfile=\jobname.aux%
      \write\pagesfile{\noexpand\def\string\lastpage{\the\pageno}}%
      \closeout\pagesfile}

      \lipsum 1,21
      \bye`

      Pur non sembrando che ci siano chiamate ricorsive, il codice ha un comportamento ricorsivo, nel senso che emette pagine senza fermarsi mai.

      Dov’è l’errore?

      Grazie, ciao.

      Commetti vari errori. Non c’è nessun bisogno di usare un registro token: basterebbe
      `\output{\savepage\plainoutput}`
      se non fosse che [tt]\savepage[/tt] riscrive ogni volta il file ausiliario. Immagino che a te serva solo una registrazione, con l’ultimo numero di pagina. Non mi pare proprio il modo migliore di procedere.

      `\input plipsum

      \outer\def\bye{\par\vfill\supereject\savepageno\end}

      \newwrite\pagesfile
      \def\savepageno{\immediate\openout\pagesfile=\jobname.aux
      \immediate\write\pagesfile{\def\string\lastpage{\the\numexpr\pageno-1\relax}}%
      \immediate\closeout\pagesfile}

      \lipsum 1,21
      \bye`
      Siccome chiamiamo il comando proprio alla fine, il numero di pagina sarà quello corretto più uno, perché l’ultima routine di output è già stata eseguita.

      Se non vuoi usare comandi e-TeX, non è un problema: lasci solo [tt]\pageno[/tt] e poi nel codice che usi per stampare il numero dell’ultima pagina aggiungi qualche trucco aritmetico per tornare indietro di uno.

      Ciao
      Enrico

    • #81130
      Up
      0
      Down
      ::

      egreg9″ post=80358
      `\input plipsum

      \outer\def\bye{\par\vfill\supereject\savepageno\end}

      \newwrite\pagesfile
      \def\savepageno{\immediate\openout\pagesfile=\jobname.aux
      \immediate\write\pagesfile{\def\string\lastpage{\the\numexpr\pageno-1\relax}}%
      \immediate\closeout\pagesfile}

      \lipsum 1,21
      \bye`

      Ciao
      Enrico

      Bella idea.

      Un dubbio di teoria: come mai è possibile scrivere
      ` \write0{\def\string\something …`
      invece di
      `\write0{\noexpand\def\string\something …`
      ?

      Non ho trovato una simile possibilità nè nel TTB nè nell’Advanced TeXbook.

      Grazie, ciao.

    • #81131
      Up
      0
      Down
      ::

      Sam Qasbah” post=80359Un dubbio di teoria: come mai è possibile scrivere
      ` \write0{\def\string\something …`
      invece di
      `\write0{\noexpand\def\string\something …`
      ?

      Non ho trovato una simile possibilità nè nel TTB nè nell’Advanced TeXbook.

      [tt]\def[/tt] non è espandibile. L’istruzione [tt]\write[/tt] funziona come [tt]\edef[/tt], cioè espande tutto ciò che è espandibile, fino a quando rimangono solo token non espandibili che non vengono toccati. Quando un token è preceduto da [tt]\noexpand[/tt] funziona esattamente allo stesso modo: l’espansione di [tt]\noexpand[/tt] assorbe il token successivo che viene rimesso nell’input ma reso non espandibile. Perciò [tt]\noexpand\def[/tt] fa solo un po’ di lavoro per niente.

      Ciao
      Enrico

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

Go to top