TeX e LaTeX.
La codifica del file di input

Cos'è una codifica dei caratteri

I compilatori della famiglia TeX, come ogni altro compilatore di qualsiasi linguaggio di programmazione, possono compilare solo dei file di testo. Un file di testo è un file contenente una sequenza di bit che rappresenta, tramite un'opportuna "tabella di conversione tra sequenze di bit e caratteri", una sequenza di simboli. Non ci sono altra informazioni se non una sequenza di simboli.

I programmi che possono modificare i file di testo vengono chiamati, non a caso, editor di testo. Tra questi ricordiamo come esempio Notepad di Windows (Blocco Note in italiano), un editor generico molto semplice, Notepad++ per Windows, un editor generico molto potente, i vari editor specifici per TeX come TeXworks. Questi editor quando aprono un file di testo, hanno bisogno di conoscere la "tabella di conversione" giusta per passare dalle sequenze di bit ai caratteri e mostrare quindi sullo schermo i simboli corretti. In via teorica, avendo questa "tabella di conversione", anche un umano può passare dai bit alle lettere senza che questo lavoro venga svolto dagli editor di testo.

Queste "tabelle di conversione tra sequenze di bit e caratteri" vengono dette codifiche di caratteri. La più famosa è la codifica ASCII che definisce una corrispondenza tra i primi 128 numeri (partendo da zero) e 128 caratteri. Viene chiamata codifica a 7 bit perché per rappresentare in forma binaria i primi 128 numeri si ha bisogno di 7 bit (27 = 128). In pratica però i computer moderni usano sempre gruppi di 8 bit (8 bit = 1 byte) e pertanto nel caso dell'ASCII in ogni sequenza il primo bit sarà sempre zero.

Vediamo un esempio. Supponiamo di creare un nuovo file di testo con il nostro editor di testo preferito. Scegliamo come codifica dei caratteri l'ASCII e scriviamo la parola "ciao". Salviamo il file. Tramite un visualizzatore o editor esadecimale possiamo vedere la sequenza di bit contenuta in questo file. Ecco cosa vedreste

01100011011010010110000101101111

Avendo sottomano la tabella della codifica ASCII potete controllare che effettivamente, raggruppando i bit a gruppi di 8, si ottiene proprio la parola "ciao". Notate inoltre che il primo bit di ogni gruppetto di 8 bit è sempre zero. Infine il file in questione occuperà esattamente 4 byte.

Ovviamente i 128 simboli dell'ASCII, di cui solo 96 effettivamente stampabili, erano il minimo indispensabile per poter scrivere in inglese. Nacquero quindi nel corso degli anni una moltitudine di codifiche, principalmente per contemplare un numero maggiore di simboli e quindi per usare caratteri particolari, non compresi nell'ASCII e tipici di molte lingue diverse dall'inglese. Questo comportava chiaramente un numero maggiore di bit, solitamente 8 corrispondenti a 256 simboli, ma fortunatamente la maggior parte delle codifiche mantenevano i primi 128 caratteri uguali a quelli dell'ASCII, rappresentadoli con le stesse sequenze di bit. In questo modo l'ASCII diventò la codifica "di base" presa come riferimento.

Le codifiche non sono però importanti solo per i file di testo! Sono necessarie in generale ovunque bisogna associare una sequenza di bit a un simbolo: comunicazione tra terminali, indicizzazione dei simboli di un font, nomi dei file nel filesystem, ecc... ecc... Qualsiasi apparecchio, funzione, ecc... che ha bisogno di mostrare dei caratteri, fa probabilmente uso di una codifica.

Tagliando corto e facendo un grande salto nella storia delle codifiche, vi parlerò solo di Unicode e delle varie codifiche a esso associate. Nel corso degli anni la moltitudine di codifiche creò via via sempre più problemi per l'interoperabilità. Dato che la potenza dei calcolatori andava via via aumentando, si pensò di creare una codifica universale che contenesse tutti i simboli usati nella storia umana per comunicare. Nacque così Unicode.

Questo progetto importantissimo, si divide in due parti. La prima parte consiste in un semplice catalogo di simboli, ognuno associato a un numero. I primi 128 numeri (da 0 a 127) corrispondono ai 128 caratteri dell'ASCII. Attualmente il numero massimo di simboli è stato fissato a 1'114'112 (più di un milione!) ma sono stati assegnati per ora meno di 400'000 mila simboli. Nonostante questo attualmente Unicode copre già ogni simbolo grafico comunemente usato nel mondo.

La seconda parte del progetto consiste nella maniera di rappresentare in un calcolatore i numeri della tabella Unicode, cioè in pratica delle codifica vera e propria. Esistono (purtroppo) vari modi per rappresentare questi numeri sotto forma di bit. Tra questi ricordo solo la codifica UTF-8, la più importante e la codifica UTF-32.

Come abbiamo detto il tetto massimo di posizioni della tabella Unicode è 1'114'112. Per rappresentare questo numero sono sufficienti 21 bit, non è vietato però usarne un numero maggiore e metterli a zero. UTF-32 fa proprio questo. In pratica ogni numero è rappresentato da 32 bit cioè 4 byte. Ovviamente le prime 256 posizioni avranno i primi 3 byte tutti a zero. Questo sistema è il più semplice ma ha due pecche: la prima è che non è compatibile con l'ASCII. Infatti sebbene le prime 128 posizioni dell'Unicode siano identiche a quelle dell'ASCII, le sequenze di bit usate da UTF-32 per rappresentarle sono diverse. La differenza sta, lo ripetiamo, nell'uso di 4 byte anziché uno solo come nell'ASCII. Il fatto che i primi 3 byte siano impstati a zero non cambia chiaramente la faccenda. Il secondo svantaggio di UTF-32 è che spreca troppo spazio per ovvi motivi.

La codifica Unicode che invece non soffre di questi problemi ed è quindi la più famosa e usata, è UTF-8. Questa codifica usa un numero variabile di byte per rappresentare i codici dei caratteri Unicode. Le prime 128 posizioni usano solamente un byte! Inoltre tale byte è identico alla codifica ASCII. I codici dal 129 al 2047 usano 2 byte, quelli dal 2048 al 65535 usano 3 byte e infine dal 65'536 al 1'114'111 usano 4 byte. Per poter capire se due o più byte vanno raggruppati o meno, per rappresentare quindi un singolo codice, vengono impostati alcuni bit come "identificatori di raggruppamento". Vedere la voce di Wikipedia per capire la convenzione usata. Infine si faccia caso al fatto che se un file di testo usa solo caratteri ASCII, tale file è leggibile anche scegliendo come codifica UTF-8. Possiamo pensare all'ASCII come a un sottoinsieme di UTF-8.

La codifica del file di input per TeX

Un file sorgente che vuole essere compilato con il compilatore pdfTeX, deve essere salvato con la codifica ASCII. Dato che TeX è fatto apposta per scrivere dei testi, l'uso dell'ASCII risulta più restrittivo rispetto a un altro linguaggio di programmazione come può essere il C. I nuovi compilatori TeX, come XeTeX e LuaTeX, accettano invece di default un file sorgente salvato in codifica UTF-8.

Nel caso di pdfTeX quindi, per far sì che nel file di output compaiano caratteri non compresi nell'ASCII, esistono una serie di comandi appositi. Un esempio sono le lettere accentate: il comando \'a produce la lettera accentata à. Infatti se volete compilare con pdfTeX non potete inserire direttamente nel sorgente il simbolo "à". Vedremo in realtà nel prossimo paragrafo che questo è possibile pur di caricare un apposito pacchetto.

L'inserimento di qualsiasi simbolo direttamente nel sorgente è invece possibile, senza alcun problema e senza caricare alcun pacchetto, nel caso vogliate compilare con XeTeX o LuaTeX. Ovviamente continuano a essere disponibili i comandi "classici" perché non è detto che sulla vostra tastiera ci siano i simboli che volete scrivere oppure non è detto che facciate prima a fare copia e incolla prendendo il simbolo voluto da qualche programma (tipo BabelMap o CharacterMap) o sito web.

pdfTeX: inserire caratteri non ASCII direttamente nel sorgente

Supponiamo che compiliate il vostro sorgente LaTeX con il comando pdflatex (che a sua volta richiama pdfTeX). Supponiamo inoltre che vogliate avere la possibilità di scrivere nel vostro file di input, direttamente alcuni simboli non-ASCII, per esempio le lettere accentate, senza usare i comandi LaTeX appositi e usando la codifica UTF-8 (non parliamo di altre codifiche perché, come abbiamo spiegato sopra, il futuro è UTF-8 e basta).

Oramai tutti gli editor di testo moderni pensati appositamente per LaTeX supportano UTF-8 (TeXworks, TeXstudio, TeXmaker) e la impostano come codifica di default. Pertanto il salvataggio del sorgente in UTF-8 è banale. Il passo fondamentale è invece dire a pdfTeX come gestire le sequenze di bit non-ASCII (cioè gruppi di 8 bit che cominciano con 1) senza che ci restituisca un errore!

A tal proposito esistono i pacchetti inputenx e il più vecchio inputenc. Durante la compilazione questo pacchetto si occuperà di tradurre in comandi TeX i caratteri non ASCII che abbiamo inserito. Per usarlo basta richiamarlo, come tutti i pacchetti, nel preambolo e specificare nelle sue opzioni che tipo di codifica si è usata per scrivere il sorgente. Esempio:

\usepackage[utf8]{inputenx}

Bisogna fare attenzione che i caratteri aggiuntivi messi a disposizione dalla codifica scelta non possono essere usati nell'ambiente matematico. Esiste però l'opzione math, da affiancare alla codifica, che permette di inserire un certo numeri di caratteri Unicode anche nell'ambiente matematico (sconsigliato). Ecco come fare:

\usepackage[utf8,math]{inputenx}

Infine un'ultima parola sulla compatibilità. Salvare un file in una codifica diversa dall'ASCII rende il sorgente "meno compatibile" nel caso lo vogliate dare a un'altra persona o lo vogliate passare su un altro sistema operativo. In realtà non si tratta di vere incompatibilità, è però necessario che la persona che voglia modificare quei sorgenti sappia in quale codifica sono scritti e sappia anche come impostare questa codifica nel proprio editor. Per questo motivo, se scrivete in inglese oppure se il vostro documento è breve o non necessita di particolari caratteri non-ASCII, evitate di usare una codifica diversa dall'ASCII!

Problemi dovuti all'inserimento di caratteri non-ASCII

A volte capita che, nonostante scriviate usando solo caratteri ASCII, alcuni caratteri non-ASCII vengano comunque inseriti nel sorgente a causa di un copia-incolla, di un errore di battitura, ecc... Riceverete quindi un errore di compilazione. Il o i caratteri incriminati non sono sempre facili da individuare. Un consiglio che posso dare in questi casi è di aprire il sorgente con un editor di testo decente (per esempio Notepad++ in Windows) che supporti la ricerca tramite espressioni regolari. Cercando la seguente espressione regolare

[^\x00-\x80]

trovere tutti i caratteri non-ASCII presenti nel documento!

Codifica di input: cosa accade durante la compilazione?

Questo paragrafo è puramente tecnico e non è necessario sapere le cose qui contenute per scrivere con LaTeX. Vorrei analizzare passo passo cosa accade durante la compilazione con pdfTeX e con XeTeX in modo da capire come viene gestita la codifica di input.

Le tabelle di corrispondenza tra le sequenze di bit incontrate nel sorgente e i corrispondenti comandi LaTeX si trovano nei file .def. Solitamente hanno il nome della codifica di input a cui si riferiscono.

\ProvideTextCommandDefault{command}{definition}
\DeclareInputText{slot}{text}
\DeclareInputMath{slot}{math}