Concilio dei topini

clsguide

Topino 106

Il file clsguide contiene “LaTeX2e for class and package writers”. È piuttosto corto, 33 pagine, ed è scritto principalmente per spiegare LaTeX2e (anni ’90) a chi arriva dalla versione 2.09 (che sarebbe la prima versione di LaTeX, quella degli anni ’80), quindi mi è stato meno utile del previsto. Comunque qualcosa ho imparato.

  1. Negli ultimi tempi dopo aver letto il TeXbook ho usato tendenzialmente i comandi di TeX per fare le cose perché sono più sbrigativi di quelli di LaTeX. Tanto cosa cambia?

The simplest way to ensure ‘colour safety’ is to always use LaTeX box commands rather than TeX primitives, that is use \sbox rather than \setbox, \mbox rather than \hbox and \parbox or the minipage environment rather than \vbox.

Ah ecco cosa cambia. Spiegazione:

As an example of what can go wrong, consider that in {\ttfamily ⟨text⟩} the font is restored just before the }, whereas in the similar looking construction {\color{green} ⟨text⟩} the colour is restored just after the final }.

E perché diavolo \color riimposta il colore dopo la graffa anziché prima, incasinando tutte le circostanze in cui le graffe delimitano qualcosa che viene spostato e quindi il comando di reset del colore rimane lì mentre il comando di set del colore se ne va a giro? Non potevano farlo come i comandi dei font \ttfamily etc.?

La spiegazione che ipotizzo è: l’impostazione del font è un’operazione primitiva di TeX che in qualche modo \ttfamily evoca. Quindi vengono assegnati dei valori a delle variabili che TeX legge per decidere che font usare al prossimo carattere. Come tutti gli assegnamenti, se non dichiarati globali vengono annullati alla chiusura del gruppo corrente. Invece i colori TeX non sa cosa siano, quindi avranno dovuto implementarli con dei whatsit (le estensioni/plugin in TeX si chiamano whatsit, non so perché). Quindi ci vorra un whatsit iniziale che imposta il colore, e un whatsit finale che lo annulla quando il gruppo finisce. L’unica funzione di TeX per far succedere qualcosa quando chiudi le graffe è \aftergroup che però come suggerisce il nome piazza le cose dopo la chiusura.

Visto che i comandi predefiniti di LaTeX hanno un “maglione” in più sugli argomenti, come ho scoperto leggendo il manuale, anche nei comandi tipo \mbox ci avranno messo questo gruppo in più (che in TeX con le scatole non servirebbe perché le scatole formano gruppi) cosicché \aftergroup non riesce a sparare i whatsit fuori dalla scatola.

We consider it good practice, when writing packages and classes, to use LaTeX commands as much as possible.

Ok, ok, mi avete convinto.

  1. Le opzioni delle classi e dei pacchetti di LaTeX sono implementate con una famigliola di macro tra cui \ProcessOptions. Negli esempi viene sempre usata così: \ProcessOptions\relax. Perché \relax? Perché c’è anche la versione \ProcessOptions* con l’asterisco. Visto che gli asterischi non sono caratteri validi per costruire una \-sequenza, tutte le macro con l’asterisco sono implementate con un parser che guarda il carattere successivo e controlla se è un asterisco. Se non fai errori fila tutto liscio. Se fai errori il parser viene evocato nel posto sbagliato al momento sbagliato e mangia qualcosa che non doveva mangiare e gli errori non sono più comprensibili (o meglio, sono ancora più incomprensibili). Nel documento non te la spiegano proprio così, ma non ho ancora trovato nessuna esplicita ammissione di inferno nella documentazione ufficiale.
  2. I comandi \documentclass e \usepackage supportano un argomento opzionale dopo il nome del pacchetto per specificare la data minima richiesta. C’è anche \NeedsTeXFormat per chiedere una data minima di release di LaTeX.
  3. C’è una classe minimal che definisce il minimo necessario ma Enrico Gregorio su tex.stackexchange diceva di non usarla. Boh.
  4. Il comando \DeclareOption si mangia il codice da eseguire nel caso una
    certa opzione venga specificata dall’utente. In tale codice si può usare il cancelletto #. COME DIAVOLO È POSSIBILE? Ok, idea: usano un token register.
  5. \DeclareRobustCommand, che già conoscevo, definisce una nuova macro stile
    \newcommand ma non fragile. Come funzionerà? Forse mette la macro in un nome interno del tipo \rob@macro e poi definisce \macro come \noexpand\rob@macro. O forse ormai usa \protected di eTeX? Per fortuna questi importanti quesiti si possono risolvere eseguendo latexdef \DeclareRobustCommand, che mi porta a eseguire latexdef \declare@robustcommand, che sputa fuori:

\declare@robustcommand:

macro:#1->\ifx #1\@undefined \else \ifx #1\relax \else \@latex@info {Redefining \string #1}\fi \fi \edef \reserved@a {\string #1}\def \reserved@b {#1}\edef \reserved@b {\expandafter \strip@prefix \meaning \reserved@b }\edef #1{\ifx \reserved@a \reserved@b \noexpand \x@protect \noexpand #1\fi \noexpand \protect \expandafter \noexpand \csname \expandafter \@gobble \string #1 \endcsname }\let \@ifdefinable \@rc@ifdefinable \expandafter \new@command \csname \expandafter \@gobble \string #1 \endcsname

Uhm… ci sono sicuramente un po’ di cose in più, però il succo è quello. Inoltre non usa un nome interno per salvare la macro, ma la definisce come \protect\macro, se sto capendo. Ma se tanto poi \new@command ridefinisce \macro, come fa a funzionare?? Ma non ha un Cristo di senso!!! Eseguendo latexdef \protect viene fuori:

\relax.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *

© 2024 Concilio dei topini Torna sù