plain – espansione – una macro ben scritta (apparentemente)

  • Creatore
    Topic
  • #65416
    Up
    0
    Down
    ::


    Salve a tutti.

    Invece di accapigliarvi in dispute teoriche sulla classe memoir, dedicate qualche minuto a risolvere un problema con l’uso dell’antico linguaggio di Knuth.

    All’inizio di un pacchetto di stile, che necessita di essere usato con XeTeX, ho inserito il seguente controllo sul motore in uso:

    `
    \expandafter\ifx\csname XeTeXrevision\endcsname\relax%
    \let\@@endinput\endinput%
    \errmessage{Ahi ahi, nothing to do.}\fi%
    \csname @@endinput\endcsname%

    `

    Il meccanismo sembra non fare una grinza, eppure non funziona. Provato su TeXworks con pdfTeX il motore continua bellamente a leggere le istruzioni successive, naturalmente sollevando errori e bloccando la compilazione invece di fermarsi al \csname @@endinput\endcsname e interrompere la lettura del pacchetto.

    Dove cavolo sbaglio?

    Ciao.

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

      Sam Qasbah” post=64466Salve a tutti.

      Invece di accapigliarvi in dispute teoriche sulla classe memoir, dedicate qualche minuto a risolvere un problema con l’uso dell’antico linguaggio di Knuth.

      All’inizio di un pacchetto si stile, che necessita di essere usato con XeTeX, ho inserito il seguente controllo sul motore in uso:

      `
      \expandafter\ifx\csname XeTeXrevision\endcsname\relax%
      \let\@@endinput\endinput%
      \errmessage{Ahi ahi, nothing to do.}\fi%
      \csname @@endinput\endcsname%

      `

      Il meccanismo sembra non fare una grinza, eppure non funziona. Provato su TeXworks con pdfTeX il motore continua bellamente a leggere le istruzioni successive, naturalmente sollevando errori e bloccando la compilazione invece di fermarsi al \csname @@endinput\endcsname e interrompere la lettura del pacchetto.

      Dove cavolo sbaglio?

      Se prima non dichiari “\catcode`@=11”, stai semplicemende dicendo “\let\@=@”, che non è molto utile; e “\@@endinput” non è definito. Infatti pdftex stampa “endinput”, trova “\endinput” ed esce dal file; ti trovi un condizionale non finito.

      Il metodo corretto è
      `\expandafter\ifx\csname XeTeXrevision\endcsname\relax
      \errmessage{Ahi ahi, nothing to do.}%
      \expandafter\endinput
      \fi`
      Puoi evitare \expandafter se metti \fi subito dopo \endinput, perché TeX comunque legge tutta la riga prima di eseguire \endinput.

      Oppure con il tuo metodo, ma con la riga
      `\expandafter\let\csname @@endinput\endcsname\endinput`
      perché dentro \csname…\endcsname i codici di categoria sono ignorati (a parte 0, 9, 13, 14 e 15 per motivi che puoi immaginare).

      Ciao
      Enrico

    • #65418
      Up
      0
      Down
      ::

      egreg9″ post=64468


      ho inserito il seguente controllo sul motore in uso:

      `
      \expandafter\ifx\csname XeTeXrevision\endcsname\relax%
      \let\@@endinput\endinput%
      \errmessage{Ahi ahi, nothing to do.}\fi%
      \csname @@endinput\endcsname%

      `
      Dove cavolo sbaglio?

      Se prima non dichiari “\catcode`@=11”, stai semplicemende dicendo “\let\@=@”, che non è molto utile …

      \catode’@ l’ho settato prima di quel chunk di codice, lo davo per scontato.

      egreg9″ post=64468
      Il metodo corretto è
      `\expandafter\ifx\csname XeTeXrevision\endcsname\relax
      \errmessage{Ahi ahi, nothing to do.}%
      \expandafter\endinput\fi`

      Quello è esattamente il codice che avevo scritto prima di quello copiato nel primo post, con il \fi sullo steso rigo. Ma siccome dava problemi (lo stesso problema, il motore non ferma la lettura, arriva all’istruzione successiva e restituisce un errore) avevo pensato di evitare l’expandafter con il meccanismo del \let … e \csname.

      Per maggiore chiarezza riporto un pezzo un pò più ampio del codice e il messaggio di errore che restituisce:

      `
      \chardef\atcatcode=\the\catcode`@%
      \catcode`@=11\relax%
      % …
      % a me i messaggi servono sempre su una nuova riga
      \def\@errmessage#1{\immediate\write16{!! ERR !! >>>\space#1}}
      % …
      \expandafter\ifx\csname XeTeXrevision\endcsname\relax%
      \@errmessage{Why are you here again?}%
      \let\@@endinput\endinput\fi
      \csname @@endinput\endcsname%
      %
      \XeTeXinputencoding bytes%
      % …
      `

      `
      This is pdfTeX, Version 3.1415926-2.3-1.40.12 (TeX Live 2011)
      restricted \write18 enabled.
      entering extended mode
      (./09semantics.tex (./modernb.tex
      !! ERR !! >>> Why are you here again?
      ) (./lipsum.tex
      ! Undefined control sequence.
      l.2 \XeTeXinputencoding
      bytes
      ?
      Processo interrotto dall'utente
      `

      Il lipsum.tex presente nel messaggio di errore è una mia versione del pacchetto lipsum, lo uso da molto tempo e sono sicuro che lì dentro errori non ce ne sono.

      Grazie per ogni aiuto, ciao.

    • #65419
      Up
      0
      Down
      ::


      ARGH!!!!!!!!! Ho trovato l’errore!!!!
      Lo \XeTeXinputencoding che pdfTeX non riesce a leggere non è quello nel pacchetto di stile modernb, ma quello nel mio pacchetto lipsum, richiamato al secondo rigo, come ESPLICITAMENTE riportato nel messaggio di errore.

      Scusate la figura di tolla, sarete sicuramente anche voi impazziti su errori del genere quando iniziavate a usare TeX.

      Ciao.

    • #65420
      Up
      0
      Down
      ::

      Sam Qasbah” post=64469Per maggiore chiarezza riporto un pezzo un pò più ampio del codice e il messaggio di errore che restituisce:

      `
      \chardef\atcatcode=\the\catcode`@%
      \catcode`@=11\relax%
      % …
      % a me i messaggi servono sempre su una nuova riga
      \def\@errmessage#1{\immediate\write16{!! ERR !! >>>\space#1}}
      % …
      \expandafter\ifx\csname XeTeXrevision\endcsname\relax%
      \@errmessage{Why are you here again?}%
      \let\@@endinput\endinput\fi
      \csname @@endinput\endcsname%
      %
      \XeTeXinputencoding bytes%
      % …
      `

      Mi pare poco efficiente.
      `\chardef\atcatcode=\the\catcode`@
      \catcode`@=11
      \expandafter\ifx\csname XeTeXrevision\endcsname\relax
      \@errmessage{Why are you here again?}%
      \endinput\fi`
      Il “%” dopo “`@” è ridondante; lo stesso è ridondante il “\relax%” dopo 11. Naturalmente è ridondante anche dopo “\endcsname\relax”. Non serve a nulla definire \@@endinput.

      Ciao
      Enrico

    • #65421
      Up
      0
      Down
      ::

      egreg9″ post=64471
      Il “%” dopo “`@” è ridondante; lo stesso è ridondante il “\relax%” dopo 11. Naturalmente è ridondante anche dopo “\endcsname\relax”. Non serve a nulla definire \@@endinput.

      Ciao
      Enrico

      Circa i “%” ridondanti hai sicuramente ragione: ancora non ricordo a memoria tutti i casi in cui salva dalla presenza di spazi spuri e i casi in cui è inutile.

      Circa invece \@@endinput. Magari è inutile, ma come `seconda scelta’ rispetto a \expandafter\endinput\fi (che, come ho detto prima, a me sembrava dare problemi), a me sembra una gran figata. Ha il suo fascino. Anche su CTAN si trova codice scritto in modo molto peggiore.

      Ma queste sono tutte opinioni, è meglio piantarla qui.

      Grazie per l’aiuto, ciao.

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

Go to top