205.3 Gestione delle sessioni

Transcript

205.3 Gestione delle sessioni
Introduzione a NOS-KA9Q -- IPv4 per Dos
2235
205.2.4 Comando domain
Il comando ‘domain’ permette di definire quali sono i servizi DNS a cui il sistema NOS può
rivolgersi; permette anche di configurare il loro utilizzo e di definire eventualmente una risoluzione locale per alcuni indirizzi. Qui viene mostrato solo come dichiarare l’uso dei servizi DNS
e il dominio predefinito.
domain addserver indirizzo_ip_DNS
domain suffix
[suffisso_predefinito ]
Segue la descrizione di alcuni esempi.
•
domain addserver 192.168.1.1
domain addserver 192.168.1.2
Dichiara l’uso del servizio DNS collocato presso i nodi 192.168.1.1 e 192.168.1.2.
•
domain suffix brot.dg.
• Dichiara che in caso di nomi di dominio incompleti viene aggiunto il suffisso brot.dg.
domain suffix
Mostra il suffisso predefinito per i nomi di dominio.
205.3 Gestione delle sessioni
Il sistema NOS può gestire diverse sessioni di lavoro, corrispondenti ad altrettante attività che
implicano l’instaurarsi di una connessione. Per esempio si possono gestire diverse connessioni
TELNET simultaneamente e lo stesso vale per l’utilizzo del protocollo FTP. Tutto questo funziona in modo paragonabile al sistema delle console virtuali di GNU/Linux: con il sistema NOS c’è
una finestra per la modalità di comando, dove si trova l’invito, attraverso la quale si impartiscono i comandi, e le finestre delle sessioni che vengono aperte automaticamente in base al tipo di
comando che viene dato.
Quando ci si trova a interagire con una sessione è possibile tornare alla finestra della modalità di
comando attraverso il tasto [ F10 ] (vale solo per il NOS che si basa sul Dos) e poi, da lì è possibile
tornare a una sessione attraverso il comando ‘session’. Da questo si comprende che le sessioni
sono numerate, cosa che avviene in modo automatico. Una di queste è anche la sessione attiva,
ovvero quella a cui si potrebbe fare riferimento quando non se ne specifica il numero.
Comando
session
[n_sessione]
session
session 1
close
[n_sessione]
close
close 1
reset
[n_sessione]
Descrizione
Il comando ‘session’ permette di tornare a una sessione ancora attiva, specificandone il numero. Se questo non viene
indicato, si ottiene l’elenco delle sessioni esistenti.
Elenca le sessioni esistenti.
Torna alla prima sessione.
Il comando ‘close’ interrompere una connessione TCP attraverso l’invio di un pacchetto FIN (che serve a chiudere una
connessione del genere). Il risultato che si ottiene di solito è
che la sessione corrispondente termina.
Interrompe la connessione della sessione corrente.
Interrompe la connessione della prima sessione.
Il comando ‘reset’ interrompere una connessione TCP attraverso l’invio di un pacchetto RST. Il risultato che si vuole ottenere è la conclusione della sessione corrispondente, ma dal
momento che il metodo dell’invio di un pacchetto RST non
garantisce l’ottenimento di ciò, sarebbe preferibile utilizzare
il comando ‘close’ al suo posto.
Introduzione a NOS-KA9Q -- IPv4 per Dos
2236
Comando
abort
[n_sessione]
abort
abort 1
Descrizione
Il comando ‘abort’ permette di interrompere un’operazione di carico o scarico dati attraverso una sessione FTP. La
sessione in questione non viene chiusa.<
Interrompe le operazioni di carico-scarico nella sessione
corrente, purché di FTP.
Interrompe le operazioni di carico-scarico nella prima
sessione, purché sia di FTP.
205.4 Attività nel sistema locale
Dal momento che non è possibile intervenire direttamente sul sistema operativo sottostante senza
interrompere le connessioni che eventualmente fossero state instaurate, NOS deve incorporare
alcune funzionalità che non hanno attinenza con la rete, ma che sono indispensabili a livello
pratico.
Per quanto riguarda i percorsi delle directory possono essere indicati utilizzando sia le barre
oblique inverse (‘\’) che quelle normali (‘/’) per la separazione dei nomi che li compongono.
Comando
cd
[percorso]
pwd
[percorso]
mkdir [percorso]
rmdir [percorso]
dir
more file ...
rename file_origine file_destinazione
delete file ...
!
| shell
Descrizione
Permette di cambiare la directory corrente nel sistema sottostante. Se viene utilizzato senza l’indicazione del percorso, si
ottiene la visualizzazione della directory corrente.
Mostra quale sia la directory corrente.
Elenca il contenuto della directory corrente.
Crea una directory nel sistema operativo sottostante.
Elimina una directory nel sistema operativo sottostante.
Scorre il testo di uno o più file del sistema operativo
sottostante, facendo una pausa tra le schermate.
Rinomina o sposta un file del sistema operativo sottostante.
Elimina i file indicati negli argomenti dal sistema operativo
sottostante.
Sospende il funzionamento di NOS per aprire una shell del
sistema operativo sottostante (‘COMMAND.COM’).
205.5 Gestione della rete e delle connessioni
Oltre a quanto visto inizialmente per ciò che riguarda la definizione delle interfacce, la loro
configurazione, l’instradamento e la risoluzione dei nomi, ci sono una serie di comandi e di
funzionalità per la gestione della rete.
205.5.1 Indirizzi IP e indirizzi MAC
arp
arp flush
Il comando ‘arp’ permette di conoscere il contenuto della tabella di trasformazione degli indirizzi IP in indirizzi fisici e viceversa. Questa viene costruita automaticamente dal sistema, durante
il suo funzionamento. Sono disponibili degli argomenti particolari per inserire a forza delle voci nella tabella, anche se questa operazione non dovrebbe essere necessaria. In particolare, il
comando ‘arp flush’ svuota la tabella attuale, costringendo il sistema NOS a ricominciare a
costruirsela.
Introduzione a NOS-KA9Q -- IPv4 per Dos
2237
205.5.2 Ping e instradamento
Attraverso il comando ‘ping’ si può inviare una richiesta di eco utilizzando il protocollo ICMP.
Questo è il modo consueto per verificare che sia presente un certo nodo nella rete. In generale
conviene utilizzare soltanto la sintassi seguente, con la quale viene inviata un’unica richiesta.
ping host
Per verificare il percorso dei pacchetti lungo la rete si può utilizzare il comando ‘hop’. Il comando
normale si articola nel modo seguente:
hop check host
Tuttavia, si può intervenire su alcuni parametri di funzionamento di questo comando: il TTL
(Time to live),
hop maxttl max_salti
l’attesa massima,
hop maxwait n_secondi
e il numero di pacchetti di prova che vengono inviati a ogni nodo.
hop queries n_pacchetti
Infine, è possibile abilitare o meno la visualizzazione di informazioni aggiuntive:
hop trace
[on|off]
205.5.3 Varie
hostname
[nome]
Attraverso il comando ‘hostname’ è possibile definire o visualizzare il nome attribuito al nodo.
Questo dovrebbe corrispondere alla parte finale del nome di dominio, ma in ogni caso serve solo
nei messaggi di presentazione del sistema.
socket
[n_porta]
Attraverso il comando ‘socket’ è possibile conoscere lo stato delle porte. Utilizzandolo senza
argomenti si ottiene l’elenco delle porte utilizzate, generalmente quelle dei servizi in ascolto ed
eventualmente anche quelle gestite dalle sessioni in cui si utilizzano dei clienti di qualche tipo,
mentre specificando una porta precisa si ottengono le statistiche sul traffico intrattenuto.
205.6 NOS come cliente
L’uso più importante del sistema NOS è quello di cliente in grado di utilizzare i servizi
fondamentali di una rete TCP/IP. Si tratta principalmente di TELNET e FTP.
205.6.1 Cliente TELNET
Il sistema NOS permette di attivare una sessione TELNET verso un altro sistema che offra la
possibilità di accedere attraverso questo tipo di protocollo. Purtroppo, il tipo di terminale corrispondente alla sessione TELNET è molto modesto, tanto che nelle versioni più limitate di NOS
non si possono usare nemmeno i tasti freccia.
Introduzione a NOS-KA9Q -- IPv4 per Dos
2238
telnet host
Quando si utilizza questo tipo di cliente TELNET per accedere a un nodo corrispondente a un
elaboratore GNU/Linux, il tipo di terminale che si vede nella variabile ‘TERM’ è ‘network’, che
però non corrisponde ad alcuna voce nel sistema Terminfo o nel sistema Termcap. Eventualmente
si può cambiare questo nome con ‘ansi’, o ‘ansi-mono’ se si preferisce.
Da una sessione TELNET è possibile tornare alla modalità di comando premendo il tasto
[ F10 ]. Per ritornare alla sessione con TELNET, si potrà poi utilizzare il comando ‘session’.
205.6.2 Cliente FTP
Il sistema NOS permette di attivare una sessione FTP. Una volta avviata, si ha a disposizione
un cliente FTP tradizionale, con comandi molto simili a quelli del programma ‘ftp’ dei sistemi
Unix (se ne trova la descrizione nel capitolo 148).
ftp host
L’unico vero difetto sta nel sistema operativo sottostante: utilizzando il Dos i nomi dei file che
vengono salvati sono ridotti al modello «8.3».
È importante ricordare di modificare sempre il tipo di trasferimento dati, in modo che sia di
tipo binario (image): ‘type i’.
205.7 NOS come servente
I servizi offerti da NOS sono limitati e comunque dipendono dalla versione di questo sistema.
Questi servizi devono essere abilitati attraverso il comando ‘start’. Dal momento che dipende dalla versione di NOS se un tipo di servizio è disponibile o meno, attraverso il comando
‘start ?’ si ottiene l’elenco di questi.
In generale non conviene avere grandi pretese; probabilmente è il caso di attivare sempre i servizi
‘discard’, ‘echo’, ‘ftp’ e ‘finger’ (ammesso che questo ultimo possa avere senso).
start
start
start
start
discard
echo
finger
ftp
Per converso, volendo disattivare un servizio basta utilizzare il comando ‘stop’ nello stesso
modo.
205.7.1 Registrazione degli eventi
NOS permette di annotare gli accessi in un registro abbastanza semplificato. Si attiva questa
funzionalità attraverso il comando ‘log’:
log
[stop |
file_delle_registrazioni
]
Per esempio, per attivare la registrazione degli accessi nel file ‘C:\ACCESSI.LOG’, si può usare
il comando seguente:
log c:\accessi.log
Introduzione a NOS-KA9Q -- IPv4 per Dos
2239
Come si può intuire, il comando ‘log stop’ termina l’attività di registrazione degli accessi,
senza interferire con gli accessi stessi. Infine, il comando ‘log’ senza argomenti permette di
sapere se questo sia attivo e in tal caso su quale file vengono fatte le annotazioni.
2240
Introduzione a NOS-KA9Q -- IPv4 per Dos
205.7.2 Servente FTP
Per abilitare il servizio FTP, oltre che usare il comando ‘start ftp’, occorre predisporre un
file di autorizzazioni: ‘ftpusers’ collocato nella directory radice del servizio NOS. Il file deve
contenere delle righe scomposte in quattro campi separati da uno o più spazi e si possono indicare
anche dei commenti che si introducono con il simbolo ‘#’.
utente parola_d’ordine percorso permessi
I quattro campi sono obbligatori e il significato è intuitivo:
1. utente serve a specificare il nome dell’utente che può accedere;
2. parola_d’ordine rappresenta la parola d’ordine in chiaro necessaria per l’accesso -- se si
utilizza un asterisco (‘*’), viene accettata qualunque parola d’ordine;
3. percorso indica la directory a partire dalla quale si concede l’accesso all’utente;
4. permessi è un numero che esprime i permessi consentiti all’utente.
I permessi non sono indicati secondo la tradizione Unix, quindi occorre fare attenzione. I permessi sono espressi con un solo numero ottenuto sommandone altri, che comunque si riferiscono
alla directory di partenza e a tutte le sottodirectory: uno rappresenta un permesso di lettura; due
rappresenta un permesso di creazione (di aggiunta di file senza poter sovrascrivere o eliminare quelli esistenti); quattro rappresenta un permesso di scrittura (o di sovrascrittura). Si osservi
l’esempio seguente:
tizio tazza \home\tizio 7
caio capperi \home\caio 7
semproni sempre \progetto 3
ftp * \pub 1
anonymous * \pub 1
Gli utenti ‘tizio’ e ‘caio’ hanno una loro directory personale in cui possono fare quello che
vogliono; l’utente ‘semproni’ partecipa a un lavoro che si trova nella directory ‘\PROGETTO\’
e lì ha la possibilità di immettere file, senza cancellare o sovrascrivere quelli presenti. Infine, gli
utenti ‘ftp’ e ‘anonymous’ accedono con una parola d’ordine qualunque alla directory ‘\PUB\’,
con il solo permesso di lettura.
205.8 NOS come router IPv4
NOS funziona perfettamente come router se l’elaboratore in cui si utilizza dispone di più interfacce di rete. A titolo di esempio viene mostrato in che modo potrebbero essere utilizzate due
schede di rete compatibili NE2000. Supponendo che queste utilizzino rispettivamente le risorse
IRQ 10, I/O 28016, e IRQ 11, I/O 30016, la configurazione del driver di pacchetto (si fa riferimento
a quanto descritto nella sezione 203.1) potrebbe essere quella seguente:
NE2000 0x60 0x0a 0x280
NE2000 0x61 0x0b 0x300
Supponendo che queste due schede servano a connettere le reti 192.168.1. e 192.168.2. ,
supponendo anche che l’instradamento predefinito passi per il router 192.168.1.254, il file di
configurazione di NOS potrebbe contenere in particolare le righe seguenti:
*
# Configurazione delle interfacce di rete.
attach packet 0x60 ethernet0 8 1500
*
Introduzione a NOS-KA9Q -- IPv4 per Dos
2241
attach packet 0x61 ethernet1 8 1500
# Definizione degli indirizzi IP.
ifconfig ethernet0 ipaddress 192.168.1.10
ifconfig ethernet0 netmask 255.255.255.0
ifconfig ethernet1 ipaddress 192.168.2.10
ifconfig ethernet1 netmask 255.255.255.0
# Instradamento.
route add 192.168.1.0/24 ethernet0
route add 192.168.2.0/24 ethernet1
route add default ethernet0 192.168.1.254
Non c’è bisogno di fare altro: l’attraversamento dei pacchetti da un’interfaccia all’altra avviene
automaticamente (purché gli instradamenti siano corretti).
Appunti di informatica libera 2003.01.01 --- Copyright © 2000-2003 Daniele Giacomini -- daniele @ swlibero.org
2242
Introduzione a NOS-KA9Q -- IPv4 per Dos
Parte xxxix
Samba
di Fulvio Ferroni fuferro @ tin.it
2243
Copyright © Fulvio Ferroni fuferro @ tin.it
Via Longarone, 6 - 31030 - Casier (TV)
Fulvio Ferroni ha concesso l’inclusione del suo documento alle stesse condizioni dell’opera
complessiva.
2244
206 Informazioni generali su Samba . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2246
206.1 Natura di Samba . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2246
206.2 Componenti di Samba . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2246
207 Servente Samba . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2248
207.1 I demoni del servente . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2248
207.2 Attivazione del servente Samba . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2248
207.3 Configurazione di un servente Samba . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2248
207.4 Programmi ausiliari per un servente Samba . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2257
208 Samba dal lato cliente . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2259
208.1 smbclient . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2259
208.2 smbmount . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2259
208.3 Uso con Samba di stampanti MS-Windows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2260
208.4 Altri strumenti utili . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2260
209 Samba come servente WINS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2261
210 Samba e la scansione della rete . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2262
211 Autenticazione di utenti MS-Windows con Samba . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2264
211.1 Domain logons . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2265
211.2 Logon script . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2265
211.3 Logon path . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2265
211.4 Logon home e logon drive . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2266
211.5 Sezione [netlogon] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2266
211.6 Definizione delle utenze per macchina . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2266
212 Accesso a GNU/Linux da parte di utenti di un dominio MS-Windows con Winbind 2267
212.1 Configurazioni necessarie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2267
212.2 Attivazione . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2269
213 Samba e DFS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2270
2245
Capitolo
206
Informazioni generali su Samba
Samba 1 è un insieme di strumenti realizzati da Andrew Tridgell per le piattaforme Unix e
GNU/Linux, distribuito sotto licenza GNU GPL, curato da un piccolo gruppo di persone di varie
parti del mondo coordinate dallo stesso Tridgell.
206.1 Natura di Samba
Samba utilizza il protocollo SMB (Server message block) definito per reti MS-Windows e a sua
volta basato sull’interfaccia di rete NetBIOS (Network basic input output system). SMB è stato
progettato originariamente per reti molto piccole. Per permettere la connessione a reti più estese
ed eterogenee, Microsoft ha sviluppato il sistema CIFS (Common internet file system) ancora
basato su NetBIOS.
Samba può essere a tutti gli effetti considerato una versione libera e gratuita di CIFS; con esso,
una macchina GNU/Linux, può accedere alle risorse condivise di un elaboratore MS-Windows
ma anche mettere a disposizione proprie risorse a clienti MS-Windows o GNU/Linux.
Più in dettaglio ecco quali sono i servizi offerti da Samba:
• servente per offrire la condivisione di file system e stampanti;
• cliente per l’accesso a risorse NetBIOS su macchine Unix, MS-Windows, Novell remote;
• master browser sia locale che di dominio;
• servente WINS (Windows internet name service);
• servente per l’autenticazione di clienti di un dominio MS-Windows;
• servente DFS (Distributed file system).
A livello di protocolli è necessario far presente che MS-Windows può incapsulare messaggi SMB
sui protocolli IPX/SPX, NetBEUI e TCP/IP mentre invece Samba può dialogare con macchine
MS-Windows solo attraverso il TCP/IP. Questa non è comunque una grande limitazione vista la
diffusione ormai universale di tale protocollo
La descrizione di come NetBIOS debba operare all’interno di una rete TCP/UDP è contenuta
nei documenti RFC 1001/1002. Lo standard descritto in questi documenti è noto come NBT
(NetBIOS over TCP/IP) ed è alla base del funzionamento sia delle reti NetBIOS che di Samba.
206.2 Componenti di Samba
La versione di Samba che viene presa in esame è la 2.2 cioè la più recente al momento della
stesura di questi appunti (primavera 2002).
I pacchetti da installare sono (si fa riferimento a pacchetti RPM essendo le prove state effettuate
su macchine dotate di una distribuzione GNU/Linux Red Hat; x.y.z rappresenta il numero di
versione):
• ‘samba-x.y.z .i386.rpm’
1
Samba GNU GPL
2246
Informazioni generali su Samba
2247
• ‘samba-client-x.y.z .i386.rpm’
• ‘samba-common-x.y.z .i386.rpm’
Il primo pacchetto contiene gli strumenti lato servente di Samba, il secondo gli strumenti lato
cliente, il terzo una serie di file indispensabili per il funzionamento sia del servente che del
cliente.
Scendendo più in dettaglio:
• nel pacchetto ‘samba’ si trovano i demoni ‘nmbd’ e ‘smbd’ che sono alla base del funzionamento di un servente Samba e alcuni programmi di servizio come ‘smbadduser’,
‘smbstatus’;
• nel pacchetto ‘samba-client’ sono contenuti altri programmi di servizio come ‘nmblookup’, ‘smbclient’, ‘smbmount’, ‘smbumount’, ‘smbtar’, ‘findsmb’,
‘testparm’;
• nel pacchetto ‘samba-common’ si trovano tra altri elementi il programma ‘smbpasswd’
e il file di configurazione di Samba ‘/etc/samba/smb.conf’ precompilato con alcune
impostazioni predefinite.
Tutti questi elementi verranno trattati nel seguito di questo documento.
Capitolo
207
Servente Samba
207.1 I demoni del servente
Un servente Samba si basa su due demoni:1
• ‘smbd’ che fornisce i servizi di condivisione di file stampanti per i clienti SMB (che possono
essere macchine MS-Windows o altre macchine GNU/Linux) e si occupa della gestione
delle sessioni di comunicazione e delle autenticazioni necessarie all’accesso alle risorse
che vengono offerte in condivisione dal servente; il demone avvia una copia di se stesso per
ogni richiesta di servizio da soddisfare;
• ‘nmbd’ che gestisce la distribuzione dell’elenco delle risorse condivise alle altre macchine della rete, può mantenere la lista delle risorse condivise (scansione della rete) ed
eventualmente risolvere i nomi NetBIOS della rete (servente WINS);
207.2 Attivazione del servente Samba
Entrambi i demoni ‘smbd’ e ‘nmbd’ possono essere attivati in modo autonomo, o gestiti dal
supervisore dei servizi di rete (come Xinetd); qui viene presa in esame solo la prima alternativa
che è di gran lunga la più praticata e anche quella predefinita in molte distribuzioni GNU/Linux.
In quasi tutte le distribuzioni si trovano infatti degli script preconfezionati per l’attivazione e la
disattivazione di determinati servizi; nel caso della Red Hat si attivano entrambi i demoni con il
comando:
# /etc/rc.d/init.d/smb start
e si disattivano con il comando:
# /etc/rc.d/init.d/smb stop
ci sono poi anche i comandi:
# /etc/rc.d/init.d/smb restart
e
# /etc/rc.d/init.d/smb status
il cui significato dovrebbe essere ovvio.
207.3 Configurazione di un servente Samba
La configurazione di un servente Samba si basa su di un file di testo; nella distribuzione Red Hat
(ma anche per altre) è ‘/etc/samba/smb.conf’.
Solitamente viene fornito preconfezionato e commentato, con una configurazione di base già
pronta all’uso; ovviamente è possibile intervenire sul file per adattare il comportamento del
servente alle proprie esigenze.
Prima di esaminare la struttura del file e i parametri principali di configurazione è opportuno
sottolineare alcuni importanti aspetti generali:
1
Un demone è un programma di servizio costantemente in esecuzione e pronto a rispondere a richieste a esso rivolte
da altri processi in esecuzione localmente o da una posizione remota
2248
Servente Samba
2249
• È indifferente usare maiuscole o minuscole a meno che tale uso non vada a interferire
con le regole del sistema operativo sottostante. Se ad esempio si indica il percorso di una
directory condivisa su una macchina GNU/Linux con l’opzione (che verrà descritta più
avanti) ‘PATH=/USR/LOCAL’, Samba non ha alcun problema ad accettare la direttiva ma al
momento di collegarsi alla risorsa fallisce in quanto in GNU/Linux quella directory al 99 %
non esiste, mentre esiste ‘/usr/local/’. È quindi consigliabile l’uso delle minuscole.
• Le righe di commento iniziano con i simboli ‘;’ oppure ‘#’.
• Il carattere di continuazione riga è ‘\’.
• Alcune direttive di configurazione di Samba, per ragioni di compatibilità, sono ridondanti;
per questo motivo uno stesso risultato si può ottenere in modi diversi.
• Per rendere effettive le variazioni fatte al file di configurazione non è necessario riavviare
i demoni di Samba in quanto il file viene riletto automaticamente ogni 60 s; se si vuole
forzare la rilettura basta impartire il comando: ‘kill -SIGHUP n ’ dove n è il numero del
processo corrispondente al demone ‘smbd’ in funzione (per individuarlo si può eseguire ‘ps
afx | grep smbd’). Occorre comunque notare che non tutti i cambiamenti alla configurazioni vengono necessariamente attuati subito; in particolare le variazioni della configurazione di risorse condivise rimangono congelate finché c’è qualche utente connesso a tali
risorse.
Il file di configurazione è suddiviso in sezioni i cui nomi sono racchiusi tra parentesi quadrate.
Ogni sezione corrisponde a una risorsa condivisa a eccezione della sezione ‘global’ usata per le
configurazioni globali. Altre sezioni con un ruolo un po’ particolare sono ‘homes’ e ‘printers’.
Sezione [global]
In essa si impostano le informazioni che condizionano tutto il sistema ed eventualmente
quei parametri che se non specificati vengono assunti in modo predefinito, ad esempio il
nome del gruppo di lavoro (workgroup).
Sezione [homes]
In essa si regolano i parametri di configurazione delle directory personali degli utenti che
si collegano al servente Samba.
Sezione [printers]
Consente di impostare le caratteristiche della condivisione di tutte le stampanti installate
nella macchina GNU/Linux senza dover definire una condivisione separata per ognuna di
esse.
All’interno del file di configurazione è possibile usare alcune variabili il cui nome viene sostituito
dal rispettivo valore quando il file di configurazione viene utilizzato dai demoni ‘smbd’ e ‘nmbd’.
Segue una lista delle variabili più importanti con una breve descrizione:
Variabile
%S
%P
%u
%g
%U
%D
%G
%H
Descrizione
nome del servizio corrente (‘[tmp]’, ‘[homes]’, ecc.);
directory principale del servizio corrente;
nome dell’utente (GNU/Linux) del servizio corrente;
nome del gruppo primario di ‘%u’;
nominativo-utente della sessione;
nome del dominio MS-Windows in cui il servente Samba si integra;
nome del gruppo primario di ‘%U’;
directory personale assegnata a ‘%u’;
Servente Samba
2250
Variabile
%v
%h
%m
%L
%M
%N
%p
%d
%a
%I
%T
Descrizione
versione in uso di Samba;
nome del nodo che ha avviato il servizio Samba;
nome NetBIOS della macchina cliente;
nome NetBIOS assegnato al servente;
nome Internet della macchina cliente;
nome della directory personale ottenuta dal servizio NIS del servente;
percorso della directory personale ottenuto dal servizio NIS;
numero identificativo del processo corrente;
architettura software della macchina remota (Samba, MS-Windows 95/98/Me/NT),
diversamente sarà assegnata la parola ‘UNKNOWN’;
indirizzo IP della macchina cliente;
data e ora corrente.
207.3.1 smb.conf: sezione global
È la sezione che appare in tutte le configurazioni di Samba, anche se non è obbligatoria. Le
opzioni in essa contenute vengono applicate a tutte le altre sezioni.
Viene mostrato un esempio comprendente alcune direttive di uso comune suddivise in blocchi in
base alla funzione svolta e intervallate da brevi descrizioni del loro significato:
[global]
#
# identificazione del servente
#
workgroup = INF
netbios name = pippo
server string = Samba Server
La voce più importante è ‘workgroup’ che assegna a Samba il dominio o il gruppo di
appartenenza. Occorre assegnarla correttamente, pena conflitti nella rete paritetica (peer-to-peer).
La voce ‘netbios name’ è di utilizzo meno frequente e serve ad assegnare al servente Samba un
nome NetBIOS a piacere. Il nome NetBIOS viene infatti assegnato in modo definito pari a quello
ottenuto dal DNS. Ad esempio se il nome DNS del servente fosse muscolis.inf.besta
il nome NetBIOS sarebbe ‘muscolis’. Uno dei casi in cui è utile poter impostare un nome NetBIOS diverso da quello predefinito è quello in cui la rete è suddivisa in due o più
domini DNS diversi; in questo caso potrebbe infatti anche esistere una macchina con nome
muscolis.mat.besta che verrebbe quindi ad avere lo stesso nome NetBIOS. Ovviamente
il valore di ‘netbios name’ deve essere assegnato seguendo le regole dei nomi NetBIOS (unica
stringa senza punti contenente i simboli alfabetici maiuscoli e minuscoli le cifre e i simboli ‘!’,
‘@’, ‘#’, ‘$’, ‘%’, ‘^’, ‘&’, ‘(’, ‘)’, ‘-’, ‘’’ e ‘~’).
Con ‘server string’ si assegna semplicemente la descrizione dell’elaboratore servente.
#
# opzioni di rete
#
hosts allow = 192.168.1. localhost
hosts deny = 172.16.244.254
interfaces = 192.168.1.1/24 172.16.244.1/16
bind interfaces only = yes
Le direttive ‘Host allow’ e ‘host deny’ servono rispettivamente a specificare quali nodi possono e non possono accedere alle risorse condivise dal servente Samba. L’indicazione può essere fatta tramite il nome del nodo, il nome di dominio, il numero IP, il numero della sottorete. Nell’esempio viene concesso l’accesso a tutte le macchine della sottorete 192.168.1. e
*
Servente Samba
2251
al localhost (è opportuno che l’accesso a localhost sia sempre concesso pena possibili
malfunzionamenti della scansione delle risorse del servente) e viene negato alla macchina con
indirizzo 192.168.1.3. Possono anche essere usate le parole chiave ‘ALL’, per designare qualsiasi elaboratore, e ‘EXCEPT’ per indicare un’eccezione a una regola (ad esempio ‘host allow
192.168.1. EXCEPT 192.168.1.3’). Si deve inoltre notare che in caso di assenza delle direttive ‘host allow’ e ‘host deny’, l’accesso è concesso a tutti in modo predefinito. Infine si
tenga presente che tali direttive possono essere inserite anche in specifiche condivisioni ma con
grado di priorità inferiore rispetto a quanto specificato nella sezione ‘global’.
La direttiva ‘interfaces’ è utile in caso il servente Samba risieda in più di una sottorete. Se
sull’elaboratore sono presenti più interfacce di rete, in modo predefinito, Samba si mette in ascolto di richieste provenienti dagli indirizzi di rete corrispondenti alla rete della prima interfaccia
che trova (di solito eth0). Per fare in modo che invece risponda alle richieste provenienti da più
sottoreti si deve impostare questa opzione. Nell’esempio Samba si pone in ascolto dalle sottoreti ‘192.168.1.*’ e ‘172.16.*.*’ (si può usare anche una notazione con maschera di rete:
‘192.168.1.1/255.255.255.0’ ‘172.16.244.1/255.255.0.0’).
Ponendo ‘bind interfaces only = yes’ (l’alternativa è ovviamente ‘no’ oppure si può evitare di inserire questa opzione), si forza il servente a rispondere soltanto alle sottoreti corrispondenti alle interfacce indicate in ‘interfaces’. In tal caso si deve inserire tra le interfacce anche 127.0.0.1 per permettere al programma ‘smbpasswd’ di potersi collegare al localhost e
funzionare correttamente.
#
# opzioni per la stampa
#
printing = bsd
printcap name = /etc/printcap
load printers = yes
La direttiva ‘printing’ permette di specificare il sistema di stampa in uso nel servente; per i
sistemi GNU/Linux il valore da indicare è di solito ‘bsd’, l’alternativa più diffusa è ‘sysv’.
Le altre due opzioni permettono di caricare automaticamente tutte le stampanti configurate nel
sistema senza descriverle singolarmente, indicando a tale scopo il percorso del file ‘printcap’
contenente la definizione di tali stampanti. La loro configurazione relativamente a Samba viene
poi indicata nell’apposita sezione ‘printers’ descritta più avanti.
#
# opzioni per il log
#
log file = /var/log/samba/%m.log
max log size = 100
log level = 3
La direttiva ‘log file’ permette di indicare il file delle registrazioni per gli eventi Samba; tale file può essere unico oppure, come nell’esempio, diverso per ogni cliente che si collega al
servente (il nome del file sarà ‘nome_host .log’). Altra possibilità è quella di avere un file di
registrazioni per ogni utente usando opportunamente la variabile ‘%U’ o ‘%u’.
Con ‘max log size’ si specifica la grandezza in kibibyte del file delle registrazioni, raggiunta
la quale il file stesso viene rinominato con estensione ‘.old’ e reinizializzato; il file ‘.old’
eventualmente già esistente viene cancellato. Il valore predefinito di questo parametro è 5000; il
valore zero significa nessun limite di ampiezza (scelta non consigliabile per evitare una crescita
abnorme del file o dei file delle registrazioni).
La direttiva ‘log level’ indica il livello di dettaglio dei messaggi annotati nel registro; il valore predefinito è zero e corrisponde a nessun messaggio. Aumentando questo valore si hanno
messaggi sempre più dettagliati; è comunque sconsigliabile un livello superiore a 3.
2252
Servente Samba
#
# opzioni per l’accesso alle condivisioni
#
encrypt password = yes
null password = yes
guest account = utentesmb
security = share
# in alternativa
; security = user
; security = server
; security = domain
# altri parametri nel caso di security = user
; smb passwd file = /etc/samba/smbpasswd
; username map = /etc/samba/smbusers
# altri parametri nel caso di security = server o domain
; password server = SERVER_NT
La direttiva ‘encrypt password = yes’ è praticamente obbligatoria se il servente Samba deve
«convivere» con macchine equipaggiate con sistemi operativi MS-Windows 98/NT o più recenti
che usano le parole d’ordine cifrate.
La direttiva ‘null password = yes’ permette di avere utenti Samba con parola d’ordine nulla
(il valore predefinito è ‘no’.)
La direttiva ‘guest account’ indica il nome di un utente generico al quale può essere consentito
l’accesso alle condivisioni (da usare nel caso di ‘security = share’, come dettagliato più
avanti). Tale utente deve essere definito nel sistema GNU/Linux senza directory personale e senza
shell, aggiungendo al file ‘/etc/passwd’ la riga:
utentesmb::499:499:utente generico samba:/dev/null:/dev/null.
Il valore predefinito è ‘nobody’.
Il parametro ‘security’ è di importanza fondamentale e richiede una trattazione leggermente
più ampia.
207.3.1.1 Livello di sicurezza «share»
Con l’impostazione ‘security = share’ si ha il controllo di accesso a livello di condivisione: il cliente che vuole accedere a una risorsa invia ogni volta una parola d’ordine e nessun
nominativo-utente. Samba tenta di dedurre il nominativo-utente dalla direttiva ‘valid users’
eventualmente inserita nella sezione di condivisione di quella risorsa (come illustrato in seguito),
oppure dal nome dell’elaboratore cliente, o, in caso di insuccesso, da quanto indicato con il parametro ‘guest account’ (questo solo se fra i parametri di condivisione è indicato ‘guest ok
= yes’ e ‘guest only = yes’).
Questo livello di sicurezza si usa, soprattutto nel caso di utenti MS-Windows e GNU/Linux
non coincidenti, per condividere porzioni di file system quando si ha interesse a far sì che tutti gli utenti abbiano gli stessi diritti sui file condivisi (con l’impostazione ‘guest account
= utentesmb’ il «proprietario» delle risorse condivise sarà sempre l’utente GNU/Linux
‘utentesmb’ qualunque sia il nominativo dell’utente MS-Windows che si connette).
Servente Samba
2253
207.3.1.2 Livello di sicurezza «user»
Con l’impostazione ‘security = user’, che è quella predefinita, si ha il controllo di accesso a
livello di utente: il cliente che vuole accedere a una risorsa invia al momento della connessione
una coppia utente-parola d’ordine in base alla quale avviene l’autenticazione da parte del servente. Se la connessione viene accettata il cliente può accedere a tutte le risorse condivise senza
doversi autenticare nuovamente a ogni accesso.
Il controllo delle utenze viene effettuato dal servente Samba in base al contenuto del file dei
suoi utenti che solitamente è ‘/etc/samba/smbpasswd’ (si può cambiare il nome del file o il
percorso tramite il parametro ‘smb passwd file =’).
Gli utenti Samba vengono aggiunti con il comando ‘smbpasswd’ illustrato in un paragrafo
successivo.
È di fondamentale importanza notare che comunque il nome utente Samba deve coincidere con il
nome di un utente definito nel sistema GNU/Linux, in quanto quest’ultimo deve essere sempre in
grado di assegnare un proprietario «valido» agli eventuali file creati o copiati dall’utente conneso
all’interno della risorsa condivisa.
Questa esigenza può costituire un problema, ad esempio per la limitazione a otto caratteri dei
nominativi-utente di GNU/Linux, che viene in parte superato grazie all’uso di un file di corrispondenza tra utenti GNU/Linux e utenti MS-Windows, il cui nome è indicato con la direttiva ‘username map =’. Un valore abbastanza comune di tale parametro è ‘/etc/samba/
smbusers’. Tale file conterrà delle righe così formate:
nome_linux = nome_smb_1 nome_smb_2
...
Per ovvi motivi di sicurezza, entrambi i file ‘smbusers’ e ‘smbpasswd’, devono essere
accessibili sia in scrittura che in lettura dal solo utente ‘root’.
207.3.1.3 Livello di sicurezza «server»
Con l’impostazione ‘security = server’ si ha lo stesso controllo di accesso visto nel caso
di ‘user’ con la differenza che l’utenza viene controllata su un servente esterno (solitamente un
PDC MS-Windows) il cui nome (NetBIOS) viene indicato con la direttiva ‘password server
=’.
207.3.1.4 Livello di sicurezza «domain»
Con l’impostazione ‘security = domain’ si ha ancora lo stesso controllo di accesso visto nel
caso di ‘user’, ma questa volta il servente Samba va a inserirsi in un dominio MS-Windows
NT/2000.
Per ottenere questo risultato occorre fermare i demoni di Samba, quindi aggiungere il servente
Samba al dominio NT sul PDC usando il server manager di MS-Windows NT oppure a una
active directory sul servente MS-Windows 2000 con la MMC (Microsoft management console)
attraverso lo strumento «Utenti e computer di Active Directory». A questo punto si deve eseguire
il comando:
smbpasswd -j nome_dominio -r nome_server -Unome_utente %parola_d’ordine
Il nome_dominio deve essere lo stesso indicato nella direttiva ‘workgroup’ di ‘smb.conf’;
il nome_server deve coincidere con il valore di ‘password server’; nome_utente e relativa parola_d’ordine devono rappresentare un’utenza con privilegi sufficienti ad aggiungere
un’utenza nuova nella macchina MS-Windows NT/2000.
2254
Servente Samba
Ultimate queste operazioni occorre naturalmente riavviare il servizio Samba.
Il vantaggio principale dell’impostazione ‘domain’ rispetto a quella ‘server’ consiste nel fatto
che il PDC risulta meno carico, in quanto non è più necessaria una connessione di rete permanente
tra esso e il servente Samba. Quest’ultimo infatti effettua una chiamata RPC (Remote procedure
call) solo al momento dell’autenticazione e non necessita di essere costantemente connesso al
PDC come avviene nel caso del livello di sicurezza ‘server’.
Per concludere occorre notare che comunque anche con questo tipo di impostazione (come pure
per quella ‘server’) è necessario tenere allineati gli elenchi degli utenti dal lato MS-Windows e
dal lato GNU/Linux (il motivo è stato illustrato nel paragrafo del livello ‘user’). Ci sono però due
direttive della sezione ‘global’ che permettono di automatizzare l’aggiornamento degli utenti
GNU/Linux:
add user = script_1 %u
delete user = script_2 %u
La prima entra in azione quando, a seguito di una connessione di un cliente MS-Windows, Samba
si rivolge al servente di dominio per l’autenticazione con esito positivo ma l’utente GNU/Linux
corrispondente non esiste; ovviamente lo script script_1 deve essere scritto in modo adeguato
affinché crei l’utente ricevendolo come parametro dalla variabile ‘%u’.
In modo speculare si usa l’altra direttiva che entra in azione quando, a seguito di una connessione
di un cliente MS-Windows, Samba si rivolge al servente di dominio per l’autenticazione con esito
negativo ma il corrispondente utente GNU/Linux esiste; in questo caso script_2 deve provvedere
a cancellare l’utente in questione.
207.3.2 smb.conf: sezioni generiche di condivisione
Una sezione indicante una risorsa condivisa può avere un nome a piacere purché sempre
racchiuso tra parentesi quadrate.
Vengono adesso illustrati alcuni esempi allo scopo di descrivere almeno le direttive più
importanti:
#
# condivisione 1: una directory accessibile solo a certi utenti
#
[Pagine WWW]
comment = Dir per le pagine web
browseable = yes
public = no
path = /var/www
writable = yes
valid users = utente1 utente2
La direttiva ‘comment’ serve ad associare una descrizione alla risorsa condivisa.
L’opzione ‘browseable’ permette di rendere visibile o no la risorsa agli utenti che si connettono
al servente.
‘public’ è un sinonimo di ‘guest ok’; in questo esempio non si vuole che la risorsa sia
accessibile per l’utente generico.
‘path’ permette di indicare il percorso della risorsa sul sistema GNU/Linux.
‘writable’ serve a concedere o negare l’accesso in scrittura (un sinonimo è ‘writeable’.
‘valid users’ indica quali sono gli utenti che possono accedere alla risorsa. È anche possibile
indicare gruppi di utenti GNU/Linux con la sintassi ‘+nome_gruppo ’ e gruppi di utenti NIS (ov-
Servente Samba
2255
viamente deve essere presente in rete un servente NIS) con la sintassi ‘&nome_gruppo ’ e anche
entrambi con la sintassi ‘+&nome_gruppo ’ o ‘&+nome_gruppo ’, o ancora ‘@nome_gruppo ’.
#
# condivisione 2: una directory pubblica = accessibile a tutti
#
[public]
comment = Dir pubblica
browseable = yes
guest ok = yes
path = /usr/local/public
writable = yes
#
# condivisione 3: una directory pubblica = accessibile a tutti in cui tutti
# gli utenti possano creare, modificare, cancellare tutti i file
#
[temp]
comment = Dir pubblica plus
browseable = yes
guest ok = yes
guest only = yes
path = /tmp
writable = yes
La differenza tra le due condivisioni è molto sottile ma anche interessante. La presenza di ‘guest
ok = yes’ permette le connessioni anonime; eventuali file creati o copiati nella directory sarebbero di proprietà dell’utente indicato in ‘guest account’ in caso di accesso anonimo, oppure
dell’utente effettivo in caso esso fosse registrato in GNU/Linux. Se è presente anche ‘guest
only = yes’ invece il proprietario è sempre l’utente fittizio ‘ospite’ anche nel caso l’utente
collegato fosse riconosciuto regolarmente da GNU/Linux; in questo caso quindi tutti gli utenti
possono fare tutte le operazioni con qualsiasi file presente nella directory condivisa.
Un modo alternativo per ottenere lo stesso risultato è quello di usare la direttiva ‘force user =
nome_utente ’; in questo modo Samba assegna lo stesso nominativo-utente a chiunque si connetta
alla risorsa.
#
# condivisione 4: un cd-rom
#
[cd]
comment = CD-ROM
preexec = mount /mnt/cdrom
postexec = umount /mnt/cdrom
browseable = yes
public = yes
path = /mnt/cdrom
writable = no
Il significato delle impostazioni è ovvio compreso quello delle due opzioni ‘preexec’ e
‘postexec’. In caso si tema che possano connettersi utenti sprovvisti dei privilegi per montare e smontare il CD, si possono sostituire le due direttive rispettivamente con ‘root preexec’
e ‘root postexec’ che svolgono lo stesso compito ma con i privilegi dell’utente ‘root’.
2256
Servente Samba
#
# condivisione 5: una directory privata con permessi preimpostati
#
[privata]
comment = Dir privata
browseable = yes
path = /usr/local/private
writable = no
public = no
write list = pippo pluto
create mask = 0644
directory mask = 0644
In questo esempio nella directory non sarebbe possibile scrivere, ma la presenza della direttiva
‘write list’ permette di impostare permessi di scrittura, per gli utenti indicati, indipendentemente da quanto specificato negli altri parametri. Si deve però notare che i permessi impostati a
livello di sistema su quella risorsa hanno sempre il sopravvento su quanto specificato nel file di
configurazione di Samba (in altre parole, se ‘/usr/local/private’ è di proprietà dell’utente
‘root’ e i permessi sono impostati a 6008, gli altri utenti non possono né leggere né scrivere
alcunché in quella directory condivisa).
Le ultime due direttive, infine, servono a indicare i permessi con cui verranno creati file e
directory all’interno della risorsa condivisa; il valore predefinito è 07558
Altre direttive importanti sono:
admin users = tizio
follow symlinks = no
Con la prima si indica che l’utente ‘tizio’ ha gli stessi privilegi dell’utente ‘root’ sulla condivisione e quindi non risente di eventuali limitazioni dovute ai permessi sui file; con la seconda si
impedisce che vengano seguiti i collegamenti simbolici evitando che chi accede alla condivisione
possa accedere anche a file che si trovano all’esterno di questa.
207.3.3 smb.conf: sezione «homes»
La sezione ‘homes’ viene utilizzata affinché ogni utente possa avere accesso a una propria directory personale sul servente Samba che potrà anche coincidere con la directory personale
GNU/Linux di quell’utente. Un esempio di definizione può essere il seguente:
#
# directory personali degli utenti
#
[homes]
comment = directory home
browseable = no
writable = yes
path = usr/local/samba/%S
Qui è importante l’impostazione che impedisce la scansione della risorsa in modo che essa non
appaia con il nome ‘homes’ a tutti gli utenti.
La presenza di ‘path’ serve a fare in modo che questa directory non coincida con quella
GNU/Linux dell’utente (cosa che sarebbe l’impostazione predefinita).
La logica di funzionamento è la seguente: quando l’utente si connette, se l’utenza è accettata,
viene creata dal servente Samba una condivisione con le caratteristiche specificate nella sezione
‘homes’ ma con un nome uguale a quello dell’utente connesso.
Servente Samba
2257
207.3.4 smb.conf: sezione «printers»
Con questa sezione si impostano i parametri di configurazione di tutte le stampanti definite nel
sistema GNU/Linux a patto che nella sezione ‘global’ siano state inserite le direttive seguenti:
load printers = yes
printcap name = /etc/printcap
L’alternativa, che consiste nel definire le varie stampanti come singole risorse condivise, non
viene presa in esame in questa sede.
Un esempio di configurazione per le stampanti è il seguente:
#
# Stampanti
#
[printers]
comment = stampanti
path = /var/spool/samba
browseable = no
printable = yes
public = yes
writable = no
Qui occorre notare che il parametro ‘path’ serve a impostare una directory per la coda di stampa,
diversa da ‘/tmp/’ che è quella predefinita.
Altra direttiva da segnalare è ‘printable’ con la quale si attiva la coda di stampa.
207.4 Programmi ausiliari per un servente Samba
Un primo strumento molto utile è ‘testparm’ con il quale si verifica la correttezza sintattica
delle impostazioni scritte nel file ‘smb.conf’.
Il comando da eseguire è:
# testparm /etc/samba/smb.conf
si ottiene una risposta suddivisa in due parti: prima il resoconto del controllo sintattico del file di
configurazione, poi l’elenco delle risorse condivise descritte in esso.
Altro programma di fondamentale importanza è ‘smbpasswd’, già visto in precedenza a proposito della connessione di Samba a un dominio MS-Windows NT, ma che si usa principalmente
per definire utenti e parole d’ordine relative. La sintassi in questo caso è:
smbpasswd
[-a] [-x] [nominativo ]
L’opzione ‘-a’ permette di inserire un nuovo utente e poi di definirne la parole d’ordine; l’opzione ‘-x’ permette invece di eliminarlo; se non si indica alcuna opzione si esegue solo il cambio
della parole d’ordine per l’utente. Il nominativo-utente che si può inserire alla fine della riga di
comando è quello sul quale il comando opera (se non viene indicato, si fa riferimento in modo
predefinito all’utente GNU/Linux che esegue il comando).
Altro strumento utile è lo script ‘smbadduser’ che permette di definire un nuovo utente Samba
e contemporaneamente l’associazione con utenti GNU/Linux corrispondenti. La sintassi è:
smbadduser utente_linux :utente_smb
[utente_linux :utente_smb ]...
In pratica questo comando aggiorna i file ‘smbpasswd’ e ‘smbusers’, permettendo di definire
la parola d’ordine per i nuovi utenti Samba.
2258
Servente Samba
Infine può essere molto utile anche il comando ‘smbstatus’ per avere un rapporto (con l’opzione
‘-d’ anche dettagliato) delle connessioni Samba attive.
Maggiori dettagli sulla configurazione di un servente Samba si possono trovare anche nella documentazione fornita insieme al pacchetto in ‘/usr/share/doc/samba-x.y.z ’, oppure
consultando la pagina di manuale smb(5).
Capitolo
208
Samba dal lato cliente
Da una macchina GNU/Linux è possibile connettersi a un servente Samba o a macchine MSWindows per accedere alle risorse che queste condividono grazie a una serie di strumenti che
costituiscono il «lato cliente» di Samba.
208.1 smbclient
Il primo programma da esaminare è ‘smbclient’ che si usa fondamentalmente in due maniere:
smbclient -L nome_server_samba
per avere la lista delle risorse condivise dal servente; oppure:
smbclient nome_servizio
[-U
nominativo_utente
]
per connettersi alla risorsa nome_servizio (ad esempio ‘//serversamba/public’). Se la connessione ha successo si ha a disposizione un’interfaccia testuale del tutto simile a quella del
programma ‘ftp’ tradizionale, dove si possono eseguire più o meno gli stessi comandi (‘get’,
‘put’, ‘cd’, ‘pwd’, ecc.).
Un’opzione importante è ‘-I’ seguita da un numero IP, con la quale si può appunto indicare il
numero IP del servente a cui ci si vuole connettere.
208.2 smbmount
Sicuramente l’interfaccia messa a disposizione da ‘smbclient’ non è il massimo della comodità;
sarebbe molto meglio poter disporre della risorsa condivisa da un’altra macchina come se fosse
una risorsa locale. Anche questo si può ottenere con Samba, in particolare grazie a ‘smbmount’.
La sintassi è:
smbmount nome_servizio punto_di_innesto
[-o
]
opzioni
Ad esempio:
# smbmount //serversamba/public /mnt/dirsamba -o username=tizio%parola_d’ordine
Per smontare la risorsa si può usare il comando:
smbumount punto_di_innesto
È anche possibile ottenere l’inserimento automatico della risorsa all’avvio di GNU/Linux con la
riga seguente nel file ‘/etc/fstab’:
//serversamba/public
/mnt/dirsamba
smbfs
username=tizio%parola_d’ordine
È importante ribadire che in questa sede non viene illustrata la sintassi completa dei vari comandi con l’elenco di tutte le opzioni possibili. Per avere queste informazioni si deve consultare la documentazione dei vari pacchetti e il manuale in linea (per esempio
smbpasswd(8)).
2259
2260
Samba dal lato cliente
208.3 Uso con Samba di stampanti MS-Windows
Per usare su una macchina GNU/Linux una stampante condivisa da una macchina MS-Windows,
occorre impostare in modo opportuno il file di definizione delle stampanti GNU/Linux: ‘/etc/
printcap’.
Ecco un esempio di righe di configurazione da aggiungere a tale scopo:
stsamba:\
:mx=0:\
:sh:\
:sd=/var/spool/lpd/stsamba:\
:lp=/dev/null:\
:af=/var/spool/lpd/stsamba/acct:\
:if=/usr/bin/smbprint:
Una breve spiegazione sul significato di queste righe è necessaria, anche se lo studio del file di
configurazione delle stampanti in GNU/Linux esula dallo scopo di questo documento:
‘mx=0’ indica nessun limite di grandezza dei file da stampare;
‘sd=’ indica la directory della coda per questa stampante;
‘lp=/dev/null’ indica che la stampante non è collegata ad alcuna porta (non è locale);
‘af=’ indica il nome del file per registrare le transazioni;
‘if=’ indica il nome del filtro da usare per la stampa; quello usato nell’esempio è un filtro fornito
in modo predefinito con la distribuzione Red Hat all’interno del pacchetto ‘samba-client’.
Affinché il tutto funzioni è poi necessaria la presenza del file ‘.config’ nella directory della
coda indicata con la riga ‘sd=’. Un esempio del suo contenuto è il seguente:
share="//server_smb /nome_stampante_condivisa "
user="tizio"
password="blablabla"
Data la complessità della configurazione manuale di una stampante SMB in GNU/Linux (e anche di una stampante in generale), può essere consigliabile l’uso di strumenti appositi come
‘printconf-gui’ che semplificano molto queste operazioni.
208.4 Altri strumenti utili
Altri comandi presenti nel pacchetto ‘samba-client’ sono:
‘nmblookup’ che permette di trovare il numero IP di una macchina fornendo il nome NetBIOS;
‘findsmb’ che fornisce informazioni sui serventi Samba presenti in rete;
‘smbtar’ che permette di effettuare copie di sicurezza di risorse SMB su unità a nastro installate
sul servente GNU/Linux.
Per i dettagli di uso di questi comandi si rimanda ai rispettivi manuali in linea.
Capitolo
209
Samba come servente WINS
In una rete basata su NetBIOS la risoluzione dei nomi è basata sull’invio di messaggi circolari;
quando un elaboratore con MS-Windows si collega in rete invia un messaggio a tutti informando
sul proprio nome e sul proprio indirizzo. È ovvio che un sistema di questo tipo può essere efficiente solo su piccole reti e in assenza di sottoreti multiple (i router di solito sono configurati per
bloccare i messaggi circolari).
La soluzione a questo problema proposta da Microsoft consiste nell’introduzione di un servente
WINS allo scopo di gestire una tabella contenente le associazioni tra nomi NetBIOS e indirizzi
IP. I clienti della rete hanno impostata l’indicazione del numero IP del servente WINS in modo
che, quando devono qualificarsi o chiedere informazioni circa l’identità di altre macchine, si
rivolgono direttamente al servente senza generare traffico superfluo.
Un servente Samba può essere configurato sia per svolgere la funzione di servente WINS sia per
essere cliente di un servente WINS già presente in rete (ovviamente non sono possibili entrambe
le impostazioni contemporaneamente).
Nella sezione ‘global’ si deve aggiungere il seguente parametro per attivare il servente WINS:
wins support = yes
Invece per indicare a Samba qual è il servente WINS già attivo in rete si usa:
wins server = 192.168.1.1
2261
Capitolo
210
Samba e la scansione della rete
In una rete locale le macchine hanno sempre una lista delle altre macchine attive che si chiama
lista di browse. Il servente che la gestisce si chiama master browser locale se riveste questo ruolo
solo per una sottorete, se invece mantiene la lista per tutta la rete locale diviene un master browser
di dominio.
Siccome in una rete le macchine possono essere collegate e scollegate in ogni momento, il master
browser locale aggiorna continuamente la lista e la invia alle macchine che ne fanno richiesta. Il
master browser di dominio invece raccoglie le liste di ogni sottorete e le mette a disposizione dei
master browser locali.
Un elaboratore diventa master browser locale a seguito di una «elezione» che può essere effettuata in qualunque momento (ad esempio quando un nuovo elaboratore si presenta in rete). Riguardo a tale elezione Microsoft assegna ai suoi sistemi operativi un valore, detto livello, che cresce
sempre di più per i sistemi operativi più recenti (ad esempio una macchina con MS-Windows 98
ha livello 2, una con MS-Windows NT 4 Workstation ha livello 17, una con MS-Windows NT
4-Server ha livello 32, una con MS-Windows 2000-Server ha livello 64).
L’elezione avviene sulla base di questo valore; in caso di parità viene esaminata la funzione svolta
dalla macchina (senza entrare in dettagli eccessivi, basti sapere che un PDC diviene sempre anche
PDM); in caso di ulteriore parità viene scelta la macchina che è da più tempo in rete.
Con Samba il livello per la partecipazione all’elezione può essere scelto in sede di configurazione.
Nell’esempio seguente vengono mostrate le direttive da inserire nella sezione ‘global’ affinché
il servente Samba sia master browser locale prevalendo su macchine MS-Windows equipaggiate
fino a NT-server:
local master = yes
os level = 34
preferred master = yes
La terza direttiva serve ad attivare il preferred master bit del servente Samba, in modo che
il proprio servente prevalga al momento dell’elezione su macchine con uno stesso sistema
operativo.
Se si vuole che il servente Samba divenga master browser di dominio occorre inserire anche:
domain master = yes
In caso però che il servente partecipi a un dominio NT è preferibile che il ruolo di master browser
di dominio sia lasciato al PDC (che comunque, come viene descritto nel prossimo capitolo, può
essere lo stesso servente Samba).
A proposito della scansione della rete, nel caso siano presenti sottoreti multiple, è opportuno
ricordare le seguenti regole generali:
• ci deve essere una macchina MS-Windows o Samba che faccia da master browser locale per
ciascuna sottorete (se nella sottorete c’è gia un master browser di dominio non è necessario
anche il master browser locale);
• almeno una macchina MS-Windows o Samba deve essere master browser di dominio per il
gruppo di lavoro;
• ogni master browser locale deve sincronizzarsi con il master browser di dominio.
In caso nella rete non sia presente un master browser di dominio e ci siano però delle sottoreti multiple, Samba mette a disposizione due direttive utili per la sincronizzazione (da inserire
sempre nella sezione ‘global’):
2262
Samba e la scansione della rete
2263
remote announce = 192.168.1.255/INF 192.168.2.255/INF
remote browse sync = 192.168.3.255 192.168.4.255
Con ‘remote announce’ il servente Samba fornisce l’elenco di scansione anche ad altre sottoreti. Se si conoscono i numeri IP dei master browser locali si possono indicare tali numeri,
altrimenti (come nell’esempio) si indicano degli indirizzi broadcast. In pratica con i valori indicati, il servente Samba segnalerà la sua presenza a tutte le macchine delle sottoreti 192.168.1.
e 192.168.2. (del gruppo di lavoro INF) e quindi anche ai relativi master browser locali.
*
*
L’altra direttiva ha uno scopo simile nel caso però i master browser locali delle sottoreti siano
altri serventi Samba (anche in questo caso si possono indicare gli indirizzi precisi dei servente
o degli indirizzi broadcast). Nell’esempio, un servente Samba contatta altri serventi Samba delle
sottoreti 192.168.3. e 192.168.4. , con i quali sincronizza le liste di scansione.
*
*
A proposito della possibilità di usare gli indirizzi broadcast ci si deve sincerare che i router della
rete non siano configurati per bloccare il traffico broadcast tra sottoreti diverse.
Capitolo
211
Autenticazione di utenti MS-Windows con
Samba
A partire dalla versione 2.0 è possibile configurare Samba come domain controller e autenticare gli utenti degli elaboratori clienti MS-Windows 95/98 sostituendo un servente MS-Windows
NT/2000.
Con la versione 2.1 è stata data la possibilità di accreditare anche clienti MS-Windows NT.
Dalla versione 2.2, che è la più recente, Samba può accreditare anche clienti MS-Windows
2000/XP, partecipare a una ADS (Active directory service) ed è stato aggiunto il demone
‘winbind’ che consente di usare un domain controller MS-Windows come servente per le utenze, allineando del tutto le utenze di GNU/Linux con quelle di MS-Windows e centralizzando la
loro gestione su un solo sistema.
È sicuramente anche il caso di elencare ciò che Samba non può fare (almeno per il momento):
• utilizzo di BDC (Backup domain controller) in domini NT e Active directory replication
con MS-Windows 2000;
• partecipazione ad alcun tipo di trust relationship;
• sostituzione di un MS-Windows 2000-Server.
In questa sede viene presa in esame solo la configurazione di Samba come PDC per
l’accreditamento di clienti MS-Windows 95/98/Me/NT.
Di seguito viene presentato un possibile file ‘smb.conf’ con le definizioni necessarie affinché
Samba sia un PDC:
[global]
netbios name = ServerSamba
workgroup = INF
server string = Samba Server NT
log file = /var/log/samba/%m.log
max log file = 50
security = user
encrypt password = yes
smb password file = /etc/samba/smbpasswd
local master = yes
preferred master = yes
os level = 33
domain master = yes
;
domain logons = yes
;
# script di accesso fisso per tutti
logon script = logon.bat
# oppure uno per ogni cliente
; logon script = %m.bat
# oppure uno per ogni utente
; logon script = %U.bat
;
# profili utenti
logon path = \\ServerSamba\profile\%U
[netlogon]
comment = Directory degli script di inizializzazione
2264
Autenticazione di utenti MS-Windows con Samba
2265
path = /home/netlogon
read only = yes
guest ok = yes
browseable = no
[home]
comment = Dir utente
path = /home/%U
browseable = yes
writable = yes
[public]
comment = Dir pubblica
path = /home/public
browseable = yes
writable = yes
public = yes
create mask = 0777
211.1 Domain logons
È la direttiva che permette di configurare Samba come PDC in quanto lo imposta come servente
di autenticazione di dominio.
211.2 Logon script
Samba consente l’esecuzione degli script di accesso di MS-Windows (‘.BAT’ o ‘.CMD’). Tali
script vengono eseguiti sul cliente al momento della connessione di un utente al dominio ma sono
memorizzati sul servente e vengono quindi trasferiti attraverso la rete. Ovviamente sono molto
utili per impostare dinamicamente le configurazioni di rete per gli utenti quando si connettono.
L’opzione ‘logon script’ permette appunto di indicare il nome dello script da eseguire quando
l’utente si collega; come si vede dall’esempio può essere uno script unico, valido per tutti, oppure
dipendente dal cliente o dal nome utente.
Sul servente GNU/Linux questi script vengono memorizzati nella directory indicata nella
condivisione ‘netlogon’, che viene descritta più avanti.
Una cosa importante da ricordare è che gli script di accesso vengono eseguiti in ambiente MSWindows e devono essere quindi scritti con righe terminanti con i caratteri di <CR> e <LF>,
invece del solo <LF> di un sistema GNU/Linux.
L’esempio seguente di script di accesso, definisce un disco di rete ‘W:’ su una condivisione di
Samba:
echo Connette disco di rete
net use w: \\ServerSamba\dati
211.3 Logon path
In MS-Windows 95/98 ciascun utente può avere il proprio profilo comprendente informazioni
sull’aspetto della scrivania grafica, sulle applicazioni che appaiono nel menù Start, sullo sfondo
e altre ancora. Tale profilo può essere memorizzato direttamente su un elaboratore cliente e si
chiama allora «profilo locale», oppure sul servente e si chiama «profilo di roaming», in quanto
l’utente ha a disposizione sempre lo stesso ambiente anche spostandosi da un cliente all’altro.
La direttiva ‘logon path’ viene usata per indicare dove vengono memorizzati i profili dei vari
utenti.
2266
Autenticazione di utenti MS-Windows con Samba
211.4 Logon home e logon drive
Con ‘logon home’ si indica la posizione della directory personale di un utente, che può essere
diversa da quella indicata nella sezione ‘homes’.
Con ‘logon drive’, da usare solo in caso di clienti MS-Windows NT, si indica la lettera del
disco su un client in cui vengono abbinate le directory personali indicate con ‘logon home’.
211.5 Sezione [netlogon]
In questa sezione viene configurata una condivisione speciale che serve a contenere gli script di
accesso. La configurazione scelta nell’esempio (sola lettura, pubblica, non visibile alla scansione
delle risorse) è dettata dal ruolo particolare che svolge.
211.6 Definizione delle utenze per macchina
Nel caso nella rete siano presenti dei clienti MS-Windows NT, per essi devono essere creati
sul PDC i cosiddetti machine account in aggiunta alle utenze normali. Ovviamente, tali utenze
speciali devono essere inserite sia come utenti Samba che come utenti del sistema GNU/Linux
che ospita il servente. Tale operazione può essere fatta in modo automatico (direttiva ‘add user’
illustrata in precedenza) oppure manualmente, con i seguenti comandi:
/usr/sbin/useradd -d /dev/null -g 100 -c"descrizione_dell’elaboratore_client " ←,→-s /bin/false nome_elaboratore $
passwd -l nome_elaboratore $
smbpasswd -a -m nome_elaboratore
È necessario prestare attenzione al carattere ‘$’ alla fine del nome della macchina nel primo e nel
secondo comando.
Il secondo comando permette di bloccare la parola d’ordine di quell’utente fittizio.
Con il terzo comando si definisce l’utente ‘nome_elaboratore ’ per Samba grazie all’opzione ‘-m’.
Capitolo
212
Accesso a GNU/Linux da parte di utenti di un
dominio MS-Windows con Winbind
In precedenza, nel capitolo sull’impostazione di un servente Samba, è stato illustrato come integrare quest’ultimo in un dominio MS-Windows NT o in una active directory di MS-Windows
2000. In particolare si è visto come questo sia possibile impostando il livello di sicurezza al
valore ‘domain’ ed eseguendo un opportuno comando ‘smbpasswd’.
Grazie a Winbind, un nuovo strumento di Samba presente dalla versione 2.2.2, diventa addirittura
possibile l’autenticazione degli utenti GNU/Linux (attenzione: utenti GNU/Linux, non utenti
Samba) presso il domain controller windows. Ciò può essere molto utile in quei contesti in cui si
vogliano inserire elaboratori con GNU/Linux in reti già consolidate su piattaforma MS-Windows,
utilizzando le informazioni su utenti e gruppi preesistenti senza essere costretti a ridefinirle anche
per le macchine GNU/Linux.
Winbind è costituito da un piccolo gruppo di componenti disponibili all’interno del pacchetto
‘samba-common’; in dettaglio ne fanno parte:
• una libreria per il NSSwitch (Name service switch);
• una libreria per i moduli PAM (Pluggable authentication modules);
• un programma di servizio, ‘wbinfo’, e un demone, ‘winbindd’.
Il servizio NSSwitch è presente in tutte le moderne librerie C e permette di ottenere i dati relativi
a utenti, gruppi e nodi, da varie fonti (ad esempio NIS, DNS, ecc.); Winbind diventa un’ulteriore
fonte di informazioni per NSSwitch relativamente a utenti e gruppi di un dominio MS-Windows.
Il PAM è un sistema generalizzato per la gestione dei metodi di autenticazione per molteplici servizi (quelli per cui esistono le librerie PAM relative); grazie all’apposita libreria PAM, Winbind
fornisce anche il servizio di autenticazione.
212.1 Configurazioni necessarie
212.1.1 smb.conf
Per configurare il servizio Winbind occorre intervenire innanzitutto nel file ‘smb.conf’
inserendo le direttive seguenti:
workgroup name = nome_dominio_NT
encrypt password = yes
security = domain
password server = nome_PDC_WIN
; impostazioni per il demone winbindd
winbind separator = +
template shell = /bin/bash
template homedir = /home/%D/%U
winbind uid = 10000-20000
winbind gid = 10000-20000
winbind enum users = yes
winbind enum groups = yes
Con ‘winbind separator’ si imposta il carattere usato per ottenere il nome utente GNU/Linux
dall’unione di nome di dominio e nome utente NT; il valore predefinito corrisponde a ‘\’, ma è
2267
2268Accesso a GNU/Linux da parte di utenti di un dominio MS-Windows con Winbind
sconsigliabile, in quanto ha un significato speciale nella shell di GNU/Linux; invece, la scelta del
carattere ‘+’ dovrebbe essere quella migliore.
Con ‘template shell’ si imposta la shell degli utenti.
Con ‘template homedir’ si definisce la directory personale degli utenti; nell’esempio si usano
le variabili ‘%D’ e ‘%U’ in modo che ogni utente abbia come directory ‘/home/nome_dominio_nt /
nome_utente_nt ’.
‘winbind uid’ e ‘winbind gid’ permettono di impostare gli intervalli di numeri di identifica-
zione per utenti e gruppi che Winbind utilizza per riabbinare gli utenti e i gruppi MS-Windows a
utenti e gruppi GNU/Linux.
‘winbind enum users’ e ‘winbind enum groups’ permettono di attivare l’enumerazione di
gruppi e utenti.
212.1.2 Modifiche ai file di configurazione dei moduli PAM
Le modifiche ai file di configurazione dei moduli PAM devono essere effettuate con molta attenzione in quanto errori in questa fase possono causare anche l’impossibilità di accedere. Può quindi essere opportuno fare una copia dei file interessati alle modifiche in modo da poter ripristinare
la situazione precedente in ogni momento.
Maggiori informazioni sul funzionamento dei moduli PAM non possono essere fornite in questa
sede; eventualmente si può consultare il capitolo 56.
Nel file ‘/etc/pam.d/system-auth’ deve essere aggiunta la riga:
auth
sufficient
/usr/lib/security/pam_winbind.so
dopo la prima riga ‘auth’ già presente e trasformata la riga:
auth
sufficient
/lib/security/pam_unix.so
likeauth
nullok
in:
auth
sufficient
/lib/security/pam_unix.so
likeauth
nullok
use_first_pass
Nel file ‘/etc/pam.d/login’ devono essere aggiunte le seguenti due righe, rispettivamente
come prima riga ‘account’ e come ultima riga ‘session required:’
account
sufficient /lib/security/pam_winbind.so
...
session
required
/lib/security/pam_mkhomedir.so
skel=/etc/skel/
umask=0022
L’ultima è molto importante in quanto permette la creazione automatica della directory personale
dell’utente al primo accesso alla macchina GNU/Linux.
Riguardo la modifica al file ‘system-auth’ occorre osservare che, essendo la sua configurazione
usata, attraverso il modulo ‘pam_stack’, in molti altri file di configurazione dei moduli PAM (e
non solo in ‘login’), sarebbe più opportuno lasciarlo invariato definendone uno nuovo con le
modifiche e con nome leggermente diverso. Se si opta per questa scelta è ovvio che si devono
modificare opportunamente i riferimenti al file ‘system-auth’ contenuti nel file ‘login’.
Accesso a GNU/Linux da parte di utenti di un dominio MS-Windows con Winbind 2269
212.1.3 Modifiche alla configurazione di NSSwitch
Nel file ‘/etc/nsswitch.conf’, contenente la configurazione del servizio NSSwitch, è
necessario aggiungere Winbind tra le fonti dei dati relativi a utenti e gruppi. Ad esempio:
passwd:
group:
files winbind
files winbind
L’ordine con cui vengono elencate le fonti è significativo e quindi è opportuno lasciare la priorità
a ‘files’ in modo che per primi siano interrogati i file di sistema (‘/etc/passwd’ e ‘/etc/
group’).
212.2 Attivazione
Per prima cosa occorre inserire la macchina GNU/Linux nel dominio MS-Windows operando
come illustrato nel capitolo relativo alla configurazione di un servente Samba, nel paragrafo sul
livello di sicurezza ‘domain’ (207.3.1.4).
Occorre poi avviare i servizi ‘smb’ e ‘winbind’:
# /etc/rc.d/init.d/smb start
# /etc/rc.d/init.d/winbind start
Si può verificare il buon funzionamento di Winbind con i comandi:
# wbinfo -u
# wbinfo -g
con i quali si elencano rispettivamente utenti e gruppi del dominio MS-Windows.
Si possono usare anche i comandi:
# getent passwd
# getent group
per ottenere gli elenchi di tutti gli utenti e gruppi utilizzabili, sia quelli del dominio che quelli
propri di GNU/Linux.
Infine si può procedere all’accreditamento sulla macchina GNU/Linux di un utente del dominio
MS-Windows ricordando che il nome utente è dato da ‘nome_dominio_nt +nome_utente_nt ’ e la
parola d’ordine è ovviamente la stessa utilizzata in ambiente MS-Windows.
Capitolo
213
Samba e DFS
Il DFS (Distributed file system), introdotto con MS-Windows 2000, permette di organizzare le
condivisioni di rete in una struttura ad albero svincolando gli utenti di tali risorse dalla conoscenza della reale collocazione delle stesse sui vari serventi. Con MS-Windows 95/98/NT è invece necessario, quando si deve connettere una risorsa, conoscere esattamente la sua collocazione in rete;
si può ovviare in parte a questo inconveniente connettendo permanentemente la risorsa all’avvio
dell’elaboratore cliente, ma in caso di spostamento della risorsa il problema si ripresenta.
Con il DFS si vengono a creare dei «volumi di rete» che possono essere ispezionati come fossero
residenti fisicamente su un solo servente. La struttura può poi essere duplicata, tutta o in parte,
per ottenere maggiori garanzie contro le perdite di dati accidentali.
Ogni struttura DFS ha una radice comune a tutte le condivisioni e numerose diramazioni (foglie),
tutte di primo livello. Un servente può ospitare una sola radice mentre le foglie possono anche
essere ospitate su macchine diverse. Sarebbe anche possibile ottenere strutture più complesse
annidando radici di DFS come foglie di altri DFS ma qui non si considera tale possibilità.
Samba può assumere il ruolo di servente DFS e ospitare una radice di un volume DFS grazie alla
seguente direttiva nella sezione ‘global’:
host msdfs = yes
e alla definizione di questa nuova sezione:
[dfs]
path = /dir-expo/dfs
msdfs root = yes
Nella directory ‘/dir-expo/dfs’ del servente GNU/Linux si dovranno poi impostare i
collegamenti simbolici agli altri serventi della rete procedendo come nell’esempio seguente:
# cd /dir-expo/dfs
# chown root /dir-expo/dfs
# chmod 755 /dir-expo/dfs
# ln -s msdfs:serverA\\shareA coll-a
# ln -s msdfs:serverB\\shareBC,serverC\\shareBC coll-bc
Il secondo collegamento dell’esempio associa a un solo nome di risorsa DFS, due condivisioni:
queste saranno in fault tolerance tra di loro e l’allineamento dei dati al loro interno sarà assicurato
dal servente DFS.
Grazie alla definizione dei collegamenti simbolici, quando un cliente si collega a una risorsa
DFS, viene ridiretto, in modo del tutto trasparente e automatico, verso la macchina che ospita
fisicamente i dati condivisi.
2270
Parte xl
Programmare in PHP
Gianluca Giusti <brdp @ urcanet.it>
2002.11.05
2271
Gianluca Giusti si è diplomato in Informatica presso l’ITIS de L’Aquila, attualmente frequenta
il corso di laurea in Fisica presso la Facoltà di Scienze MM.NN.FF. dell’Università de L’Aquila
Lavora come analista programmatore nella città di Roma allo sviluppo di portali, siti di
commercio elettronico, software di BI.
È appassionato di amministrazione di sistema, in particolare GNU/Linux, e di reti informatiche.
Programmare in PHP
Copyright © 2001-2002 Gianluca Giusti
brdp @ urcanet.it
This information is free; you can redistribute it and/or modify it under the terms of the GNU
General Public License as published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
This work is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this work; if
not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Una copia della licenza GNU General Public License, versione 2, si trova nell’appendice A.
2272
non modificare
;)
2273
L’indirizzo della versione aggiornata dell’opera "Programmare in PHP" è:
<http://www.urcanet.it/brdp/php_manual/>
Al momento l’opera è incompleta, tuttavia ho ritenuto opportuno pubblicare quanto fatto. Scrivo questo documento nel tempo libero e ultimamente ne ho davvero poco quindi aggiornerò il
contenuto ogni volta che un argomento sarà completato.
Gli script di esempio sono contenuti e raggruppati per capitolo all’indirizzo <http://www.urcanet.it/
brdp/php_manual/esempi/>
L’opera è inclusa in "Appunti di informatica libera" di Daniele Giacomini.
La diffusione di questo documento è incoraggiata in base ai termini della licenza.
2274
Prefazione . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2277
214 Avere le idee chiare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2278
214.1 Cos’è il PHP? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2278
214.2 Cosa può fare il PHP? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2281
214.3 PHP su piattaforma Microsoft . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2281
214.4 Quanto costa il PHP? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2281
215 Le basi del linguaggio . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2282
215.1 La sintassi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2282
215.2 Primo script . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2284
215.3 Tipi di dati . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2285
215.3.1
215.3.2
215.3.3
215.3.4
215.3.5
215.3.6
integer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2286
boolean . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2287
double . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2287
string . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2288
array . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2289
object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2293
215.4 Operatori . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2293
215.4.1
215.4.2
215.4.3
215.4.4
215.4.5
215.4.6
Operatori aritmetici . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2293
Operatori di assegnazione . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2294
Operatori di controllo degli errori . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2295
Operatori di incremento e decremento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2296
Operatori logici . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2297
Operatori di confronto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2297
215.5 Strutture di controllo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2297
215.5.1 if . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2298
215.5.2 else . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2299
215.5.3 elseif . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2300
215.5.4 switch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2302
215.5.5 while . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2303
215.5.6 do..while . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2305
215.5.7 for . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2305
215.5.8 foreach . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2306
215.5.9 break . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2308
215.5.10 include() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2309
216 Passaggio di variabili tramite l’HTTP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2311
216.1 Metodo get . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2311
216.2 Metodo post . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2313
216.3 Quale metodo scegliere? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2313
216.4 Cosa è cambiato nel PHP versione 4.2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2314
217 L’utilizzo delle funzioni in PHP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2315
2275
217.1 Le funzioni predefinite . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2315
217.2 Le funzioni definite dall’utente . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2317
217.3 Le funzioni ricorsive . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2322
218 La gestione del file system . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2324
218.1 Concetto di file . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2324
218.2 Apertura di un file . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2324
218.3 Lettura di un file di testo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2325
218.4 Scrittura in un file di testo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2327
218.5 Accodare testo in un file . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2330
218.6 Conclusioni . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2332
Indice analitico del volume . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2333
2276
Prefazione
Questo documento vuole essere una guida all’utilizzo di uno dei più versatili e potenti linguaggi
di programmazione oggi diffuso in Internet. Il lettore non troverà un elenco delle funzioni del linguaggio, perché sarebbe inutile dal momento che queste notizie sono già disponibili nel manuale
ufficiale; al contrario, potrà trovare una guida all’utilizzo degli strumenti che gli sviluppatori del
linguaggio hanno messo a disposizione.
Naturalmente ognuno potrà ampliare e personalizzare gli script proposti come esempio; sarà la
guida stessa a sollevare dubbi e a suggerire delle modifiche, per il resto via libera all’immaginazione del lettore. Inutile dire che per qualsiasi problema la mia casella di posta è a vostra
disposizione compatibilmente con gli impegni.
Per la lettura della guida si darà per scontato:
• la configurazione corretta della macchina che offre i servizi, in cui devono essere installati il
servente HTTP (negli esempi di questa guida si fa riferimanto principalmente ad Apache),
il modulo PHP 4 e una base di dati (DBMS), che negli esempi proposti è costituita da
MySQL;
• la conoscenza del linguaggio HTML;
• un minimo di conoscenza del linguaggio SQL per l’interrogazione delle basi di dati di
prova.
Verranno risolti i problemi più comuni, progettati e realizzati i servizi necessari a un sito per
essere moderno, dinamico e al passo coi tempi. Si pensi alla gestione di utenze, aree riservate,
notizie, sondaggi, motori di ricerca, album fotografici, servizi FTP, ecc.
Per fare questo si partirà da esempi molto semplici, scritti in modo altrettanto semplice, fino ad
arrivare alla realizzazione di «classi» da utilizzare in tutti i nostri servizi.
Prima di iniziare converrà collegarsi al sito <http://www.php.net> per scaricare il manuale ufficiale
del PHP; sarà molto utile ed è importante saperlo consultare. Viene rilasciato in vari formati;
probabilmente il più conveniente è il formato PDF. In tal modo, si disporrà di un unico file su
cui poter effettuare ricerche di testo. Inoltre è importante ricordare che un gruppo di persone
sta traducendo il manuale in italiano ospitato sul sito ufficiale all’indirizzo <http://www.php.net/
manual/it/>. Chi volesse partecipare può mettersi in contatto con i coordinatori del progetto Luca
Perugini Simone Cortesi.
2277
Capitolo
214
Avere le idee chiare
Prima di addentrarsi nella programmazione, è bene capire quali sono gli strumenti a disposizione
e cosa permettono di fare. C’è molto interesse verso le tecnologie utilizzate in Internet, di conseguenza si crea spesso confusione. Una delle conseguenze più frequenti è ostinarsi a utilizzare un
linguaggio nato con uno scopo per realizzare tutt’altro.
214.1 Cos’è il PHP?
PHP sta per Hypertext Preprocessor. Dalla documentazione ufficiale il PHP viene definito come
un «linguaggio script dal lato del servente immerso nel codice HTML». Di seguito la definizione
nel dettaglio:
«linguaggio script»: il PHP è un vero e proprio linguaggio di programmazione, è importante
rendersi conto che l’HTML, ad esempio, non è un linguaggio di programmazione ma un linguaggio di descrizione e formattazione del testo. Inoltre, per i più esperti, il PHP è un linguaggio
interpretato.
«Dal lato del servente»: queste le parole fondamentali. Il codice PHP inserito tra i marcatori HTML viene interpretato dall’elaboratore servente e non dal navigatore del cliente. Il modo
migliore per rendere l’idea è passare ad un esempio.
Figura 214.1. Il servente elabora tramite l’interprete PHP gli script i quali generano le
pagine HTML che vengono fornite al cliente tramite il protocollo HTTP.
Si supponga di voler scrivere la data odierna in una pagina HTML. L’HTML non permette di farlo, in quanto, è un linguaggio di formattazione statico. Una soluzione potrebbe essere l’utilizzo
di uno script Java di Netscape (JavaScript) ma è un linguaggio lato cliente. Il codice JavaScript
viene eseguito dal navigatore del visitatore e non dal servente. Tutto ciò potrebbe portare alla
visualizzazione di una data errata sulle pagine del sito solo perchè l’orario di sistema del visitatore non è impostato correttamente. Inoltre la guerra per il monopolio nel mercato dei navigatori
2278
Avere le idee chiare
2279
ipertestuali tra Microsoft e Netscape ha fatto sì che non ci sia uno standard, di conseguenza Netscape non gestiste molte istruzioni JScript di Microsoft e Explorer non riconosce molte istruzioni
JavaScript di Netscape 1 .
A questo punto l’ideale è fornire al navigatore una stringa HTML generata e formattata da una
funzione PHP. Ecco come:
1 <html>
2
<head>
3
<title>La mia prima pagina php</title>
4
</head>
5
<body>
6
7
<br><br>
8
9
<?php echo date("d-m-Y") ?>
10
11
<br><br>
12
13
<a href="../cap_2/benvenuto.php">vai a benvenuto.php &gt;&gt;</a>
14
15
</body>
16 </html>
Una volta completato salvare il codice nel file ‘primo.php’.
Se si prova ad aprire ‘primo.php’ dal menù file del navigatore il risultato è una pagina bianca.
Il motivo sta nel fatto che il PHP è un «linguaggio dal lato del servente» dunque il navigatore
(cliente) non è in grado di interpretarne il codice compreso tra i marcatori: ‘<?php ?>’
Per visualizzare la data in modo corretto è necessario dare il codice in pasto all’interprete PHP
tramite il servente HTTP, quindi bisogna copiare il file ‘primo.php’ nella directory dei documenti del servizio HTTP e dal navigatore richiamare il file scrivendo l’indirizzo dell’elaboratore su cui è ospitato. Tutti gli script di esempio sono disponibili in rete all’indirizzo <http://
www.urcanet.it/brdp/php_manual/esempi/> e sono raccolti per capitolo.
Se si scaricano gli script di esempio per essere eseguiti in locale e la configurazione del servente
è corretta, il risultato sarà:
Figura 214.2. Ecco come appare la pagina HTML <http://www.urcanet.it/brdp/php_manual/
esempi/cap_1/primo.php> sul navigatore del visitatore.
Ben più interessante è osservare il sorgente della pagina <http://www.urcanet.it/brdp/php_manual/esempi/
cap_1/primo.php> dal menu visualizza del navigatore, ecco quello che viene inviato dal servente:
1
Netscape ha sviluppato un linguaggio di programmazione ad oggetti interno al navigatore chiamato JavaScript tramite il quale è possibile gestire le finestre del navigatore, i form di invio dati, la navigazione stessa delle pagine e
tanto ancora. La Microsoft per il proprio navigatore Explorer ha realizzato un linguaggio molto simile chiamato JScript.
Purtroppo i due linguaggi non sono compatibili al 100% anche se le istruzioni di base sono ben gestite da entrambi.
Avere le idee chiare
2280
Figura 214.3. L’interprete PHP ha fatto il suo dovere. Questo è il codice generato e
fornito al navigatore tramite il servente HTTP.
Una volta ricevuta la richiesta della pagina da parte del navigatore, il servente inizia a leggere
il file ‘primo.php’ e a inviarlo al cliente, appena trovati i marcatori ‘<?php.?>’ capisce che
deve farsi «tradurre» il codice in essi contenuto. Lo passa quindi all’interprete PHP che lo esegue e restituisce il risultato. In questo semplice esempio il risulato dell’operazione è la stringa
‘23-03-2002’.
La funzione utilizzata nell’esempio ‘date("d-m-Y")’ formatta la data nello schema giorno mese -anno (numerico), mentre ‘echo’ visualizza a schermo il risultato della funzione ‘date()’.
Una modifica interessante al file precedente è:
1 <html>
2
<head>
3
<title>La mia prima pagina php</title>
4
</head>
5
<body>
6
7
<br><br>
8
9
<?php phpinfo() ?>
10
11
<br><br>
12
13
<a href="../cap_2/benvenuto.php">vai a benvenuto.php &gt;&gt;</a>
14
15
</body>
16 </html>
Questa volta il risultato è una pagina che visualizza la configurazione dell’elaboratore servente ,
dell’interprete e dei componenti per l’interrogazione delle basi di dati, oltre a una serie di variabili
predefinite. È bene dare un’occhiata al sorgente HTML della pagina, tutta opera dell’interprete
PHP.
«immerso nel codice HTML»: con ciò si intende che quanto contenuto tra i marcatori
‘<?php.?>’ viene prima interpretato, e poi inviato al navigatore come semplice codice HTML
insieme al resto della pagina.
Avere le idee chiare
2281
214.2 Cosa può fare il PHP?
Dunque il PHP permette di rendere dinamiche le pagine HTML dal lato del servente. Questo
insieme alla sua semplicità di utilizzo, alla somiglianza con la sintassi C e alle innumerevoli
funzioni che permettono di interagire con basi di dati e servizi di ogni genere ne hanno decretato
il successo in Internet.
La diffusione è dovuta alla semplicità di configurazione e alla completa compatibilità con numerosi serventi HTTP. Per il test degli script di questa guida è stato utilizzato come servente
Apache. 2
Il PHP permette, in modo semplice e diretto, di far interagire il cliente con le basi di dati ospitate
sul servente tramite il semplice utilizzo di un comune navigatore.
Tutti i maggiori DBMS sono gestiti da PHP, senza dover installare software aggiuntivo o
commerciale. Un breve elenco è riportato nella tabella 214.1.
Tabella 214.1. Queste le basi di dati gestite dal PHP.
BASI DI DATI
Adabas D
dBase
Empress
FilePro (read-only)
IBM DB2
Informix
Oracle (OCI7 and OCI8)
InterBase
FrontBase
mSQL
Direct MS-SQL
MySQL
ODBC
PostgreSQL
Solid
Sybase
Velocis
Unix dbm
Ingres
Inoltre il PHP permette di interagire con numerosi servizi tramite i protocolli: IMAP, SNMP,
NNTP, POP3, HTTP e molti altri.
214.3 PHP su piattaforma Microsoft
Il PHP è compatibile con molte piattaforme di sviluppo, tra cui quella Microsoft. Ovviamente le
migliori prestazioni si ottengono in ambiente GNU/Linux (o più in generale su sistemi Unix).
Per informazioni più dettagliate si rimanda al sito ufficiale <http://www.php.net>.
214.4 Quanto costa il PHP?
Il PHP viene distribuito nei termini della: The PHP License, version 2.02.
I requisiti minimi richiesti all’eleboratore servente sono del tutto abbordabili. Per i test degli
script contenuti in questa guida è stato utilizzato un vecchio P-120MHz con soli 16.Mibyte di
RAM e un piccolo disco fisso da 1,2.Gibyte.
Su di esso è stata installata una versione Debian GNU/Linux 2.2 con servente Apache, MySql,
interprete PHP4. Sulla stessa macchina erano in esecuzione il servente FTP, PostgreSQL, Postfix
e altri servizi minori.
Programmare in PHP --- Copyright © 2001-2002 Gianluca Giusti -- brdp @ urcanet.it
2
è possibile prelevare Apache dal sito ufficiale <http://www.apache.org>.
Capitolo
215
Le basi del linguaggio
Per poter scrivere codice in un qualunque linguaggio è necessario conoscerne la sintassi. In questo capitolo verranno trattate le espressioni fondamentali del PHP con il supporto di script di
esempio.
215.1 La sintassi
In realtà ‘<?php ?>’ non sono gli unici marcatori per fornire codice all’interprete. Ecco tutti i
modi di includere codice PHP negli script:
•
<?
•
<?php
•
<script language="php">
•
<%
codice
?>
codice
codice
?>
codice
</script>
%>
Il primo è disponibile solo se sono stati impostati i marcatori abbreviati, ciò può essere fatto
abilitando nel file di configurazione ‘php.ini’ l’opzione ‘short_open_tag’. Per i particolari
sugli altri marcatori si rimanda al manuale ufficiale.
Va sottolineato che il codice può essere bloccato e ripreso in ogni punto dello stesso file, ad
esempio:
1 <html>
2
<head>
3
4
<? $nome = "BRDP"; ?>
5
<title>ancora agli inizi</title>
6
7
</head>
8
<body>
9
10
<br>Ciao a tutti questo è il mio nome: <?=$nome ?>
11
12
</body>
13 </html>
Nell’esempio il codice viene aperto per la prima volta nella riga 4, viene assegnato un valore alla
variabile ‘$nome’, viene chiuso e poi riaperto nella riga 10 dove viene visualizzato a schermo il
valore della variabile insieme a una frase HTML. Il file quindi restituirà come output la stringa:
Ciao a tutti questo è il mio nome: BRDP
Con l’occasione, nell’esempio, sono stati toccati due concetti base.
Il primo è che le variabili in PHP iniziano con il carattere ‘$’ e sono sensibili a maiuscole e
minuscole, l’altro è che non è necessario definirne il tipo, sarà quello del primo dato ad essa
assegnato. Nel nostro caso la variabile ‘$nome’, dalla riga 4 in poi, sarà considerata una stringa.
Per averne conferma basta sostituire il codice della riga 4 con le due righe seguenti:
4
5
6
7
<?
$nome = "BRDP";
echo gettype($nome);
?>
Il risultato è:
string
Ciao a tutti questo è il mio nome: BRDP
2282
Le basi del linguaggio
2283
Più avanti si apprenderà come trattare i vari tipi di dati, quindi è inutile dilungarsi in questo
esempio; bisogna però dire che è possibile cambiare il tipo di dati mediante l’istruzione:
settype($variabile, tipo_variabile);
e ottenere il tipo di dato contenuto in una variabile tramite:
gettype($variabile);
Il secondo concetto è nella riga 10; per visualizzare il contenuto della variabile è stata utilizzata
la sintassi:
<?=$nome ?>
Per chi si avvicina al PHP dopo aver sviluppato in Perl o in altri linguaggi script CGI la differenza è lampante. Non è necessario scrivere codice per generare HTML, semplicemente si
inserisce codice PHP tra i marcatori HTML. Inoltre nel caso in cui l’istruzione sia la semplice
visualizzazione di una singola variabile, la sintassi classica:
<? echo $nome ?>
può essere abbreviata con:
<?=$nome ?>
Attenzione: se il codice PHP è formato da più istruzioni consecutive è richiesto il carattere punto
e virgola (‘;’) alla fine di ognuna di esse, se invece l’istruzione da inserire è una sola, il ‘;’ può
essere omesso.
Sarebbe buona norma dedicare molta cura all’indentazione del codice e inserire commenti chiari
e diretti; così facendo si rende il codice più leggibile e comprensibile. La gestione dei commenti è
simile a quella utilizzata in C, C++ e shell di Unix. I caratteri di commento sono: per una singola
riga ‘//’ la barra obliqua doppia oppure il carattere ‘#’, per più righe il commento viene aperto
con ‘/*’ e chiuso con ‘*/’. Nel secondo caso bisogna fare attenzione a non annidare i commenti.
Questo è il modo corretto:
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?
// Questo è un commento su una singola riga
// adesso visualizzo ciao mondo!
echo "ciao mondo!";
/*
questo è un commento
su più righe, posso scrivere di tutto!!!
anche istruzioni php che non verranno interpretate come:
echo "questo non verrà visualizzato!";
chiudo il commento
*/
echo "<br>questo invece si vedrà!!";
/*
Notare che ho inserito <br> un marcatore html nel
codice php! Posso farlo.
*/
?>
Questo è sbagliato:
0
1
2
3
4
<?
/*
echo "ciao mondo!"; /* questo causa problemi! */
*/
2284
5
6
Le basi del linguaggio
?>
215.2 Primo script
Come primo esempio verrà realizzata una pagina di riconoscimento del visitatore. Il PHP fornisce
una serie di «variabili predefinite». Tra esse ce ne sono alcune fornite dal protocollo HTTP.
Per l’elenco completo delle variabili predefinite è bene consultare il manuale ufficiale del PHP,
molte di esse vengono visualizzate nella pagina generata dalla funzione ‘phpinfo()’ 1
Il primo passo è scegliere le variabili da utilizzare.
Per questo semplice script verranno utilizzate:
• ‘SERVER_NAME’: nome dell’elaboratore su cui risiede e viene eseguito lo script;
• ‘HTTP_REFERER’: l’URI, se ne esiste uno, da cui proviene il visitatore; 2
• ‘HTTP_USER_AGENT’: il tipo di navigatore utilizzato dal visitatore;
• ‘REMOTE_ADDR’: l’indirizzo IP dell’elaboratore cliente;
• ‘SCRIPT_NAME’: il percorso dello script in esecuzione;
è importante fare molta attenzione all’utilizzo di queste variabili, alcune di esse usate
in modo superficiale potrebbero fornire informazioni utili ai malintenzionati. Ad esempio
‘DOCUMENT_ROOT’ fornisce la directory su file system in cui si trovano gli script PHP e i
documenti del servizio HTTP. Informazioni di questo tipo è meglio tenerle riservate!
Scelte le variabili va creato il nuovo file e salvato con il nome di ‘benvenuto.php’. La prima
versione, la più rudimentale, è la seguente:
1 <html>
2
<head>
3
<title>Benvenuto!</title>
4
</head>
5
<body>
6
7
<br> La mia prima vera pagina in PHP.<br><hr>
8
9
<br><br> Informazioni sul server:
10
<br>Sei giunto su: <?=$SERVER_NAME ?>
12
<br>Stai eseguendo lo script: <?=$SCRIPT_NAME ?>
13
14
<br><br> Esaminiamo il client:
15
16
<br> Indirizzo IP: <?=$REMOTE_ADDR ?>
17
<br> Vedo che provieni da: <?=$HTTP_REFERER ?>
18
<br> Tipo di browser: <?=$HTTP_USER_AGENT ?>
19
20
</body>
21 </html>
Salvato il file nella directory del servizio HTTP e richiamato dal navigatore si ottiene qualcosa
simile a:
1
Nel caso in cui il servente sia Apache, le variabili HTTP nella pagina ‘phpinfo()’ vengono raccolte nella sezione
«variabili di Apache»
2
Se si segue il percorso degli script proposti dalla guida, il visitatore arriverà da <http://www.urcanet.it/brdp/php_manual/
esempi/cap_1/primo.php>
Le basi del linguaggio
2285
La mia prima vera pagina in PHP.
Informazioni sul server:
Sei giunto su: www.urcanet.it
Stai eseguendo lo script: /brdp/php_manual/esempi/cap_2/benvenuto.php
Esaminiamo il client:
Indirizzo IP: 127.0.0.1
Vedo che provieni da: http://www.urcanet.it/brdp/php_manual/esempi/cap_1/primo.php
Tipo di browser: Mozilla/5.0 (X11; U; Linux 2.4.2-2 i686; en-US; 0.7) Gecko/20010316
Anche questo esempio è disponibile in rete all’indirizzo: <http://www.urcanet.it/brdp/php_manual/
esempi/cap_2/benvenuto.php>
Il risultato potrebbe essere incomprensibile per i visitatori meno esperti. Ad esempio, il tipo di
navigatore non è molto chiaro.
Gli strumenti fin qui trattati non permettono di fare molto per migliorare il risultato dello script.
Più avanti questo esempio potrà essere ripreso per manipolare il risultato in modo da mostrare al
visitatore dei messaggi più chiari.
215.3 Tipi di dati
Il PHP gestisce quattro tipi scalari, due tipi composti e due tipi speciali di dati.
Tabella 215.1. Questi i tipi di dati gestiti dal PHP.
Scalari
Composti
Speciali
‘boolean’
‘integer’
‘double’
‘string’
‘array’
‘object’
‘resurce’
‘NULL’
Come già accennato in precedenza, il tipo di una variabile può essere modificato in ogni momento
con la funzione ‘settype($variabile,tipo)’ che restituisce un valore booleano vero o falso
rappresentante l’esito dell’operazione. I possibili tipi da assegnare alla variabile sono:
• ‘integer’
• ‘double’
• ‘string’
• ‘array’
• ‘object’
I criteri di conversione dei tipi sono molto importanti, il codice mostrato di seguito non provoca
problemi.
0
1
2
3
4
5
6
7
8
9
<?
$a = 231;
// da questo momento in poi $a è un intero
if(settype($a,double)){
/*
Se l’operazione è riuscita il valore è TRUE quindi
visualizza il testo seguente. Altrimenti salta alla
fine dell’if riga 10.
*/
echo "<br>valore settato a double. Ecco il nuovo valore: ";
echo $a;
Le basi del linguaggio
2286
10 }
11 ?>
Spiacevoli inconvenienti potrebbero verificarsi se si prova a convertire una stringa in un intero.
Per una trattazione più approfondita di questo argomento si rimanda al manuale ufficiale.
Un’altra funzione utile per la gestione dei tipi di dati è ‘gettype($variabile)’ che restituisce
una stringa contenente il tipo della variabile a essa fornita. Questi i possibili valori restituiti dalla
funzione:
• ‘integer’
• ‘double’
• ‘string’
• ‘array’
• ‘object’
• ‘unknown type’
Ecco un semplice esempio di utilizzo della funzione ‘gettype()’:
0
1
2
3
4
5
6
7
8
9
<?
$a = "brdp";
/*
la variabile $a è stata
inizializzata come stringa
*/
$tipo_a = gettype($a);
echo "<br>La variabile è di tipo:";
echo $tipo_a;
?>
Il risultato dello script sarà:
La variabile è di tipo: string
Dopo questa breve trattazione sulla gestione dei tipi di dati a disposizione nel PHP, è bene
accennare alle caratteristiche di ognuno di essi.
215.3.1 integer
Il tipo di dati ‘integer’ rappresenta tutti i numeri dell’insieme matematico degli interi.
Z = {..., -2, -1, 0, 1, 2, ...}
Quindi tutti i numeri interi, sia negativi che positivi, vengono gestiti dal PHP come tipi
‘integer’.
Anche i corrispondenti valori in base otto e sedici vengono gestiti come gli interi. Ecco alcuni
esempi tratti dal manuale ufficiale:
<?
$a
$a
$a
$a
=
=
=
=
1234;
-123;
0123;
0x1A;
//
//
//
//
numero
numero
numero
numero
intero positivo
intero negativo
ottale (equivalente a 83 in decimale)
esadecimale (equivalente a 26 in decimale)
?>
Il limite massimo della dimensione dei valori interi dipende dall’architettura dell’elaboratore su
cui si lavora.
Le basi del linguaggio
2287
Nel PHP non esiste un tipo specifico per i numeri naturali.3 Essi vengono gestiti come ‘integer’.
215.3.2 boolean
Il tipo di dati ‘boolean’ può assumere solo due valori, vero o falso.
Questo tipo viene utilizzato frequentemente per la gestione degli errori. Molte funzioni, infatti,
restituiscono un valore booleano che assume valore vero se l’operazione è andata a buon fine,
falso se si è verificato un errore.
Per assegnare il valore vero o falso a una variabile è sufficiente l’istruzione:
$bit = True;
In questo esempio alla variabile ‘$bit’ è stato assegnato il valore vero. Anche se l’istruzione
‘if’ non è ancora stata trattata, è necessario anticipare le metodologie di controllo sul valore
della variabile.
In PHP non è necessario (anche se è possibile) eseguire il controllo in questo modo:
<?
$bit = True;
if($bit == "True"){
// $bit è vero
echo " il valore è vero!";
}
?>
Basta scrivere:
<?
$bit = True;
if($bit){
// $bit è vero
echo " il valore è vero!";
}
?>
L’interprete riconosce il tipo di dato e controlla se è vero. Nei prossimi capitoli verranno
approfondite le caratteristiche dell’istruzione ‘if’.
215.3.3 double
Come è stato più volte ripetuto, il PHP non necessita della definizione dei tipi di dati che si
vanno a utilizzare ma inizializza il tipo di variabile in base al primo valore a essa associato. I
«numeri a virgola mobile» in PHP contengono i tipi conosciuti in altri linguaggi come: ‘floats’,
‘doubles’, ‘real’. È possibile inizializzare una variabile di tipo ‘double’ assegnandole valori
formattati in uno dei seguenti modi:
<?
$a = 1.234;
$a = 1.2e3;
$a = 7E-10;
?>
Anche per questo tipo, come per gli interi, la dimensione massima dipende dall’architettura
dell’elaboratore su cui viene eseguito lo script.
3
I numeri naturali sono il sottoinsieme positivo dei numeri interi.
Le basi del linguaggio
2288
215.3.4 string
Una stringa è un insieme di caratteri. In PHP non ci sono limiti particolari di lunghezza per i dati
di tipo ‘string’.
Ci sono più modi di delimitare una stringa. Ecco i due più comuni:
0
1
2
3
4
5
6
7
8
9
<?
// single quoted string
$nome = ’Gianluca Giusti’;
// double queoted string
$nome = "Gianluca Giusti";
/* In entrambi i casi $nome viene inizializzata
come stringa dall’interprete PHP */
?>
L’interprete PHP riconosce come carattere di escape il ‘\’ (barra obliqua inversa). 4
Di seguito riportiamo i caratteri più comuni, una tabella completa è contenuta nel manuale
ufficiale.
Tabella 215.2. Alcuni caratteri di escape per le stringhe PHP.
Carattere
\t
\n
\\
\"
\$
Significato
carattere tabulazione
carattere di fine riga
‘\’ barra obliqua inversa
‘"’ doppio apice
‘$’ dollaro
Ecco alcuni esempi di come gestire le stringhe.
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<?
// Valorizzo una variabile che servirà in seguito.
$email = " brdp @ urcanet.it ";
// Stringa semplice:
$stringa = "Ecco. Questa è una stringa";
// Ad essa si possono concatenare altre stringhe alla fine
$stringa = $stringa." con dell’altro testo aggiunto";
// che equivale a scrivere
$stringa .= " con dell’altro testo aggiunto";
// Oppure all’inizio
$stringa = "altro testo ancora ".$stringa;
// Adesso si prende la prima lettera della stringa
$prima = $stringa{0};
// Concatenazione multipla
$stringa = $prima." - ".$stringa." <br><br> il mio email: ".$email;
/* Test sui caratteri di escape. All’interno della stringa posso
visualizzare il valore di una variabile ma per visualizzarne
il nome devo "inibire" il carattere speciale $. Lo faccio con
l’uso della barra obliqua inversa. Ecco come: */
$stringa = "Questo il valore di \$email: $email";
4
il carattere di escape viene utilizzato per rappresentare caratteri speciali all’interno di una stringa, caratteri che
potrebbero creare confusione all’interprete.
Le basi del linguaggio
2289
27
28 // c’è differenza con:
29 $stringa = "Questo il valore di $email: $email";
30 ?>
L’esempio precedente non è completo. Per poter osservare i risultati delle varie operazioni a
schermo è necessario modificare lo script. Questo semplice, ultimo passo è lasciato al lettore
come esercizio.
Il PHP fornisce un gran numero di funzioni dedicate alla gestione delle stringhe; uno dei punti di
forza di questo linguaggio sta proprio nella semplicità con cui queste possono essere manipolate.
Risulta inutile dilungarsi nella trattazione delle singole funzioni, esse verranno descritte negli
esempi in cui saranno impiegate. Un elenco completo e dettagliato è contenuto nel manuale
ufficiale alla sezione «String functions».
215.3.5 array
Gli array possono essere creati tramite il costrutto ‘array()’ oppure tramite la valorizzazione
degli elementi.
A differenza dei classici linguaggi di programmazione, il PHP permette di indicizzare gli array non solo mediante interi non negativi, ma anche tramite stringhe. Per chi conosce il Perl il
concetto è molto simile a quello degli array associativi.
Di seguito la sintassi per creare un array tramite il costrutto ‘array()’.
0
1
2
3
4
5
6
<?
array( [chiave =>] valore
, ...
)
// la chiave può essere un intero non negativo o una stringa
// il valore può essere qualunque
?>
La chiave è contenuta tra le parentesi quadre perchè può essere omessa, se non viene specificata
viene incrementato il valore intero. La sintassi di associazione è molto semplice ed intuitiva, per
le chiavi intere positive: ‘chiave => valore’, mentre per le chiavi di tipo stringa vanno aggiunte
le doppie virgolette ‘"chiave " => valore’.
Per visualizzare il contenuto dell’array è possibile utilizzare la semplice istruzione
‘print_r($array)’. Negli esempi seguenti si vedrà come questa funzione visualizza l’array.
Ecco alcuni esempi.
0
1
2
3
<?
$a = array( "a", "b", 44, "d", "e");
print_r($a);
?>
L’istruzione ‘print_r($a)’ visualizzerà sullo schermo la struttura e il contenuto dell’array nel
seguente modo:
Array ( [0] => a [1] => b [2] => 44 [3] => d [4] => e )
L’indice dei valori è stato incrementato automaticamente. È bene tenere sempre presente che le
chiavi degli array partono da 0 e non da 1.
C’è la possibilità di specificare solo alcune chiavi e lasciare la gestione degli indici omessi
all’interprete.
0
1
<?
$a = array( "a", "b", "c", "d",
8=>"e",
4=>"f", "g", 3=>"h");
2290
2
3
Le basi del linguaggio
print_r($a);
?>
Questo il risultato dello script precedente:
Array ( [0] => a [1] => b [2] => c [3] => h [8] => e [4] => f [9] => g )
A prima vista il risultato può sembrare errato, ma non è così. L’interprete incrementa automaticamente gli indici omessi dei primi quattro valori, ossia da 0 a 3, e mano a mano valorizza l’array.
La lettera ‘e’ va invece inserita nella cella con chiave, specificata, pari a 8 e la ‘f’ in quella con
chiave 4. Per la lettera ‘g’ non viene specificata nessuna chiave, l’interprete, quindi, riparte automaticamente dall’indice intero più alto incrementandolo di uno e ottiene il valore 9. Rimane
da inserire l’ultima lettera ‘h’ che va, come richiesto, nella cella con chiave pari a 3. Questa
operazione sovrascrive la lettera ‘d’ che già era stata inserita, in automatico, con chiave pari a 3.
A questo punto dovrebbero essere chiari i motivi dell’assenza della lettera ‘d’ e del particolare
ordine con cui vengono visualizzati i valori contenuti nell’array.
Un array può essere creato anche senza l’utilizzo del costrutto ‘array()’, in questo caso la
sintassi ricorda quella dei più comuni linguaggi di programmazione.
Di seguito sono riportati gli esempi precedenti con l’utilizzo del secondo metodo di creazione.
0
1
2
3
4
5
6
7
<?
$a[] = "a";
$a[] = "b";
$a[] = 44;
$a[] = "d";
$a[] = "e";
print_r($a);
?>
Il secondo esempio può essere tradotto in questo modo:
0 <?
1
$a[] = "a";
2
$a[] = "b";
3
$a[] = "c";
4
$a[] = "d";
5
$a[8] = "e";
6
$a[4] = "f";
7
$a[] = "g";
8
$a[3] = "h";
9
print_r($a);
10 ?>
I due procedimenti per la creazione degli array sono equivalenti.
Gli array possono avere chiavi miste, come nell’esempio seguente, in cui alcune sono intere e
alcune stringhe.
0
1
2
3
4
5
6
7
<?
$a["rosso"] = "a";
$a[] = "c";
$a[8] = "e";
$a["nero"] = "f";
$a[] = "g";
print_r($a);
?>
Ecco il risultato:
Array ( [rosso] => a [0] => c [8] => e [nero] => f [9] => g )
è interessante studiare una possibile applicazione pratica degli array. Nel seguente esempio verrà
ripresa la funzione ‘date()’ già incontrata nella sezione 214.1.
Le basi del linguaggio
2291
0 <?
1 // valorizzo l’array dei giorni della settimana con il metodo classico.
2
$giorno[0] = "Domenica";
3
$giorno[1] = "Lunedì";
4
$giorno[2] = "Martedì";
5
$giorno[3] = "Mercoledì";
6
$giorno[4] = "Giovedì";
7
$giorno[5] = "Venerdì";
8
$giorno[6] = "Sabato";
9
10 // valorizzo l’array dei mesi dell’anno con il costrutto array()
11
$mese = array(
12
1 => "Gennaio",
13
2 => "Febbraio",
14
3 => "Marzo",
15
4 => "Aprile",
16
5 => "Maggio",
17
6 => "Giugno",
18
7 => "Luglio",
19
8 => "Agosto",
20
9 => "Settembre",
21
10 => "Ottobre",
22
11 => "Novembre",
23
12 => "Dicembre"
24
);
25 // Prendo il mese in formato numerico da 1 a 12.
26
$numero_mese = date("n");
27
28 /* Prendo il giorno della settimana da 0 (domenica) a 6 (sabato)
29
questa volta formatto tutto annidando più funzioni.
30
in PHP è possibile! */
31
$giorno_settimana = $giorno[date("w")];
32
33 // Formatto la data nel modo: Lunedì 19 Novembre 2001
34
$oggi = $giorno_settimana." ".date("d")."-".$mese[$numero_mese]."-".date("Y");
35
36 // Visualizzo la data a schermo concatendandola ad una stringa
37
echo "<br> Oggi è: <b>".$oggi."</b>";
38 ?>
Il risultato di questo script, raggiungibile presso <http://www.urcanet.it/brdp/php_manual/esempi/cap_2/
è:
data.php>,
Oggi è: Domenica 18-Novembre-2001
Gli array rappresentano una delle strutture più versatili in PHP, a differenza dei linguaggi classici,
infatti, la dimensione non deve essere specificata a priori. Questo permette una dinamicità e una
libertà di utilizzo notevole.
Il PHP gestisce anche gli array multidimensionali e gli array annidati.
Non si entrerà nel merito, si darà per scontata la teoria sulla gestione degli array, che è simile per
i diversi tipi di linguaggi, mentre si tratterà la sintassi tramite uno script di esempio.
Il seguente è un esempio sull’utilizzo degli array multidimensionali.
0
1
2
3
4
5
6
7
8
9
10
<html>
<head>
<title>Semplice Agenda telefonica statica</title>
</head>
<body>
<?
/*
Un semplice esempio di array multidimensionale.
Una rubrica telefonica.
*/
2292
Le basi del linguaggio
11
12
$a["nome"][0] = "Gianluca";
13
$a["cognome"][0] = "Giusti";
14
$a["tel"][0] = "06/66666666";
15
16
$a["nome"][1] = "Mirko";
17
$a["cognome"][1] = "Simeoni";
18
$a["tel"][1] = "07/77777777";
19
20
$a["nome"][2] = "Fabio";
21
$a["cognome"][2] = "Ferri";
22
$a["tel"][2] = "08/88888888";
23
24
/*
25
Adesso elenchiamo la rubrica. Lo faremo senza
26
utilizzare Nessuna struttura ciclica per non
27
confondere le idee
28
*/
29
30
?>
31
32
<br>
33
34
<table border="1">
35
<tr bgcolor="gray" >
36
<td>ID</td>
37
<td>Nome</td>
38
<td>Cognome</td>
39
<td>Telefono</td>
40
</tr>
41
<tr>
42
<td>0</td>
43
<td><?=$a[nome][0]?></td>
44
<td><?=$a[cognome][0]?></td>
45
<td><?=$a[tel][0]?></td>
46
</tr>
47
<tr>
48
<td>1</td>
49
<td><?=$a[nome][1]?></td>
50
<td><?=$a[cognome][1]?></td>
51
<td><?=$a[tel][1]?></td>
52
</tr>
53
<tr>
54
<td>2</td>
55
<td><?=$a[nome][2]?></td>
56
<td><?=$a[cognome][2]?></td>
57
<td><?=$a[tel][2]?></td>
58
</tr>
59
60
</table>
61
62
</body>
63</html>
Una volta salvato il codice nella propria directory dei documenti del servizio HTTP si può verificare il risultato. Anche questo esempio è disponibile all’indirizzo: <http://www.urcanet.it/brdp/
php_manual/esempi/cap_2/agenda.php>,inoltre, il risultato è riportato in figura 215.1.
Le basi del linguaggio
2293
Figura 215.1. La rubrica telefonica è stata formattata in una tabella HTML.
Inutile dire che questo è solo un’esempio per prendere confidenza con la sintassi PHP relativa
agli array e che esistono soluzioni migliori per il salvataggio dei dati. Più avanti nella guida si
tratteranno i file e le basi di dati.
Un esercizio molto utile lasciato al lettore è la realizzazione di uno script clone del precedente
con l’utilizzo del costrutto ‘array()’ per la gestione dell’array utilizzato nella rubrica telefonica.
Gli array di array verranno trattati nella sezione dedicata alla «programmazione avanzata in
PHP», in quanto richiedono maggiore dimestichezza con il linguaggio.
215.3.6 object
Una classe è una collezione di variabili e di funzioni dette metodi. Una volta definita la classe
è possibile istanziare uno o più oggetti della stessa classe. Ognuno di essi è indipendente dagli
altri.
Una trattazione approfondita può essere trovata nella sezione «programmazione avanzata in
PHP» di questa guida.
215.4 Operatori
Il PHP gestisce numerosi tipi di operatori, di seguito sono elencate le caratteristiche principali
dei tipi utilizzati più di frequente. Per una trattazione completa si rimanda il lettore al manuale
ufficiale.
Tabella 215.3. Questi alcuni degli operatori gestiti dal PHP.
OPERATORI
aritmetici
controllo degli errori
incemento e decremento
assegnazione
logici
confronto
Verranno analizzati singolarmente gli operatori riportati nella tabella 215.3.
215.4.1 Operatori aritmetici
Nella tabella 215.4 sono riportati gli operatori aritmetici con le rispettive caratteristiche.
Le basi del linguaggio
2294
Tabella 215.4. Le caratteristiche degli operatori aritmetici.
Esempio
$a + $b
$a - $b
$a * $b
$a / $b
Nome
Addizione
Sottrazione
Moltiplicazione
Divisione
Risultato
Somma tra $a e $b
Differenza tra $a e $b
Prodotto tra $a e $b
Quoziente tra $a e $b
Lo schema è stato preso dal manuale ufficiale, è molto chiaro e non ha bisogno di molte spiegazioni. Bisogna tenere ben presente che il tipo della variabile a cui si assegna il risultato dipende
dal tipo dei due valori ‘$a’ e ‘$b’.
215.4.2 Operatori di assegnazione
L’operatore fondamentale per l’assegnazione di un valore ad una variabile è ‘=’. La sintassi
fondamentale è:
0
1
2
3
4
5
6
7
8
9
<?
// assegno ad $a il valore intero 123
$a = 123;
// assegno a $b il contenuto di $a
$b = $a;
// assegno una stringa alla variabile $c
$c = "questa è una stringa";
?>
L’operatore ‘=’ può essere utilizzato insieme ad altri operatori elencati nell’esempio:
0 <?
1
//
2
$a
3
4
//
5
$b
6
7
//
8
$a
9
10 //
11 $a
12
13 //
14 $a
15 $a
16 $a
17
18 //
19 $a
20
21 //
22 $a
23 $b
24
25 //
26 $a
27 $a
28
29 //
30 $a
31 $a
32 ?>
assegno ad $a un valore intero
= 2;
assegno a $b un altro valore intero
= 5;
posso assegnare a $a la somma di $a e $b in questo modo
= $a + $b;
oppure in questo modo
+= $b;
stesso discorso per tutti gli operatori aritmetici
-= $b;
*= $b;
/= $b;
posso anche assegnare un valore a più variabili
= $b = 30;
o ancora in questo esempio sia $a che $b valgono 6
= 3;
= $a += 3;
per le stringhe. $a varrà "ciao a tutti!!!"
= "ciao a";
.= " tutti!!!";
equivale a concatenare la stringa in questo modo
= "ciao a";
= $a." tutti!!!";
Le basi del linguaggio
2295
I commenti inseriti nell’esempio dovrebbero bastare a descrivere la versatilità degli operatori
appena trattati.
215.4.3 Operatori di controllo degli errori
Nell’esempio seguente viene gestito un errore dovuto al tentativo di lettura di un file inesistente.
Con l’occasione viene utilizzata la funzione PHP ‘file(’nome_del_file’)’ che restituisce
un array contenente le righe del file passato alla funzione.
0
1
2
3
4
5
6
7
8
9
<?
// provo ad aprire un file che non esiste
$file_array = file(’file_inesistente’) or
die (" Errore durante l’apertura del file. ");
/*
il file non esiste, lo script si ferma
mostrando i messaggi di errore
*/
?>
Se si salva il codice in un file e si richiama tramite il navigatore, si nota che oltre al messaggio
di errore inserito nello script viene visualizzato un messaggio introdotto dall’interprete PHP.
I messaggi di errore possono contenere informazioni utili ai male intenzionati, è bene, quindi,
gestire tali messaggi al meglio. Un esempio è riportato in figura 215.2 dove si nota il percorso su
file system dello script di prova.
Figura 215.2. Ecco come appare la pagina contenente l’errore non gestito. Oltre al
messaggio di errore da noi inserito viene visualizzato anche un warning dall’interprete
PHP.
Un modo molto semplice per non far visualizzare i messaggi d’errore dell’interprete è
premettere il carattere ‘@’ alla funzione. Ad esempio: ‘@file(’dati.txt’)’.
L’esempio precedente potrebbe essere modificato in questo modo:
0
1
2
3
4
5
6
7
8
9
<?
// provo ad aprire un file che non esiste
$file_array = @file(’file_inesistente’) or
die (" Errore durante l’apertura del file. ");
/*
In questo caso il messaggio di errore dell’interprete
PHP è stato silenziato dalla ’@’ premessa alla funzione file().
Verrà quindi mostrato solo il nostro messaggio di errore
*/
?>
Il costrutto ‘die()’ non fa altro che terminare l’esecuzione del programma, in caso di errore,
mostrando il messaggio contenuto tra le parentesi.
Le basi del linguaggio
2296
215.4.4 Operatori di incremento e decremento
Come detto, la sintassi PHP ricorda molto quella del C. Gli operatori di pre e post
incrementazione sono gestiti come nel linguaggio C.
Nella tabella 215.5 sono riportati i quattro operatori:
Tabella 215.5. Questi gli operatori di incremento e decremento gestiti dal PHP.
Esempio
‘$a++’
‘++$a’
‘$a--’
‘--$a’
Nome
Post-incremento
Pre-incremento
Post-decremento
Pre-decremento
Risultato
Restituisce ‘$a’ e poi la incrementa di uno
Incrementa di uno ‘$a’ e poi la restituisce
Restituisce ‘$a’ e poi la decrementa di uno
Decrementa di uno ‘$a’ e poi la restituisce
Nell’esempio seguente vengono utilizzati i quattro operatori:
0 <?
1
$a = 1;
2
3
// Operatori di pre-incremento
4
5
echo "<br>La variabile vale: ".++$a;
6
echo " e dopo vale: ".$a;
7
8
// Operatori di post-incremento
9
10
echo "<br>La variabile vale: ".$a++;
11
echo " e dopo vale: ".$a;
12
13
// Operatori di pre-decremento
14
15
echo "<br>La variabile vale: ".--$a;
16
echo " e dopo vale: ".$a;
17
18
// Operatori di post-decremento
19
20
echo "<br> La variabile vale: ".$a--;
21
echo " e dopo vale: ".$a;
22
23 ?>
Se si prova a salvare l’esempio in un file nella directory del servizio HTTP, una volta richiamato
mediante il navigatore, il risultato sarà di questo tipo:
La
La
La
La
variabile
variabile
variabile
variabile
vale:
vale:
vale:
vale:
2
2
2
2
e
e
e
e
dopo
dopo
dopo
dopo
vale:
vale:
vale:
vale:
2
3
2
1
Ragionando passo passo si capisce il lavoro dell’interprete e di conseguenza il risultato ottenuto.
La variabile inizialmente vale 1. Nella riga 5 viene incrementata, prima di essere visualizzata,
tramite l’operatore ‘++$a’. Nella riga 6 viene mostrato il valore di ‘$a’ senza eseguire alcuna
operazione. Da queste prime due righe di codice si ottiene la riga:
La variabile vale: 2 e dopo vale: 2
Nella riga 10, invece, viene utilizzato l’operatore ‘$a++’ che prima visualizza il contenuto della
variabile e poi lo incrementa. Infatti la riga 11 restituisce un valore di ‘$a’ pari a 3. Il risultato è
evidente nella seconda riga del file HTML generato dallo script di prova.
Stessa procedura per gli operatori di pre e post decremento, fino a ritornare al valore iniziale della
variabile.
Le basi del linguaggio
2297
215.4.5 Operatori logici
Gli operatori logici gestiti dal PHP sono riportati nella tabella 215.6.
Tabella 215.6. Questi gli operatori logici gestiti dal PHP.
Esempio
‘$a and $b’
‘$a or $b’
‘$a Xor $b’
‘!$a’
‘$a && $b’
‘$a || $b’
Nome
AND
OR
XOR
NOT
AND
OR
Risultato
vera se $a e $b sono vere
vera se $a o $b è vera
vera se $a o $b è vera ma non entrambe
Negazione. Vera se $a non è vera
Simile a ‘and’ ma con precedenza diversa
Simile a ‘or’ ma con precedenza diversa
Le precedenze degli operatori sono riportate nel manuale ufficiale.
In questo momento è inutile dilungarsi in esempi, gli operatori logici verranno approfonditi in
seguito. In particolare verranno trattati con l’introduzione dell’istruzione ‘if’.
215.4.6 Operatori di confronto
Il PHP gestisce tutti gli operatori di confronto riportati nella tabella 215.7.
Tabella 215.7. Gli operatori di confronto gestiti dal PHP.
Esempio
‘$a
‘$a
‘$a
‘$a
‘$a
‘$a
‘$a
‘$a
‘$a
== $b’
=== $b’
!= $b’
<> $b’
!== $b’
< $b’
> $b’
<= $b’
>= $b’
Nome
Uguale
Identico
Diverso
Diverso
Non Identico
Minore
Maggiore
Minore o uguale
Maggiore o uguale
Risultato
vera se $a è uguale a $b
vera se $a è uguale a $b e sono dello stesso tipo
vera se $a è diverso da $b
vera se $a è diverso da $b
vera se $a non è uguale a $b o non sono dello stesso tipo
vera se $a è minore di $b
vera se $a è maggiore di $b
vera se $a è minore o uguale a $b
vera se $a è maggiore o uguale a $b
Esempi pratici sugli operatori di confronto verranno trattati in seguito, nella guida, con
l’introduzione delle «strutture di controllo».
215.5 Strutture di controllo
Nella tabella 215.8 sono riportate le strutture di controllo che verranno trattate in dettaglio nelle
pagine seguenti.
Tabella 215.8. Le strutture di controllo.
Strutture
if
else
elseif
switch
di controllo
while
do..while
for
foreach
break
include()
le strutture di controllo sono state raggruppate per tipologia e ordinate secondo la difficoltà. Di
seguito verranno trattati prima i costrutti più semplici e poi quelli più complessi.
2298
Le basi del linguaggio
Nella prima colonna sono raccolte le strutture tramite le quali si è in grado di eseguire determinate
istruzioni al verificarsi di particolari condizioni.
Nella seconda colonna sono raccolte le strutture mediante cui è possibile realizzare e gestire delle
operazioni cicliche, fino a quando una particolare condizione viene soddisfatta e interrompe il
ciclo.
In questo ultimo caso è importante tenere sempre presente la condizione di STOP. Questo per
evitare dei cicli infiniti che possono bloccare il funzionamento del programma.
Inoltre negli esempi che seguono verranno utilizzati gli operatori precedentemente introdotti.
215.5.1 if
Il costrutto ‘if’ è molto importante e utilizzato in tutti i linguaggi di programmazione. La sintassi
è la seguente:
if(condizione)
singola istruzione
Utilizzato in questo modo, solamente un’istruzione è condizionata dall’esito della condizione
contenuta nel costrutto ‘if’. Ecco un esempio:
0 <?
1
$a = 3;
2
$b = 5;
3
4
if($a < $b) // uso un operatore di confronto
5
echo "Condizionato da if. Solo se \$a è minore di \$b.";
6
7
echo "<br>Questo, invece, viene scritto comunque!!!";
8
9 ?>
Se si ha bisogno di condizionare una o più istruzioni la sintassi da utilizzare è la seguente:
if(condizione){
istruzione 1
istruzione 2
.
.
.
istruzione n
}
Riprendendo l’esempio precedente si può scrivere:
0 <?
1
$a = 3;
2
$b = 5;
3
4
if($a < $b){
5
echo "Istruzione 1.";
6
echo "Istruzione 2.";
7
echo "Istruzione 3.";
8
}
9
10
echo "<br>Questo, invece, viene scritto comunque!!!";
11
12 ?>
La differenza è semplice e lampante. Il blocco delle istruzioni condizionate va contenuto tra le
parentesi ‘{ }’.
Le basi del linguaggio
2299
215.5.2 else
Nell’ultimo esempio viene gestito un solo evento. Se si volesse gestire anche l’evento $a >=
$b si potrebbe aggiungere, in modo poco elegante e funzionale, un altro ‘if($a >= $b){
istruzioni }’. Tuttavia la soluzione più corretta è sicuramente l’utilizzo della struttura ‘else’
La sintassi del costrutto ‘else’ è la seguente:
if(condizione){
istruzione 1
istruzione 2
.
.
.
istruzione n
}else{
istruzione 1
istruzione 2
.
.
.
istruzione m
}
Di seguito sono riportati alcuni esempi per chiarirne l’utilizzo e per prendere confidenza con gli
operatori precedentemente trattati.
0 <?
1
2
if(!$a){ // $a è falso.
3
$a = "ok";
4
}else{
5
$a = "ko";
6
}
7
8
// a questo punto $a vale "ok"
9
10
if($a == "ok"){
11
echo "Sono entrato nell’if e \$a vale: ".$a;
12
echo "<br> Adesso cambiamo il contenuto di \$a";
13
$a = 17;
14
}else{
15
echo "\$a non vale \"ok\" e quindi mi trovo nell’else. \$a: ".$a;
16
echo "<br> anche in questo caso setto \$a uguale a 17 ma in modo diverso.";
17
$a = 16;
18
$a += 1;
19
}
20
21
// adesso scrivo il tipo e il valore di $a
22
23
if(is_integer($a)){
24
echo "<br> \$a è un INTERO e vale: ".$a;
25
}else{
26
echo "<br> \$a NON è un intero e vale: ".$a;
27
}
28
29 ?>
Lo script, così come nell’esempio, restituisce un risultato simile al seguente:
Sono entrato nell’if e $a vale: ok
Adesso cambiamo il contenuto di $a
Le basi del linguaggio
2300
$a è un INTERO e vale: 17
Per comprendere al meglio il flusso del programma e delle strutture in esso contenute, si può
inserire nella riga 1 la valorizzazione di ‘$a’, ad esempio:
1
$a = "qualche valore";
Così facendo l’esito del primo ‘if’ cambia e di conseguenza tutto il resto dello script.
Con l’occasione si è utilizzata una nuova funzione, ‘is_integer()’, che restituisce un valore
booleano vero se la variabile ad essa fornita è di tipo intero, falso se la variabile non è intera.
Esistono altre funzioni simili per verificare il tipo delle variabili, tra cui: ‘is_array()’,
‘is_double()’, ‘is_string()’. Il funzionamento è analogo a quello di ‘is_integer()’.
Ovviamente esistono altre funzioni di questo tipo e sono raccolte nella sezione «Funzioni di
Variabili» del manuale ufficiale del PHP.
215.5.3 elseif
Si supponga di dover gestire il confronto tra due variabili ‘$a’ e ‘$b’ di tipo intero. I possibili
risultati del confronto sono tre:
•
$a > $b
•
$a < $b
•
$a = $b
Utilizzando le strutture viste fino ad ora, non si è in grado di risolvere il problema. Una soluzione
poco elegante, e sicuramente non ottimale, è eseguire tre ‘if’ in cascata.
Per risolvere problemi di questo tipo il PHP mette a disposizione la struttura ‘elseif’. La sintassi
è analoga a quella di ‘else’.
if(condizione){
istruzione 1
istruzione 2
.
.
.
istruzione n
}elseif(condizione){
istruzione 1
istruzione 2
.
.
.
istruzione m
}else{
istruzione 1
istruzione 2
.
.
.
istruzione k
}
Ecco come applicare la sintassi all’esempio precedentemente descritto:
Le basi del linguaggio
2301
0 <?
1
$a = 3; // valorizzo la variabile $a a mio piacere
2
$b = 6; // valorizzo la variabile $b a mio piacere
3
4
// adesso eseguo il confronto con un unica istruzione elseif
5
6
if ($a > $b) {
7
echo " \$a è maggiore di \$b ";
8
} elseif ($a == $b) {
9
echo " \$a è uguale a \$b ";
10
} else {
11
echo " \$a è minore di \$b ";
12
}
13
14 ?>
Dunque in questo modo si è in grado di gestire più condizioni. Il flusso è molto semplice e intuitivo. Se una delle due condizioni è soddisfatta l’interprete esegue le istruzioni ad essa associate ed
esce dal blocco ‘elseif’. Se è presente un ‘else’ finale e nessuna condizione è stata soddisfatta,
l’interprete ne esegue le istruzioni e lascia il blocco ‘elseif’.
Va precisato che viene eseguito al massimo un blocco di istruzioni. Se più condizioni sono
soddisfatte, solo le istruzioni associate alla prima condizione vera vengono eseguite, le altre
vengono saltate.
Si può inserire più di un ‘elseif(condizione)’ all’interno della struttura. Vediamo come,
modificando l’esempio precedente.
0 <?
1
$a = 3; // valorizzo la variabile $a a mio piacere
2
$b = 6; // valorizzo la variabile $b a mio piacere
3
4
// adesso eseguo il confronto con un unica istruziione elseif
5
6
if ($a > $b) {
7
echo " \$a è maggiore di \$b ";
8
} elseif ($a === $b) {
9
echo "\$a è identica a \$b";
10
} elseif ($a == $b) {
11
echo " \$a è uguale a \$b ";
12
} else {
13
echo " \$a è minore di \$b ";
14
}
15
16 ?>
Per verificare la correttezza e capire il diverso funzionamento, si provi ad assegnare alla variabile
‘$b’ i seguenti valori:
•
$b = 6;
•
$b = 3;
•
$b = 3.0;
Infine si modifichino le righe interessate allo script di esempio nel seguente modo:
8
9
10
11
} elseif ($a == $b) {
echo "\$a è uguale a \$b";
} elseif ($a === $b) {
echo " \$a è identica a \$b ";
Le basi del linguaggio
2302
In questo modo la voce ‘$a è identica a $b’ non viene mai visualizzata. Al lettore il
semplice compito di scoprirne il motivo. 5
215.5.4 switch
Spesso ci si trova a dover confrontare il contenuto di una variabile con più valori, in questi casi è
preferibile utilizzare la struttura ‘switch’ al posto di ‘elseif’. Un esempio renderà più chiaro
il concetto.
Si supponga di dover gestire un menu. In base al valore di una variabile vengono eseguite una
o più operazioni. Nell’esempio la variabile ‘$scelta’ è valorizzata nella riga 2. Per provare il
funzionamento del programma basterà cambiare il valore a questa variabile.
0 <?
1
// valorizzo la variabile $scelta
2
$scelta = 0;
3
4
// con switch gestisco i confronti e le operazioni.
5
6
switch ($scelta) {
7
case 0:
8
echo "<br> lancio l’istruzione associata al valore 0 ";
9
break; // esce da switch
10
case 1:
11
echo "<br> lancio l’istruzione associata al valore 1 ";
12
break; // esce da switch
13
case 2:
14
echo "<br> lancio l’istruzione associata al valore 2 ";
15
break; // esce da switch
16
default:
17
echo "<br> NESSUNA OPERAZIONE ASSOCIATA alla scelta";
18
19
}
20
21 ?>
Nella struttura ‘switch’ a differenza di ‘elseif’, l’interprete esegue le istruzioni successive al
‘case’ soddisfatto. Questo è il motivo per cui si utilizza il comando ‘break’. Più avanti si tratterà
questo costrutto, per il momento basta sapere che serve ad abbandonare la struttura di controllo.
L’esempio precedente genera un risultato di questo tipo:
lancio l’istruzione associata al valore 0
Se non ci fossero i ‘break’ in ogni blocco di istruzione il risultato sarebbe:
lancio l’istruzione associata al valore 0
lancio l’istruzione associata al valore 1
lancio l’istruzione associata al valore 2
NESSUNA OPERAZIONE ASSOCIATA alla scelta
Se il funzionamento di ‘switch’ non risulta ancora chiaro, si provi, dopo aver tolto le istruzioni
‘break’, ad assegnare alla variabile ‘$scelta’ i valori: 0,1 e 2, verificandone i singoli risultati.
Nel caso di più uguaglianze la differenza tra ‘switch’ e ‘elseif’ è minima, in questi casi,
l’utilizzo di ‘switch’ risulta più elegante e leggibile di ‘elseif’. Di seguito viene riportato
l’esempio precedente riscritto utilizzando la struttura elseif.
0
1
<?
// valorizzo la variabile $scelta
5
La condizione di identità include quella di uguaglianza, quindi, se due variabili sono identiche di conseguenza
sono anche uguali, mentre non è vero il contrario. Ecco perchè bisogna fare attenzione all’ordine in cui si scrivono le
condizioni.
Le basi del linguaggio
2303
2
$scelta = 0;
3
4
// adesso utilizzo elseif per gestire le operazioni
5
6
if($scelta == 0) {
7
echo "<br> lancio l’istruzione associata al valore 0 ";
8
}elseif($scelta == 1){
9
echo "<br> lancio l’istruzione associata al valore 1 ";
10
}elseif($scelta == 2){
11
echo "<br> lancio l’istruzione associata al valore 2 ";
12
}else{
13
echo "<br> NESSUNA OPERAZIONE ASSOCIATA alla scelta";
14
}
15
16 ?>
215.5.5 while
Il ‘while’ è la struttura di gestione dei cicli più semplice del PHP. La traduzione in italiano è:
"mentre".
La sintassi è la seguente:
while(condizione){
istruzione 1
istruzione 2
.
.
.
istruzione n
}
Cioè: «MENTRE la condizione è vera esegui le istruzioni».
Il seguente esempio può aiutare a chiarire le idee.
0
1
2
3
4
5
6
<?
$i=1;
while ($i <= 6){
// mentre $i è minore o uguale a 7
echo "<br> \$i adesso vale: ".$i;
$i++;
}
?>
Dunque, in questo caso la condizione di stop, che fa fermare il ciclo, è ‘$i > 6’. Ovvero ‘$i <=
6’ è falsa.
Il risultato è il seguente:
$i
$i
$i
$i
$i
$i
adesso
adesso
adesso
adesso
adesso
adesso
vale:
vale:
vale:
vale:
vale:
vale:
1
2
3
4
5
6
Tramite un semplice ciclo PHP si può generare una pagina HTML come quella riportata in figura
215.3
Le basi del linguaggio
2304
Figura 215.3. Questo è stato generato dal ciclo ‘while’.
Semplicemente è stato eseguito il seguente codice:
0 <html>
1
<head>
2
<title>Ciclo while</title>
3
</head>
4
<body>
5
6
<br> Un ciclo WHILE<br><hr>
7
8
<?
9
$i=1;
10
while ($i <= 6){
11 ?>
12
13
<br> <font size="<?=$i?>">Questo è un font con size = <?=$i?></font>
14
15 <?
16
$i++;
17
}
18 ?>
19
20
21
</body>
22 </html>
Dal menu visualizza del navigatore, l’opzione sorgente
0 <html>
1
<head>
2
<title>Ciclo while</title>
3
</head>
4
<body>
5
<br> Un ciclo WHILE<br><hr>
6
7
<br> <font size="1">Questo è
8
<br> <font size="2">Questo è
9
<br> <font size="3">Questo è
10
<br> <font size="4">Questo è
11
<br> <font size="5">Questo è
12
<br> <font size="6">Questo è
13
14
</body>
15 </html>
un
un
un
un
un
un
font
font
font
font
font
font
con
con
con
con
con
con
pagina,
size
size
size
size
size
size
=
=
=
=
=
=
mostra il seguente codice:
1</font>
2</font>
3</font>
4</font>
5</font>
6</font>
Le righe dalla 7 alla 12 sono state generate dall’interprete con l’esecuzione del ciclo ‘while’
dell’esempio.
Le basi del linguaggio
2305
215.5.6 do..while
A differenza del ‘while’ il ‘do..while’ esegue il controllo sulla condizione dopo l’esecuzione
delle istruzioni. Ecco la sintassi:
do {
istruzione 1
istruzione 2
.
.
.
istruzione n
}while(condizione);
Dunque l’interprete esegue le istruzioni e solo dopo controlla la condizione di stop, se è vera
riesegue le istruzioni, se è falsa abbandona il ciclo.
Di seguito è riportato un esempio costituito da due cicli, uno utilizza il costrutto ‘do..while’,
l’altro il ‘while’. Le condizioni iniziali e di uscita sono le stesse ma il risultato è diverso. Al
lettore il compito di capire tali differenze.
0 <?
1
// Condizione iniziale!
2
$inizio = 0;
3
4
// ciclo do..while
5
6
do{
7
echo "<br> ciclo: do..while. \$inizio vale: ".$inizio;
8
}while($inizio > 0);
9
10
// mentre il ciclo while
11
12
while($inizio > 0){
13
echo "<br> ciclo: while. \$inizio vale: ".$inizio;
14
}
15 ?>
215.5.7 for
La sintassi del ciclo ‘for’ può sembrare incomprensibile ad una prima lettura, invece è molto
coincisa, versatile e, con un po’ di pratica, semplice. Eccola:
for(condizione
istruzione
istruzione
.
.
.
istruzione
}
iniziale; condizione stop; variazione parametro){
1
2
n
Tale sintassi viene applicata nel seguente modo:
for($i=0; $i<10; $i++){
echo "<br>tutte le istruzioni che desidero";
}
Il codice dell’esempio può essere letto come: «partendo da $i = 0, mentre $i<10 esegui le
istruzioni e incrementa $i di uno ».
Sia le condizioni che la variazione possono essere omesse o incluse tra le istruzioni. Per il momento verrà trattata la sintassi classica. Il modo più semplice e diretto è, come al solito, un
esempio ben commentato.
2306
Le basi del linguaggio
0 <?
1
// sintassi classica:
2
3
for($i=0; $i<10; $i++){
4
echo "<br> non serve incrementare, lo fa il for";
5
echo "<br> infatti ecco il valore di \$i: ".$i;
6
}
7
8
// se ho una sola istruzione, come con l’if
9
10
for ($i=0; $i<10; $i++)
11
echo "<br> per una sola va bene così. \$i vale: ".$i;
12
13
// oppure se è solo un print
14
15
for($i=0; $i<10; print"<br>".$i, $i++)
16
17
// Ancora posso incrementare $i tra le istruzioni
18
19
for($i=0; $i<10; ){
20
echo "<br>incrementare \$i altrimenti il ciclo è infinito. \$i=".$i;
21
$i++;
22
}
23
24
// Oppure premetto la condizione iniziale.
25
26
$i=0;
27
for( ; $i<10; $i++){
28
echo "<br>eccolo : ".$i;
29
}
30
31 ?>
Come detto è possibile omettere anche le condizioni iniziale e di stop. Per fare questo è necessario utilizzare la struttura ‘break’ che verrà introdotta nelle pagine seguenti. In quell’occasione
verranno trattate tali eccezioni.
A questo punto, un ottimo esercizio per il lettore è la traduzione degli esempi visti per le strutture
del ‘while’ e ‘do..while’, in script uguali o simili utilizzando le varie derivazioni del costrutto
‘for’.
215.5.8 foreach
Va subito notato che il costrutto ‘foreach’ è stato implementato dalla versione 4.0 in poi e quindi
non è gestita dalle versioni precedenti del PHP.
L’uso del ‘foreach’ è indicato per la gestione degli array e mette a disposizione due sintassi
principali:
foreach($variabile_array as $value){
....
istruzioni
....
}
e:
foreach($variabile_array as $key => $value){
...
istruzioni
...
}
Le basi del linguaggio
2307
il suo funzionamento, a differenza del semplice ‘for’, non è molto intuitivo ed è vincolato all’utilizzo di un array. Si nota immediatamente che la sintassi non richiede l’utilizzo di indici ne
di incrementi, infatti il costrutto opererà su tutti gli argomenti dell’array indistintamente. Dunque questo strumento risulta comodo e versatile quando si ha a che fare con array con chiavi
particolari o non consecutive (nel caso di chiavi numeriche).
Si supponga di avere un primo array composto da chiavi intere e consecutive simile al seguente:
<?
$array_1 = array (1, "a", 5, "c", "ciao");
print_r($array_1);
?>
// con chiavi da 0 a 4
e un secondo composto da chiavi miste e quindi non consecutive come questo:
<?
$array_2 = array (
"uno" => 1,
"frutta" => "mela",
5 => "cinque",
40 => 30
);
print_r($array_2);
?>
//
//
//
//
chiave
chiave
chiave
chiave
stringa e valore intero
stringa e valore stringa
intero e valore stringa
intero e valore intero
I risultati dei due script sono semplicemente:
Array ( [0] => 1 [1] => a [2] => 5 [3] => c [4] => ciao )
Array ( [uno] => 1 [frutta] => mela [5] => cinque [40] => 30 )
Si supponga ora di non conoscere le chiavi del secondo array perchè assegnate dinamicamente da
un codice precedente. In questo caso non si sarebbe in grado di operare sull’array con le strutture
cicliche classiche perchè non c’è nessuna relazione tra le chiavi. Mentre nel primo la relazione
tra le chiavi è semplice, sono interi successivi a partire da 0. In queste situazioni la struttura
‘foreach’ è tanto indispensabile quanto semplice ed immediata da utilizzare.
L’esempio potrebbe continuare con la necessità di separare i valori interi da quelli non interi, contenuti in ‘$array_2’. Di seguito viene risolto il problema con l’utilizzo del costrutto ‘foreach’
e della prima sintassi.
0 <?
1
foreach ($array_2 as $val) {
2
echo "<br>\$val = ".$val;
3
if(is_integer($val)){
4
echo " ------&gt; ed è un intero...";
5
// possono seguire istruzioni per trattare i dati interi
6
}else{
7
echo " ------&gt; ma non è un intero...";
8
// possono seguire istruzioni per trattare i dati NON interi
9
}
10
}
11 ?>
‘foreach’ in italiano può essere tradotto come ‘per ogni’, dunque la sintassi è ora più chiara:
per ogni valore dell’array ‘$array_2’ preso come ‘$val’ esegui le istruzioni associate.
Il costrutto ad ogni ciclo valorizza la variabile ‘$val’ con un elemento dell’array. Ripete
l’operazione per tutti gli elementi indipendentemente dalle chiavi ad essi associati.
Nell’esempio le cose sono state complicate con l’annidamento di un ‘if’ che verifica ad ogni
ciclo il tipo di dato estratto dall’array, il risultato è il seguente:
$val = 1 ------> ed è un intero...
$val = mela ------> ma non è un intero...
Le basi del linguaggio
2308
$val = cinque ------> ma non è un intero...
$val = 30 ------> ed è un intero...
A questo punto è semplice dedurre il funzionamento della seconda sintassi, infatti, il ‘foreach’
può estrarre sia la chiave che il valore degli elementi contenuti nell’array. Complicando
ulteriormente lo script precedente si può verificare il funzionamento della seconda sintassi.
0 <?
1
foreach ($array_2 as $chiave => $valore) {
2
echo "<br>\$val = ".$valore;
3
if(is_integer($valore)){
4
echo " ------&gt; ed è un intero...";
5
echo " ------&gt; questa la sua chiave: ".$chiave;
6
// possono seguire istruzioni per trattare i dati interi
7
}else{
8
echo " ------&gt; ma non è un intero...";
9
echo " ------&gt; questa la sua chiave: ".$chiave;
10
// possono seguire istruzioni per trattare i dati NON interi
11
}
12
}
13 ?>
Sono state aggiunte le righe 5 e 9 che visualizzano il volore delle chiavi ed è stata modificata
la sintassi della riga 1 in cui si chiede al ‘foreach’ di estrarre anche le chiavi degli elementi
dell’array oltre al valore e di assegnarli alle variabili ‘$chiave’ e ‘$valore’. Il risultato è il
seguente:
$val
$val
$val
$val
=
=
=
=
1 ------> ed è un intero... ------> questa la sua chiave: uno
mela ------> ma non è un intero... ------> questa la sua chiave: frutta
cinque ------> ma non è un intero... ------> questa la sua chiave: 5
30 ------> ed è un intero... ------> questa la sua chiave: 40
In conclusione il costrutto ‘foreach’ è una struttura ciclica dedicata alla manipolazione degli array. Ovviamente possono essere gestiti anche array multidimensionale con dei ‘foreach’
annidati, il lettore può approfondire l’argomento sul manuale ufficiale.
L’esempio trattato è raggiungibile all’indirizzo: <http://www.urcanet.it/brdp/php_manual/esempi/cap_2/
foreach.php>
215.5.9 break
Il costrutto ‘break’ serve ad abbandonare una struttura di controllo, nel dettaglio permette di
uscire da: ‘for’, ‘foreach’, ‘while’, ‘do..while’ e ‘switch’, e ammette un parametro numerico opzionale. Tale parametro deve essere un intero che indicherà il "livello" della struttura da
abbandonare. Ad esempio, nel caso di due o più strutture annidate, si potrebbe voler uscire da
una o più di esse: questo è possibile tramite il parametro.
Con l’occasione verranno approfondite, negli esempi seguenti, le strutture tralasciate in
precedenza.
0 <?
1
2
$i = 0;
3
while (++$i) {
// il while incrementa anche in questo modo
4
5
if($i == 3){
6
7
echo "<br>Conto fino a ".$i." ed esco solo dal conteggio: ";
8
9
for ($t = 1; ;$t++) { // la condizione di stop è tra le istruzioni.
10
if ($t > $i) {
11
break 1;
// esce solo dal for equivale a break senza parametri.
12
}
Le basi del linguaggio
2309
13
echo " ".$t;
14
}
15
16
}elseif($i == 9){
17
18
echo "<br> Conto fino a ".$i." ed esco dal for e dal while:";
19
20
$t = 1;
21
for (;;) { // Nessuna condizione è espressa nel costrutto.
22
if ($t > $i) {
23
break 2; // il parametro è 2 quindi esce dal for e dal while.
24
}
25
echo " ".$t;
26
$t++;
27
}
28
29
}
30
31 }
32
33 echo "<br><br> fine dello script!";
34
35 ?>
Come detto in precedenza, è importante curare l’indentazione del codice. L’ultimo esempio è
composto da un ciclo ‘while’ che include un ‘elseif’ e due cicli ‘for’ che, a loro volta, contengono un ‘if’ ciascuno. Tutto questo susseguirsi di parentesi può creare confusione e rendere
il codice illegibile se non si presta attenzione all’indentazione.
Nella maggior parte dei casi, se il codice è ben scritto e ragionato, non si ha bisogno della struttura
‘break’. Tuttavia è bene sapere che esiste.
215.5.10 include()
Il PHP permette di includere uno o più file in un punto ben preciso di un altro file. Tali file
possono, a loro volta, contenere codice PHP che verrà interpretato se delimitato dagli appositi
marcatori.
Si pensi alla gestione di modelli grafici, alla necessità di dichiarare le stesse variabili in più file,
all’inclusione di funzioni già pronte e via dicendo. In tutti questi casi è possibile creare un file
specifico in cui inserire il codice che va incluso negli script. Ovviamente è possibile includere
anche file residenti su macchine diverse dalla nostra. Di seguito vedremo come fare.
Per l’inclusione dei file il PHP offre diverse soluzioni. In questa guida verrà approfondita la
funzione ‘include()’. Ne esistono altre che sono riportate nel manuale ufficiale.
La sintassi di base è la seguente:
0
1
2
3
4
5
<?
// inclusione di un file chiamato esterno.html
include(’esterno.html’);
?>
è preferibile utilizzare le stringhe con double quote perchè meglio gestite e più versatili:
0
1
2
3
4
5
<?
// oppure con il double quote
include("esterno.html");
?>
Le basi del linguaggio
2310
Come accennato in precedenza, il file da includere può trovarsi su una macchina diversa dalla
nostra. Supponiamo che sia accessibile tramite il protocollo HTTP. La sintassi sarà:
0
1
2
3
4
5
6
7
8
<?
/* inclusione di un file remoto.
Su una macchina diversa, tramite
il protocollo HTTP
*/
include("http://www.url_altro_sito.com/esterno.html");
?>
Questo modo di operare è del tutto corretto. Tuttavia va tenuto conto dei seguenti fattori:
• l’elevato tempo di accesso al servente remoto, che può causare un ritardo nella generazione
della pagina e può rallentare notevolmente la visualizzazione della stessa;
• l’elaboratore servente potrebbe essere irraggiungibile o il file essere inesistente;
• il contenuto del file remoto potrebbe essere modificato a nostra insaputa.
Alcuni di questi ostacoli possono essere aggirati, altri no. Ad esempio, il primo problema non
è risolvibile. Per quanto una connessione sia veloce ed i servizi performanti si aggiunge sempre
un intervallo di tempo dovuto alla procedura di richiesta del file. Questo è un parametro molto
importante, che va tenuto presente quando si effettua una scelta di questo tipo. Il tempo necessario, inoltre, non è sempre lo stesso ma dipende da svariati fattori, ad esempio il traffico sul sito
remoto, il traffico sulla rete, ecc...
Il secondo punto può essere affrontato in vari modi, quello più sbrigativo è sicuramente la
gestione dell’errore generato con la mancata inclusione del file. Ecco un modo di procedere:
0
1
2
3
4
5
6
7
8
9
<?
/* inclusione di un file remoto. Su una macchina diversa,
tramite il protocollo HTTP.
Compresa la gestione dell’errore!!!
*/
if( !@include("http://www.url_altro_sito.com/esterno.html") )
echo "<br><br> Problemi di visualizzazione! torna a trovarci...";
?>
In questo modo si è reso invisibile l’eventuale messaggio di errore dell’interprete tramite il prefisso ‘@’. Per il resto si tratta di un semplice ‘if’ che verifica il valore restituito dalla funzione
‘include()’, se il valore è falso visualizza il messaggio di errore, altrimenti include il file e
prosegue.
Se il file remoto è uno script, ad esempio PHP, prima di essere incluso viene interpretato dal
servente, quindi viene incluso il risultato dello script generato in remoto e non sull’elaboratore
su cui è ospitato il nostro script .
Programmare in PHP --- Copyright © 2001-2002 Gianluca Giusti -- brdp @ urcanet.it
Capitolo
216
Passaggio di variabili tramite l’HTTP
Fino ad ora sono stati trattati i casi di singole pagine PHP in cui le variabili sono valorizzate, manipolate e visualizzate con l’interpretazione del singolo file. In questo modo l’utente che naviga
la pagina non è in grado di interagire con gli script, non può passare dei dati al programma perchè
non può editarne il codice. Il protocollo HTTP permette, tramite i marcatori HTML di passare
dei dati tra le pagine, il PHP è in grado di ricevere ed elaborare queste informazioni.
Nelle pagine seguenti verranno trattati i metodi di scambio di variabili dando per scontata la
conoscenza, come detto in principio, dell’HTML.
L’HTML permette al navigatore di inserire dati tramite il marcatore ‘form’ che riceve dagli
attributi ‘action’ e ‘method’ le direttive relative al file che deve ricevere i dati e al modo in cui
essi devono esseregli passati. L’attributo ‘method’ ammette due possibili valori: ‘get’ e ‘post’.
Di seguito saranno approfondite le differenze tra i due metodi.
216.1 Metodo get
Quando si sceglie il metodo ‘get’ le variabili ed il relativo valore vengono fornite allo script
destinatario tramite la barra dell’indirizzo del browser.
Il modo migliore per chiarire il concetto è l’utilizzo di un esempio. Verranno realizzati due script,
‘get_1.html’ e ‘get_2.php’. ‘get_1.html’ invierà i dati contenuti nel ‘form’ a ‘get_2.php’
utilizzando il metodo ‘get’, ‘get_2.php’ riceverà i dati, li manipolerà e li visualizzerà in una
semplice pagina di saluto. Questo l’indirizzo dell’esempio: <http://www.urcanet.it/brdp/php_manual/
esempi/cap_3/get_1.html>
Ecco il codice del file ‘get_1.html’:
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<html>
<head>
<title> Passaggio del nome! </title>
</head>
<body>
<br>
Una semplice pagina HTML che passa nome e cognome ad
uno script PHP che saluterà il navigatore.
<br><br>
<form method="get" action="get_2.php">
Dimmi il tuo nome: <input type="Text" name="nome"> <br><br>
Ed ora il Cognome: <input type="Text" name="cognome"> <br><br>
<input type="Submit" value="Adesso invia i dati in GET &gt;&gt;">
</form>
</body>
</html>
Il primo file invia i due campi di testo al file destinatario ‘get_2.php’ che riceve due variabili
valorizzate con i dati inseriti dal navigatore. Le variabili hanno il nome del campo del ‘form’,
nell’esempio le variabili sono ‘$nome’ e ‘$cognome’ e sono di tipo stringa.
Il codice del secondo script è molto semplice, non fa altro che visualizzare i valori delle due
variabili.
2311
Passaggio di variabili tramite l’HTTP
2312
0
1
2
3
4
5
6
7
8
9
10
11
12
13
<html>
<head>
<title> Pagina di destinazione... </title>
</head>
<body>
Ciao, <br><br>
Il tuo nome è: <?=$nome?> <br>
e il tuo cognome è: <?=$cognome?>
</body>
</html>
Figura 216.1. Come appare il ‘form’ di invio dei dati.
Figura 216.2. Nella barra degli indirizzi è evidenziata la sintassi del metodo ‘get’ per il
passaggio delle variabili.
L’obiettivo di questo esempio è quello di capire come funziona il metodo ‘get’, per farlo basta
leggere il contenuto della barra degli indirizzi nel browser durante la visualizzazione dello script
destinatario. L’indirizzo è simile a:
http://www.urcanet.it/ ... ual/esempi/cap_3/get_2.php?nome=Gianluca&cognome=Giusti
Risulta semplice e intuitivo capire come vengono passate variabili e valori. All’indirizzo della
pagina viene aggiunto un carattere ‘?’ e di seguito tutte le coppie di variabili e rispettivo valore
separate dal ‘=’, ad esempio: ‘nome=Gianluca’. Le coppie sono poi separate dal carattere ‘&’.
Passaggio di variabili tramite l’HTTP
2313
216.2 Metodo post
Nel metodo ‘post’ i dati non vengono visualizzati in nessun modo, essi sono spediti tramite il
protocollo HTTP e non sono visibili sul navigatore.
Una semplice verifica può essere eseguita modificando lo script ‘get_1.html’ nel seguente
modo:
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<html>
<head>
<title> Passaggio del nome! </title>
</head>
<body>
<br>
Una semplice pagina HTML che passa nome e cognome ad
uno script PHP che saluterà il navigatore.
<br><br>
<form method="post" action="get_2.php">
Dimmi il tuo nome: <input type="Text" name="nome"> <br><br>
Ed ora il Cognome: <input type="Text" name="cognome"> <br><br>
<input type="Submit" value="Adesso invia i dati in GET &gt;&gt;">
</form>
</body>
</html>
Salvato come ‘post_1.html’ è possibile testarne il funzionamento e verificare che nella pagina ‘get_2.php’ la barra degli indirizzi del programma di navigazione è priva delle coppie di
variabili, allo stesso tempo lo script ha funzionato e viene visualizzato il messaggio di saluto
correttamente.
Analizzando lo script ‘post_1.html’ si nota che l’unica modifica è quella all’attributo ‘method’
del marcatore ‘form’.
216.3 Quale metodo scegliere?
Non c’è una regola particolare per scegliere l’uno piuttosto che l’altro metodo. Possiamo dire
che se la quantità di dati da inviare è grande è preferibile utilizzare il ‘post’. Il protocollo HTTP
permette, tramite i form HTML, l’upload di file dall’elaboratore cliente a quello servente, in
questi casi è bene utilizzare il metodo ‘post’.
Nel file di configurazione del PHP (‘php.ini’) può essere definita sia la dimensione massima dei
file che il servente accetterà tramite HTTP, sia la dimensione massima dei dati accettati tramite
‘post’. Quest’ultimo valore può essere definito valorizzando la variabile ‘post_max_size’ nel
‘php.ini’.
Quando i dati da scambiare sono pochi e non importa che risultino direttamente visibili si può
utilizzare il metodo ‘get’, che è comodo anche per quelle situazioni in cui si utilizza spesso
il tasto avanti e indietro del navigatore. Le variabili sono memorizzate insieme all’indirizzo e
quindi ogni volta che si richiama una pagina ad essa vengono rifornite le variabili e i loro valori.
Per rendersi conto di questo basta tenere d’occhio la barra degli indirizzi durante le ricerche su un
qualunque motore di ricerca, il 99% di essi passano i dati tramite il metodo ‘get’. È altrettanto
vero che i dati passati al motore per le ricerche sono decisamente pochi, di solito si tratta di una
stringa con dei parametri che il motore aggiunge automaticamente.
Passaggio di variabili tramite l’HTTP
2314
216.4 Cosa è cambiato nel PHP versione 4.2
Dalle versioni del PHP 4.2 e successive la gestione delle variabili passate tramite moduli
HTML è sensibilmente cambiata. Nel file di configurazione viene valorizzata a vero la variabile
track_vars , in questo modo tutte le variabili presenti in un modulo ed inviate ad uno script PHP
vengono inserite in un array associativo contenente il nome delle variabile e il relativo valore.
Ad esempio nel caso dello script ‘get_2.php’ visto nelle sezioni 216.1 e 216.2 si avrebbe la
necessità di distinguere il metodo di invio. Più precisamente nel caso di un invio tramite metodo
‘get’ il file ‘get_2.php’ dovrebbe essere così modificato:
0
1
2
3
4
5
6
7
8
9
10
11
12
13
<html>
<head>
<title> Pagina di destinazione... </title>
</head>
<body>
Ciao, <br><br>
Il tuo nome è: <?=$HTTP_GET_VARS["nome"]?> <br>
e il tuo cognome è: <?=$HTTP_GET_VARS["cognome"]?>
</body>
</html>
Le differenze sono lampanti e riguardano le righe 9 e 10. L’interprete prende il valore ricevuto dalla variabile predefinita $HTTP_GET_VARS che come detto in precedenza è un array
associativo
Nel caso di un invio tramite metodo ‘post’ il programma andrebbe così modificato:
0
1
2
3
4
5
6
7
8
9
10
11
12
13
<html>
<head>
<title> Pagina di destinazione... </title>
</head>
<body>
Ciao, <br><br>
Il tuo nome è: <?=$HTTP_POST_VARS["nome"]?> <br>
e il tuo cognome è: <?=$HTTP_POST_VARS["cognome"]?>
</body>
</html>
Questo tipo di gestione delle variabili può sembrare prolissa ma evita confusioni all’interprete e
costringe il programmatore a specificare la variabile su cui operare.
Ovviamente se si hanno pagine sviluppate secondo le vecchie specifiche basterà settare a falso la
variabile track_vars nel file di configurazione del PHP, in questo modo tutto dovrebbe funzionare
correttamente.
Programmare in PHP --- Copyright © 2001-2002 Gianluca Giusti -- brdp @ urcanet.it
Capitolo
217
L’utilizzo delle funzioni in PHP
Una funzione può essere intesa come un "sotto-programma" a cui si possono fornire dei valori
per ottenere una risposta da essi dipendente o meno.
Il PHP mette a disposizione degli sviluppatori una vasta gamma di funzioni predefinite, tuttavia
in alcune situazioni è necessario eseguire operazioni particolari, in questi casi è possibile definire
delle funzioni personali che si comportano secondo le proprie necessità.
Si prenda d’esempio lo script del paragrafo 215.3.5 in cui si visualizzava la data formattata in
un modo particolare, è improponibile dover scrivere 38 righe di codice ogni volta che si desidera
visualizzare la data all’interno di una pagina HTML in questo caso la soluzione migliore è realizzare una funzione dedicata che restituisce la data mediante una semplice "chiamata". Per evitare
errori e ripetitive modifiche è consigliabile realizzare uno o più file in cui raccogliere le funzioni
personali più utilizzate, una sorta di libreria, da premettere in ogni pagina tramite il costrutto
‘include()’.
217.1 Le funzioni predefinite
Come detto in principio non è volontà dell’autore riportare l’elenco delle funzioni PHP, esse sono
catalogate ed abbondantemente illustrate nel manuale ufficiale reperibile al sito internet: <http://
www.php.net>.
Di seguito si vuole illustrare la struttura del manuale e il modo in cui esso va consultato per
cercare, scegliere ed infine utilizzare le innumerevoli funzioni predefinite del linguaggio. Come
sempre il modo migliore è l’utilizzo di un semplice esempio. Si supponga di voler realizzare uno
programma che visualizzi una porzione di una stringa. Bisogna come prima cosa individuare le
funzioni che permettono di manipolare le stringhe.
Nella sezione "IV. Guida Funzioni" sono catalogate le funzioni messe a disposizione del programmatore, esse sono raggruppate per argomento. La sottosezione "LXXXIII. String functions"
contiene le funzioni dedicate alla gestione delle stringhe. Come prima cosa si trova una descrizione della sezione e poi un lungo elenco, in ordine alfabetico, di funzioni con accanto una breve
ma molto intuitiva descrizione. La funzione ‘substr()’ potrebbe risolvere il problema sollevato
nell’esempio.
Nel primo blocco della pagina descrittiva si trova il nome della funzione subito seguito dalle
versioni dell’interprete PHP che la gestiscono e da una breve descrizione. Nel caso particolare:
substr
(PHP 3, PHP 4 >= 4.0.0)
substr -- Return part of a string
A seguire la descrizione approfondita che inizia con una delle parti più importanti della documentazione, infatti, in una sola riga viene spiegato l’intero funzionamento del comando. Nell’esempio
proposto:
string substr (string string, int start [, int length])
Come detto questa è forse la parte più importante, la prima parola descrive il tipo di dato restituito
dalla funzione, nel caso particolare ‘string’, dunque la funzione restituisce una stringa. Dopo il
nome della funzione tra parentesi i valori che la funzione può accettare ed il relativo tipo di dato,
va sottolineato che tra parentesi quadre vengono elencati i parametri non obbligatori e il relativo
tipo di dato.
2315
L’utilizzo delle funzioni in PHP
2316
Nel particolare la funzione accetta un primo dato di tipo stringa, separato da virgola il numero del
carattere di partenza di tipo intero (si parte sempre da 0 e non da 1) ed infine come dato opzionale
la lunghezza, di tipo intero, della porzione di stringa da estrarre.
A questo schema seguono una descrizione approfondita ed una serie di esempi di funzionamento.
Gli esempi se presenti sono molto utili ed autoesplicativi, inoltre trattano varie eccezioni ed
eventuali casi particolari.
In fine ma non meno importante la sezione contenente le funzioni correlate o in qualche modo
relazionate con quella in oggetto. Il manuale spesso suggerisce di consultare anche altre funzioni,
in questo caso:
See also strrchr() and ereg().
Spesso non esiste un unico modo per raggiungere la soluzione del problema e spesso questa
ultima sezione fornisce degli spunti molto interessanti che possono portare ad una soluzione più
semplice e brillante, il consiglio è di non sottovalutarla.
A questo punto è doveroso trattare almeno un esempio di utilizzo della funzione scelta come
campione.
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?
// La stringa iniziale va in $var
$var = "Questa è la stringa di partenza";
//
0123456789012345678901234567890
//
1234567890
// Le due righe superiori semplificano il conteggio dei caratteri.
// Questo esempio prende la parte: "la stringa"
$sub = substr($var, 9, 10);
echo $sub;
// Per selezionare gli ultimi 2 caratteri basta usare:
$sub = substr($var, -2);
echo "<br><br> ".$sub;
// Per selezionare i primi 2 caratteri basta usare:
$sub = substr($var, 0, 2);
echo "<br><br> ".$sub;
// Se non specifico la lunghezza della porzione continua fino alla fine
$sub = substr($var, 5);
echo "<br><br> ".$sub;
?>
Il risultato di questo semplice script è simile a:
la stringa
za
Qu
a è la stringa di partenza
Anche questo esempio è raggiungibile all’indirizzo: <http://www.urcanet.it/brdp/php_manual/esempi/
cap_4/substr.php>
L’utilizzo delle funzioni in PHP
2317
217.2 Le funzioni definite dall’utente
Un modo molto semplice di schematizzare il concetto di funzione è pensare ad una scatola che
permette tramite due fori di inserire ed estrarre dei valori. All’interno della scatola può essere
utilizzato qualunque costrutto messo a disposizione dal linguaggio, ecco perchè si parla di "sottoprogrammi". Lo schema di figura 217.1 può essere di aiuto.
Figura 217.1. Il blocco di programma principale contiene due scatole (funzioni) che
ricevono due valori e restituiscono in un caso la somma, in un altro la differenza.
L’esempio classico è quello di una semplice funzione di saluto:
0 <?
1
//---------------- Definizione delle funzioni
2
3
function saluto($ora){
4
5
/*
6
Questa funzione genera un messaggio di saluto
7
in base al valore della variabile $ora passatagli
8
che contiene l’ora, con valore tra 0 e 24
9
*/
10
11
if (5 < $ora && $ora <= 12){
12
echo "Buon Giorno.";
13
}elseif(12<$ora && $ora <= 18){
14
echo "Buon Pomeriggio.";
15
}elseif(18<$ora && $ora <= 24){
16
echo "Buona Sera!";
17
}else{
18
echo "Guarda che razza di ora è! Ma quando dormi?!";
19
}
20
}
21
22
23
//---------------- Programma principale
24
25
$orario = date("H"); // estraggo l’ora attuale
26
27
// Richiamo la funzione e ci aggiungo del testo...
28
29
saluto($orario);
30
echo " Come va oggi?!?";
L’utilizzo delle funzioni in PHP
2318
31
32
// non serve riscrivere il codice posso inserire
33
// il saluto con una sola RIGA di codice!!!
34
35
echo "<br><br> Ancora un saluto: "; saluto($orario);
36 ?>
Lo script è costituito da una parte contenente le dichiarazioni delle varie funzioni, nel caso specifico una sola, e dal programma principale che le richiama una o più volte. Come prima cosa è
importante eseminare la sintassi per la dichiarazione delle funzioni.
function nome_funzione(variabile_1, variabile_2, .... , variabile_n){
istruzioni funzione
return valore se necessario
}
Il costrutto ‘function’ segna l’inizio della dichiarazine, subito dopo va assegnato un nome
che deve essere unico nel programma, non possono esserci più funzioni aventi lo stesso nome,
tra parentesi tonde è possibile elencare le variabili, se esistono, che devono essere fornite alla
funzione, se sono più di una vanno separate da una virgola (‘,’). Il corpo della funzione è, infine,
contenuto tra parentesi graffe (‘{...}’).
Una volta dichiarata, la funzione, può essere richiamata tutte le volte che si vuole, è questo
il vantaggio che si ha nel suddividere il lavoro in piccoli problemi e a risolverli con piccoli e
semplici sotto-programmi da richiamare ogni volta che se ne ha bisogno.
Come detto la funzione può restituire dei valori, dunque quando richiamata può essere vista come
una variabile contenente dei valori. Se si modifica l’esempio precedente come riportato di seguito,
la funzione non scriverà nulla sullo schermo ma valorizzerà tramite il comando ‘return’ il nome
della funzione, esso potrà essere visualizzato, assegnato ad un’altra variabile, ecc... Proprio come
fosse una variabile.
0 <?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
//---------------- Definizione delle funzioni
function saluto($ora){
/*
Questa funzione genera un messaggio di saluto
in base al valore della variabile ricevuta $ora
che contiene l’ora con valore tra 0 e 24
e lo restituisce al programma principale tramite
l’istruzione "return"
*/
if (5 < $ora && $ora <= 12){
return "Buon Giorno.";
}elseif(12<$ora && $ora <= 18){
return "Buon Pomeriggio.";
}elseif(18<$ora && $ora <= 24){
return "Buona Sera!";
}else{
return "Guarda che razza di ora è! Ma quando dormi?!";
}
}
//---------------- Programma principale
$orario = date("H");
// Richiamo la funzione e ci aggiungo del testo...
L’utilizzo delle funzioni in PHP
2319
29
30
$msg = saluto($orario);
// assegno il valore della funzione
31
echo $msg." Come va oggi?!?";
32
33
// una sola RIGA di codice CONCATENATO come fosse una variabile
34
35
echo "<br><br> Ancora un saluto: ".saluto($orario);
36
37 ?>
Le modifiche adottate nelle righe 14, 16, 18, 20 provvedono tramite il comando ‘return’ ad assegnare un valore al nome della funzione invece di visualizzarlo sullo schermo. Di conseguenza
cambia il modo di manipolare la funzione al momento della chiamata, infatti, in questo modo ritorna un valore che può essere trattato come una semplice variabile. Nella riga 30 viene assegnato
il valore restituito dalla funzione ad un’altra variabile, mentre nella riga 35 viene concatenato in
una stringa.
A questo punto si potrebbe avere la necessità di scegliere se far visualizzare il messaggio direttamente dalla funzione o farlo ritornare come valore. Complicando leggermente l’esempio si può
risolvere il problema. Una semplice soluzione è quella di passare una seconda variabile, che a
seconda del suo stato (vero o falso) fa comportare la funzione in due modi diversi.
0 <?
1
//---------------- Definizione delle funzioni
2
3
function saluto($ora, $modo){
4
5
/*
6
Questa funzione genera un messaggio di saluto
7
in base al valore della variabile ricevuta $ora
8
che contiene l’ora con valore tra 0 e 24
9
e lo restituisce al programma principale tramite
10
l’istruzione "return" se $modo è falso, se è vero
11
ne visualizza il valore.
12
*/
13
14
if (5 < $ora && $ora <= 12){
15
$msg = "Buon Giorno.";
16
}elseif(12<$ora && $ora <= 18){
17
$msg = "Buon Pomeriggio.";
18
}elseif(18<$ora && $ora <= 24){
19
$msg = "Buona Sera!";
20
}else{
21
$msg = "Guarda che razza di ora è! Ma quando dormi?!";
22
}
23
24
// controllo sul flag $modo.
25
if($modo){
26
echo $msg;
27
}else{
28
return $msg;
29
}
30
31
}
32
33
//---------------- Programma principale
34
35
$orario = date("H");
36
$modo = false;
37
38
// Richiamo la funzione e ci aggiungo del testo...
39
$msg = saluto($orario, $modo);
40
echo $msg." Come va oggi?!?"."<br><br>";
41
42
// Adesso posso anche farlo scrivere direttamente, ecco come:
2320
L’utilizzo delle funzioni in PHP
43
saluto($orario,1);
44 ?>
Adesso la funzione si aspetta due parametri, il primo serve a generare il messaggio di saluto, il
secondo (righe 25-29) a determinare il comportamento della funzione. Se cambia la dichiarazione
deve cambiare anche la chiamata alla funzione, infatti, nelle righe 39 e 43 vengono passati i due
parametri e la funzione si comporta di conseguenza.
Quando si richiama una funzione non importa il nome delle variabili che gli vengono fornite,
quello che importa è l’ordine con cui esse vengono elencate.
Dunque i valori passati alla funzione andranno nelle variabili locali (della funzione) definite
al momento della dichiarazione della stessa. Nell’esempio seguente viene approfondito questo
aspetto tramite una funzione che genera e visualizza una scheda informativa di un potenziale
utente.
0 <?
1
//---------------- Definizione delle funzioni
2
3
function scheda($nome, $cognome){
4
5
/*
6
Questa funzione ha lo scopo di chiarire il concetto di
7
variabile locale e globale. Fare inoltre attenzione
8
all’ordine con cui sono passate le variabili
9
*/
10
11
global $tel;
12
13
echo "<br>Scheda informativa utente: <br><br> ";
14
echo "<br>Nome: ".$nome;
15
echo "<br>Cognome: ".$cognome;
16
echo "<br>Telefono: ".$tel;
17
echo "<br>e-mail: ".$email;
18
echo "<br><br>-----------------------<br>";
19
}
20
21
//---------------- Programma principale
22
23
$nome = "Gianluca";
24
$cognome = "Giusti";
25
$tel = "06/66666666";
26
$email = "brdp @ urcanet.it";
27
28
// richiamo la funzione che genera la scheda.
29
scheda($nome, $cognome);
30
31
// il nome delle variabili non importa! Importa invece l’ordine
32
// con cui vengono passate alla funzione! Ecco la prova:
33
scheda($cognome, $nome);
34 ?>
Come detto in principio, le funzioni sono dei piccoli programmi a se stanti, dunque le variabili
utilizzate al loro interno, dette "variabili locali", non hanno lo stesso valore di quelle utilizzate
nel programma principale, dette "variabili globali" anche se nominate allo stesso modo. Si può
dire che sono variabili diverse. Un modo per far coincidere le variabili locali e globali è passare
le variabili globali come argomento della funzione, proprio come fatto negli esempi precedenti.
Un secondo metodo, è l’utilizzo del comando ‘global’. Nella riga 11 dell’esempio precedente
viene utilizzato per "catturare" il valore della variabile globale $tel all’interno della funzione.
Il risultato dell’ultimo programma è simile a:
L’utilizzo delle funzioni in PHP
2321
Scheda informativa utente:
Nome: Gianluca
Cognome: Giusti
Telefono: 06/66666666
e-mail:
----------------------Scheda informativa utente:
Nome: Giusti
Cognome: Gianluca
Telefono: 06/66666666
e-mail:
-----------------------
Come prima cosa va notata l’assenza dell’indirizzo e-mail, questo dipende dal fatto che la variabile $email non è stata fornita in alcun modo alla funzione quindi al suo interno non è valorizzata.
Al contrario le altre variabili sono valorizzate, $nome e $cognome vengono passate al momento
della chiamata mentre la variabile $tel viene associata a quella globale.
L’utilizzo di ‘global’ non è consigliabile dal momento che ogni modifica alla variabile utilizzata
come globale all’interno della funzione si riperquote anche nel programma principale. Se non si
hanno motivi particolari non ha senso utilizzare questo metodo.
Un ottimo esercizio per l’utente è la verifica di quanto appena detto. Modificare l’ultimo esempio
al fine di dimostrare che le modifiche alla variabile $tel effettuate all’interno della funzione si
riperquotono anche nel programma principale, mentre eventuali modifiche alle variabili passate
come argomento all’interno della funzione non hanno effetto nel programma principale.
Per i più esperti la situazione è simile al passaggio di variabili per "valore" o per "riferimento".
La funzione, inoltre, viene richiamata due volte invertendo l’ordine dei parametri a dimostrazione
che il nome delle variabili non ha alcun importanza ma quello che importa è l’ordine con cui
vengono dichiarate e passate al momento della chiamata.
In conclusione il modo migliore e più elegante per realizzare la scheda utente dell’esempio è
fornire tutti i dati necessari alla funzione come parametri della chiamata.
0 <?
1
//---------------- Definizione delle funzioni
2
3
function scheda($nome, $cognome, $tel, $email){
4
5
// Il modo più corretto è il passaggio delle variabili
6
// Salvo casi particolari in cui si è obbligati ad usare il global
7
8
echo "<br>Scheda informativa utente: <br><br> ";
9
echo "<br>Nome: ".$nome;
10
echo "<br>Cognome: ".$cognome;
11
echo "<br>Telefono: ".$tel;
12
echo "<br>e-mail: ".$email;
13
echo "<br><br>-----------------------<br>";
14
}
15
16
17
//---------------- Programma principale
18
19
$nome = "Gianluca";
20
$cognome = "Giusti";
21
$telefono = "06/66666666";
22
$posta_elettronica = "brdp @ urcanet.it";
2322
L’utilizzo delle funzioni in PHP
23
24
// richiamo la funzione che genera la scheda. I nomi non contano!
25
scheda($nome, $cognome, $telefono, $posta_elettronica);
26
27 ?>
Uno degli aspetti più importanti di un sito Internet è l’estetica ed è anche la parte che viene
rinnovata più di frequente. Si pensi alla necessità di elencare degli oggetti secondo particolari
vesti grafiche, utilizzando una funzione è possibile modificare varie pagine, in cui essa viene
richiamata, modificando una sola porzione di codice. Un altro esempio è dato dai siti in cui
è possibile personalizzare la formattazione dei dati tramite la scelta di modelli predefiniti, in
questo caso la funzione potrebbe ricevere un parametro in più che rappresente il modello, oppure
si potrebbero implementare varie funzioni che formattano i medesimi dati in modo differente.
Come conclusione si può senza dubbio affermare che un programma strutturato è molto più
leggibile ed elegante di uno costituito da un unico blocco di codice spesso incomprensibile.
In fine va notato che ci sono delle operazioni che vengono ripetute spesso nel lavoro di tutti i
giorni, ad esempio formattazione della data in vari formati, connessione e interrogazioni di basi
di dati, paginazione di elenchi, gestione di immagini, upload di file, ecc... La cosa più intelligente
è creare dei file, paragonabili a librerie, contenenti le dichiarazioni delle funzioni più utilizzate,
a questo punto basterà includere tali "librerie" in cima agli script in modo da poter richiamare
le funzioni senza dovrele dichiarare ogni volta. Ancora più corretto è la creazione di "librerie"
contenenti delle classi con cui poter dichiarare dei veri e propri oggetti ma questo verrà spiegato
nella sezione dedicata alla programmazione avanzata.
Un esercizio interessante lasciato al lettore è quello di implementare una funzione chiamata
‘isint($var)’, supponendo che non esista la funzione già vista ‘is_integer()’, che utilizzando ‘gettype()’ restituisca un valore vero se la variabile passata è un intero o falso se la
variabile è di un altro tipo.
217.3 Le funzioni ricorsive
Il PHP permette di richiamare le funzioni in modo ricorsivo, ovvero è possibile richiamare una
funzione dal suo interno. Un classico esempio applicativo di questa tecnica è il calcolo del
fattoriale. Come noto il fattoriale di un numero intero positivo n (indicato come n! ) è pari a
n*(n-1)*(n-2)*...*(n-(n-1)) . Ad esempio:
5! = 5*4*3*2*1 = 120
Ecco come risolvere il problema con l’utilizzo di una funzione ricorsiva:
0<html><body>
1 <?
2
//---------------- Definizione delle funzioni
3
4
function fattoriale($numero){
5
6
if($numero <= 1){
7
return 1;
// abbandona la ricorsione
8
}else{
9
return $numero*fattoriale($numero-1); //la funzione richiama se stessa
10
}
11
12 }
13
14
15 //---------------- Programma principale
16
17 echo "<br>Calcolo del fattoriale:<br>";
L’utilizzo delle funzioni in PHP
2323
18
19 for($i=-2; $i<=10; $i++){
20
echo "<br>Il fattoriale di $i è: ".fattoriale($i);
21 }
22
23 ?>
24
25 </body></html>
All’interno della dichiarazione, riga 9, viene richiamata la funzione stessa passandogli il numero
decrementato di uno. Questo perchè n! = n*(n-1)! = n*(n-1)*(n-2)! e così via... Il fattoriale di 0
è pari ad 1 per definizione. Per semplificare il controllo si è stabilito che il fattoriale di un numero
negativo è pari ad 1 anche se non è corretto matematicamente.
L’attenzione non deve essere focalizzata sull’aspetto matematico ma sul fatto che la funzione
nel programma principale viene richiamata una sola volta. Ancora più importante in problemi
di questo genere è la definizione di una condizione di arresto, in questo caso quando il numero
passato alla funzione è ‘<=1’ la funzione abbandona la ricorsione e restituisce valore pari ad 1. Se
si sbaglia o si tralascia la condizione di uscita il programma potrebbe entrare in un ciclo infinito
e non smetterebbe mai l’esecuzione.
Programmare in PHP --- Copyright © 2001-2002 Gianluca Giusti -- brdp @ urcanet.it
Capitolo
218
La gestione del file system
Il file system è ben gestito dal PHP, le funzioni a disposizione degli sviluppatori sono
innumerevoli, inoltre sono ben integrate con il sistema operativo in modo particolare GNU/Linux.
Ad esempio è possibile ottenere e cambiare i permessi, il proprietario e il gruppo di un file,
creare collegamenti simbolici, copiare, spostare, eliminare directory e file. Dunque gli strumenti
a disposizione non mancano e molti di essi verranno trattati nelle pagine seguenti.
Prima di entrare nello specifico è bene precisare ancora una volta che il file system su cui il PHP
opera è quello dell’elaboratore servente, quindi se si crea un file esso viene creato sul disco del
servente e non su quello del cliente.
Tramite il protocollo HTTP il PHP può gestire anche il trasferimento di file dall’elaboratore
cliente a quello servente, questo però verrà trattato nella sezione dedicata alla programmazione
avanzata.
218.1 Concetto di file
Un file può essere visto come un contenitore nel quale immagazzinare informazioni. La gestione
fisica del file su disco viene effettuata dal sistema operativo a cui si interfaccia il PHP.
Per poter accedere alle informazioni contenute in un file è necessario aprirlo, leggerne il
contenuto, eventualmente modificarlo e infine chiuderlo.
I dati vengono salvati nel file sotto forma di righe, per indicare il fine riga nei file di testo viene
utilizzato ‘\n’, mentre la fine del file è ottenuta tramite la funzione ‘feof()’ che restituisce un
valore booleano vero se ci si trova alla fine del file.
La particolarità fondamentale di questa struttura è il suo accesso, a differenza degli array non
è possibile puntare direttamente ad una riga ben precisa del file è dunque necessario scorrere il
suo contenuto fino ad arrivare alla riga desiderata. Questo tipo di accesso viene detto "accesso
sequenziale".
Non ci sono, inoltre, limiti massimi o minimi per le dimensioni del file, esse dipendono dalla
disponibilità di spazio su disco.
218.2 Apertura di un file
Se un file è un contenitore per poter accedere al suo contenuto è necessario aprirlo, per farlo si
utilizza la funzione ‘fopen()’ a cui va fornito il file con il percorso, se diverso da quello dello
script, e il tipo di apertura. Dunque al momento dell’apertura del file bisogna dichiarare il tipo
di operazione che si desidera eseguire su di esso, ad esempio se si vuole solo leggere, scrivere o
semplicemente aggiungere dati alla fine. Ecco l’elenco dei possibili modi di accedere ad un file
in PHP:
• ‘’r’’ Apre in sola lettura; posiziona il suo puntatore all’inizio del file;
• ‘’r+’’ Apre in lettura e scrittura; posiziona il suo puntatore all’inizio del file;
• ‘’w’’ Apre in sola scrittura; posiziona il suo puntatore all’inizio del file e ne elimina il
contenuto. Se il file non esiste lo crea;
• ‘’w+’’ Apre in lettura e scrittura; posiziona il suo puntatore all’inizio del file e ne elimina
il contenuto. Se il file non esiste lo crea;
2324
La gestione del file system
2325
• ‘’a’’ Apre in sola scrittura; posiziona il suo puntatore alla fine del file. Se il file non esiste
lo crea;
• ‘’a+’’ Apre in lettura e scrittura; posiziona il suo puntatore alla fine del file. Se il file non
esiste lo crea;
Il PHP permette anche di aprire file remoti tramite i protocolli più diffusi come HTTP e FTP,
ovviamente il file deve essere raggiungibile almeno in lettura.
Ecco qualche esempio di apertura di file:
0
1
2
3
$f
$f
$f
$f
=
=
=
=
fopen
fopen
fopen
fopen
("dati.txt", "w");
("/home/qualche_percorso/dati.txt", "a");
("http://www.php.net/", "r");
("ftp://nome_utente:password@indirizzo_del_sito_ftp.com/", "w");
Va notato che la funzione ritorna un intero. La variabile ‘$f’ contiene i riferimenti al file aperto, viene anche detto "puntatore al file" anche se non ha nulla a che vedere con la "struttura
puntatore". Tutte le operazione sarnno eseguite sul puntatore al file.
Nella riga 0 il file viene aperto in sola scrittura un file che si trova nella stessa directory dello
script, se non esistere viene creato. Nella riga 1 il file viene aperto in un ben preciso punto del del
disco del servente. Negli ultimi due esempi i file aperti risiedono in remoto e sono aperti tramite
i due protocolli HTTP ed FTP
Fare molta attenzione ai permessi dei file che si intende manipolare e delle directory in cui
sono contenuti. Ricordare che l’utente che accede al file è quello che lancia il servente HTTP
e di conseguenza l’interprete PHP in esso caricato come modulo. Tale utente viene specificato
nel file di configurazione del servente.
218.3 Lettura di un file di testo
Il primo passo sarà quello di leggere un semplice file di testo esistente e contenuto nella stessa
directory dello script. Verrà utilizzato il metodo di sola lettura con l’indispensabile controllo di
errore e ancora prima di esistenza del file da leggere. Se si salvano informazioni riservate in
file di testo è bene farlo in una directory che non faccia parte dei documenti WEB altrimenti
potrebbe essere richiamato e letto direttamente dal navigatore. Inoltre è importante nascondere
eventuali errori mediante una corretta gestione degli stessi al fine di evitare la visualizzazione
di informazioni importanti come il percorso e il nome del file che si tenta di aprire. Prima di
scrivere il codice è bene creare il file da leggere, nominarlo come ‘dati_1.txt’ e riempirlo con
del semplice testo.
Un esempio di dati_1.txt:
Salve a tutti,
scrivo nel file per poi leggere con php.
di seguito una riga vuota
e poi il file finisce!
Ecco il programma che legge il file appena creato:
0
1
2
3
4
5
<html><body>
<?
if (file_exists("dati_1.txt")){
echo "Il file dati_1.txt esiste. Ecco il suo contenuto:<br>";
La gestione del file system
2326
6
7
8
9
10
11
12
13
14
16
17
18
19
20
21
22
23
$f = @fopen("dati_1.txt", "r"); // apre il file in sola lettura
if($f){
while(!feof($f)){ // un semplice while fino alla fine del file
$riga = fgets($f,4096); // legge la riga
echo "<br>".$riga; // visualizza la riga
}
@fclose($f); // è importante chiudere il file
}else{
echo "Errore durante l’apertura del file!";
}
}else{
echo "Il file dati_1.txt NON esiste!";
}
?>
</body></html>
Nella riga 3 viene controllata l’esistenza del file di testo tramite la funzione ‘file_exists()’
che come riportato nel manuale ufficiale alla sezione "XXVI. Filesystem functions" ritorna un
valore booleano vero se il file esiste falso negli altri casi. Questa sezione del manuale è ricca di
funzioni per la gestione dei file si consiglia vivamente di approfondirne la lettura.
Alla riga 6 il file viene aperto in sola lettura è bene fare attenzione alla gestione dell’errore. Se
l’apertura va a buon fine tramite una struttura ciclica ne viene visualizzato il contenuto. La lettura
viene interrotta nel momento in cui la funzione ‘feof()’ resituisce valore vero, questo accade
quando si arriva alla fine del file.
Per la lettura delle singole righe del file è stata utilizzata la funzione ‘fgets()’ che restituisce
una stringa o un valore falso in caso di errore.
Molto importante è l’istruzione della riga 12 con la quale viene chiuso il puntatore al file definito
nella fase di apertura. È bene liberare un file prima possibile per evitare problemi di scrittura
concorrenziale. Anche questa funzione ritorna un valore booleano vero se l’operazione va a buon
fine, falso altrimenti.
Se il file di testo da leggere è piccolo si può utilizzare la funzione ‘file("nome_del_file ")’,
ovviamente oltre al nome del file può essere specificato un particolare percorso e il tutto può
essere contenuto in una variabile da passare come parametro. La funzione ‘file()’ resituisce
un array formato da tanti elementi quante sono le righe del file di testo, ogni elemento conterrà il
testo della riga relativa. Ad esempio nel caso del precedente file ‘dati_1.txt’:
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<html><body>
<?
$appo = @file("dati_1.txt");
if ($appo){
echo "Operazione riuscita il contenuto del file dati_1.txt
è nell’array <b>\$appo</b><br>";
$i=0;
foreach($appo as $valore) // visualizzo il contenuto dell’array
echo "<br>".$valore;
}else{
echo "Errore nella lettura del file! Accertarsi che
esista e che i permessi siano corretti";
}
?>
</body></html>
Questa funzione risulta molto comoda e rapida inquanto non necessita di istruzioni per l’apertura
La gestione del file system
2327
e la chiusura del file. È evidente che in questo modo il contenuto può essere soltanto letto e non
modificato. In caso di file di dimensioni medio grandi è preferibile utilizzare le funzioni classiche
viste in precedenza che benchè più macchinose garantiscono una migliore gestione del file e della
memoria.
218.4 Scrittura in un file di testo
Come al solito prima di poter operare sul contenuto del file bisogna aprirlo, ovviamente per poter
inserire dei dati nel contenitore bisogna aprirlo in modalità di scrittura. Come visto in precedenza
esistono varie modalità e per ogni situazione va scelta quella ottimale. Di seguito esamineremo
alcuni metodi di scrittura nel file.
Il tipo ‘r+’ permette di leggere e scrivere nel file che si sta aprendo e posiziona il puntatore
all’inizio del contenitore senza alterarne a priori il contenuto. È utile quando bisogna posizionare
una riga in una ben precisa posizione del file.
Nel caso di ‘w’ e ‘w+’ il file viene aperto in scrittura o scrittura e lettura e viene immediatamente
svuotato. Può essere comodo nel caso di file di appoggio che possono essere sovrascritti senza
doverne controllare il contenuto.
Il metodo di apertura ‘a’ e ‘a+’, che serve ad accodare righe al file, verrà trattato in dettaglio nel
paragrafo 218.5.
Nell’esempio seguente si salva nel file ‘dati_3.txt’ l’indirizzo IP dell’ultimo visitatore che
ha caricato la pagina ‘3.php’. Anche questo come tutti gli esempi di questo capitolo è raggiungibile al solito indirizzo: <http://www.urcanet.it/brdp/php_manual/esempi/> nel caso specifico: <http://
www.urcanet.it/brdp/php_manual/esempi/cap_5/3.php>
0 <html><body>
1
2
<?
3
$f = @fopen("dati_3.txt", "w");
// lo apre e lo svuota. se non esiste lo crea
4
if($f){
5
echo "<br><br>file <a href=\"dati_3.txt\">dati_3.txt</a> Aperto correttamente.";
6
echo "<br><br>Sto salvando i tuoi dati nel file";
7
8
$frase = "Ultimo visitatore ad aver eseguito lo script 3.php \n\n";
9
$frase = $frase."il suo IP:".$REMOTE_ADDR." \n";
10
11
@fputs($f,$frase);
// scrive la frase nel file tramite $f
12
@fclose($f);
// è importante chiudere il file
13
14
echo "...... Fatto!";
15
16
}else{
17
echo "<br>Errore durante l’apertura del file dati_3.txt";
18
}
19 ?>
20
21 </body></html>
Nella riga 3 il file viene aperto in sola scrittura e come più volte ripetuto il suo contenuto viene
cancellato. Dunque questo codice sarà in grado di mantenere traccia soltanto dell’ultimo visitatore. Sarebbe più interessante memorizzare più visite ma bisogna fare i conti con la crescita del
file, se la pagina è molto frequentata le dimensioni del file di log potrebbero crescere a dismisura
fino a saturare lo spazio su disco. Un buon esercizio potrebbe essere la realizzazione di uno script
che tenga traccia degli ultimi ‘$n’ visitatori, dove ‘$n’ è un parametro che può essere impostato
a seconda delle esigenze.
Di seguito una possibile soluzione:
La gestione del file system
2328
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
<html><body>
<?
$n = 4; // numero di visite da mantenere
$f = @fopen("dati_4.txt", "r");
if($f){
echo "<br>file dati_4.txt esistente ed aperto correttamente <br>";
$i=0;
while( !feof($f) && $i<$n-1 ){
// finchè fine del file o il $i< $n-1
$righe[$i] = @fgets($f,4096); // file piccolo! utilizzo array sacmbio
$i++;
}
@fclose($f);
// è importante chiudere il file
$f = @fopen("dati_4.txt", "w"); // adesso lo riempio con i nuovi dati.
if($f){
echo "<br><br>file <a href=\"dati_4.txt\">dati_4.txt</a> Aperto
correttamente. Sto salvando i tuoi dati";
$frase = "visitatore di 4.php - ";
$frase = $frase."il suo IP:".$REMOTE_ADDR." alle ore: ".date("d-m-Y G:i:s")." \n";
@fputs($f,$frase);
// scrive la frase nel file tramite $f
for ($i=0; $i<count($righe); $i++)
@fputs($f,$righe[$i]);
@fclose($f);
// è importante chiudere il file
echo ".......Fatto!";
}
}else{
echo "<br>Il file dati_4.txt non esiste. Lo creo.";
$f = @fopen("dati_4.txt", "w");
if($f){
echo "<br><br>file <a href=\"dati_4.txt\">dati_4.txt</a> Aperto
correttamente. Sto salvando i tuoi dati";
$frase = "visitatore di 4.php - ";
$frase = $frase."il suo IP:".$REMOTE_ADDR." alle ore: ".date("d-m-Y G:i:s")." \n";
@fputs($f,$frase);
@fclose($f);
// scrive la frase nel file tramite $f
// è importante chiudere il file
echo ".......Fatto!";
}else{
echo "<br><br>Non posso creare il file dati_4.txt";
}
}
?>
</body></html>
Ci sono vari modi per risolvere il problema, quello usato per questo esempio è volutamente prolisso al fine di utilizzare più volte le funzioni sotto esame così da rendere più semplice
l’apprendimento.
Concettualmente si è ragionato in questi termini:
se il file esiste
{
- leggo le prime $n-1 righe del file
- le salvo in un array di appoggio
La gestione del file system
-
2329
chiudo il file
apro il file in scrittura cancellandone il contenuto
salvo i dati relativi alla connessione attuale nel file
salvo tutte le righe dell’array di appoggio
chiudo il file
}
altrimenti
{
- apro il file in scrittura e viene creato
- salvo i dati relativi alla connessione attuale nel file
- chiudo il file
}
in realtà non viene fatto un controllo sull’esistenza del file ma si è considerato che se non si riesce
ad aprire in sola lettura con il metodo ‘r’ il file o non esiste o non è leggibile.
Nel ciclo di riga 9 vengono prese le prime ‘$n-1’ righe del file o tutto il file se ha meno di ‘$n’
righe, la condizione che per prima non viene soddisfatta fa abbandonare il ciclo.
Nelle righe 21 e 43 è stata usata la variabile predefinita ‘$REMOTE_ADDR’ che contiene l’indirizzo IP del visitatore e di seguito la funzione ‘date()’ già incontrata nalla sezione 214.1 che in
questo caso ritorna la data nella forma del tipo: ‘31-10-2002 15:13:13’. Maggiori informazioni in merito possono essere trovate nella sezione "XVI. Date and Time functions" del manuale
ufficiale.
In fine nella righa 24 al posto della solita struttura ‘foreach’ è stata utilizzata volutamente la
funzione ‘count()’ che restituisce il numero di elementi dell’array che gli viene passato come
parametro.
In conclusione va notato che l’ultima visita verrà registrata in testa al file mentre le più vecchie verranno scartate mano a mano che ne entreranno delle nuove. Il risultato ottenuto nel file
‘dati_4.txt’ è simile a:
visitatore
visitatore
visitatore
visitatore
di
di
di
di
4.php
4.php
4.php
4.php
-
il
il
il
il
suo
suo
suo
suo
IP:192.168.1.153
IP:192.168.1.153
IP:192.168.1.153
IP:192.168.1.153
alle
alle
alle
alle
ore:
ore:
ore:
ore:
31-10-2002
31-10-2002
31-10-2002
31-10-2002
15:13:24
15:13:17
15:13:12
15:10:21
Come conclusione viene proposto un esempio riepilogativo in merito al quale non verranno fornite spiegazioni, sarà compito del lettore capirne il comportamento. Per testarne il funzionamento
è tuttavia possibile collegarsi all’indirizzo: <http://www.urcanet.it/brdp/php_manual/esempi/cap_5/5.php>
0 <html><body>
1 <?
2 /*
3 Primo tentativo di apertura del file inesistente dati_5.txt in sola lettura
4 il tentativo di apertura fallisce perchè la modalità ’r’ non
5 crea il file in caso di inesistenza, a differenza delle modalità
6 ’w’ e ’a’ che se non esiste lo creano. Quindi il controllo seguente
7 restituirà il messaggio di errore...
8 */
9
10 $f = @fopen("dati_5.txt", "r");
11
12 if($f){
13
echo "<br>1) file dati_5.txt Aperto. Ecco il contenuto: <br>";
14
//Se apre il file facciamo scrivere il contenuto
15
while(!feof($f)){
// finchè non raggiungo la fine del file
16
$riga = @fgets($f,4096);
17
echo "<br>".$riga;
18
}
19
@fclose($f);
// è importante chiudere il file
20 }else{
21
echo "<br>1) Apertura del file dati_5.txt FALLITA! Ora lo creo e lo riempio.";
22 }
La gestione del file system
2330
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
/*
Secondo tentativo apro in sola scrittura il file
il tentativo di apertura riesce perchè la modalità ’w’
crea il file in caso di inesistenza. Il controllo seguente
restituirà messaggio positivo.
ATTENZIONE in questo caso il file viene svuotato al momento
dell’apertura, il contenuto viene perso.
*/
if (!file_exists("dati_5.txt")){
$f = @fopen("dati_5.txt", "w");
if($f){
echo "<br><br>2) file dati_5.txt Aperto correttamente. Lo riempio";
// sappiamo che va a buon fine e quindi scriviamoci qualcosa dentro.
// notare che \n inserisce un fine riga!!!
$frase = "Ciao Popolo. \n";
$frase = $frase."Scrivo nel mio primo file in PHP \n";
$frase = $frase."Speriamo bene! \n";
$frase = $frase."CIAO";
@fputs($f,$frase);
@fclose($f);
// scrive la frase nel file tramite $f
// è importante chiudere il file
}else{
echo "<br><br>2) Apertura del file dati_5.txt <strong>FALLITA!</strong>";
}
}else{
echo "<br><br>2) Il file dati_5.txt esiste già. Allora lo RIMUOVO!";
if(@unlink ("dati_5.txt")){
echo "<br><br> FILE dati_5.txt RIMOSSO CORRETTAMENTE";
}else{
echo "<br><br> ERRORE durante la rimozione di dati_5.txt";
}
}
?>
</body></html>
In questo ultimo esempio viene utilizzata per la prima volta la funzione ‘unlink()’ che serve
ad eliminare il file che riceve come parametro, essa restituisce un intero che assume valore pari a
0 o falso se l’operazione di cancellazione non va a buon fine.
218.5 Accodare testo in un file
Ovviamente esistono metodi più semplici, immediati e dunque migliori per tenere traccia di
qualunque evento. Prima di continuare è bene ricordare che il servente HTTP memorizza in
file di log le informazioni relative alle connessioni quindi se non si hanno particolari esigenze
tracciare le visite degli utenti potrebbe essere un’operazione ridondante.
Il PHP come visto nella sezione 218.2 permette di aprire un file in modalità "append", ovvero in
modo che le righe inserite vengano appese alla fine del file. questo metodo è utilizzabile passando
alla funzione ‘fopen()’ il parametro ‘a’ o ‘a+’, nel primo caso il file viene aperto in sola scrittura
mentre nel secondo in scrittura e lettura, il puntatore viene posizionato alla fine del file e se non
esiste il file specificato viene creato.
Se si pensa al problema affrontato precedentemente (sezione 218.4) ci si rende immediatamente
conto che utilizzando questo metodo di scrittura nel file si possono accodare le informazioni
utilizzando poche righe di codice. Ad esmpio:
La gestione del file system
2331
0 <html><body>
1
2
<?
3
$f = @fopen("dati_6.txt", "a");
//apre in scrittura. se non esiste lo crea
4
if($f){
5
echo "<br><br>file <a href=\"dati_6.txt\">dati_6.txt</a> Aperto.";
6
echo "<br><br>Sto salvando i tuoi dati nel file";
7
8
$frase = "visitatore di 6.php - ";
9
$frase = $frase."il suo IP:".$REMOTE_ADDR." alle ore: ".date("d-m-Y G:i:s")." \n";
10
11
@fputs($f,$frase);
// scrive la frase nel file tramite $f
12
@fclose($f);
// è importante chiudere il file
13
14
echo "...... Fatto!";
15
16
}else{
17
echo "<br>Errore durante l’apertura del file dati_6.txt";
18
}
19 ?>
20
21 </body></html>
È bene sottolineare che in questo caso non ci sono controlli sulle dimensioni del file di testo
generato. Ogni volta che lo script viene eseguito il file ‘dati_6.txt’ aumenta di dimensioni.
Se la pagina è molto visitata a lungo andare potrebbe addirittura saturare il disco. Visto che
questo è un semplice esercizio e non si ha alcun bisogno dei dati contenuti nel file verrà aggiunto
un controllo che elimina il file sele sue dimensioni superano un determinato valore. Ecco una
soluzione:
0 <html><body>
1
2
<?
3
$max_file_size = 4000; // dimensione massima in byte
4
5
if(filesize("dati_6.txt") > $max_file_size ){
6
echo "<br><br><b>Vuoto il file! ha superato il limite</b><br><br>";
7
$f = @fopen("dati_6.txt", "w");
//lo apre scrittura e lo svuota
8
}else{
9
$f = @fopen("dati_6.txt", "a");
//lo apre scrittura e appende i dati
10
}
11
if($f){
12
echo "<br><br>file <a href=\"dati_6.txt\">dati_6.txt</a> Aperto.";
13
echo "<br><br>Sto salvando i tuoi dati nel file";
14
15
$frase = "visitatore di 6.php - ";
16
$frase = $frase."il suo IP:".$REMOTE_ADDR." alle ore: ".date("d-m-Y G:i:s")." \n";
17
18
@fputs($f,$frase);
// scrive la frase nel file tramite $f
19
@fclose($f);
// è importante chiudere il file
20
21
echo "...... Fatto!";
22
23
}else{
24
echo "<br>Errore durante l’apertura del file dati_6.txt";
25
}
26 ?>
27
28 </body></html>
Le modifiche sono semplici, è stato aggiunto un ‘if’ che controlla la dimensione del file
‘dati_6.txt’ se è maggiore del valore impostato nella variabile ‘$max_file_size’ apre il file
in modalità ‘w’ e quindi ne cancella il contenuto, altrimenti lo apre in modalità ‘a’. In entrambi i
casi se il file non esiste viene creato.
2332
La gestione del file system
218.6 Conclusioni
Il file system, come appena visto, permette di immagazzinare informazioni su disco dando la
possibilità di aggiornarle modificandole o cancellandole. Tuttavia è bene tenere presente che
esistono tecnologie relazionali apposite per la gestione di grandi moli di dati che garantiscono
maggiori prestazioni e una migliore gestione dello spazio su disco. Tali tecnologie sono le basi
di dati alle quali si accede tramite un linguaggio di interrogazione standard noto come SQL1 .
Il file rimane comunque uno strumento utile, semplice e immediato, e nel caso di piccole quantità
di dati o nel caso in cui non si abbia accesso ad un DBMS2 , può essere preso in considerazione
come alternativa alle basi di dati.
Programmare in PHP --- Copyright © 2001-2002 Gianluca Giusti -- brdp @ urcanet.it
1
Acronimo di "Structured Query Language" ovvero "linguaggio di interrogazione strutturato".
Acronimo di "Data Base Management System " ovvero "Sistema di Gestione di Basi di Dati", è il software che si
occupa di rispondere alle istruzioni SQL.
2
Indice analitico del volume
./.efax.rc, 1443
./.htaccess, 1726
/etc/aliases, 1603, 1650, 1659, 1660
/etc/apache/access.conf, 1720
/etc/apache/httpd.conf, 1711, 1938
/etc/apache/srm.conf, 1715
/etc/apache-ssl/apache.pem, 2175
/etc/apache-ssl/, 2175
/etc/bind/named.ca, 1326
/etc/bind/named.conf, 1324, 1335, 1419
/etc/bind/named.root, 1326
/etc/boa/boa.conf, 1733
/etc/conf.uugetty, 1429
/etc/default/nis, 1505
/etc/default/uugetty, 1429
/etc/dhcp.conf, 1512
/etc/dhcp.leases, 1512
/etc/dhcpc/hostinfo-*, 1515
/etc/dhcpc/resolv.conf, 1515
/etc/efax.rc, 1443
/etc/ethers, 1266
/etc/exports, 1484
/etc/ftpaccess, 1583
/etc/ftpchroot, 1577
/etc/ftpconversions, 1580
/etc/ftphosts, 1590
/etc/ftpusers, 1564, 1577, 1580
/etc/ftpwelcome, 1577
/etc/host.conf, 1309
/etc/hosts, 1310
/etc/hosts.allow, 1472, 1482, 1496, 2046
/etc/hosts.deny, 1472, 1482, 1496, 2046
/etc/hosts.equiv, 1518, 2192
/etc/htdig/htdig.conf, 1853
/etc/httpd/conf/access.conf, 1720
/etc/httpd/conf/httpd.conf, 1711, 1938
/etc/httpd/conf/srm.conf, 1715
/etc/inetd.conf, 1468, 1471
/etc/init.d/nis, 1505
/etc/init.d/setserial, 1359
/etc/ircd/ircd.conf, 1546, 1547
/etc/ircd/ircd.motd, 1547
/etc/issue.net, 1532
/etc/login.access, 2039
/etc/lynx.cfg, 1698
/etc/mail.rc, 1610
/etc/mail/deny, 1658
/etc/mail/deny.db, 1658
/etc/mail/ip_allow, 1657
/etc/mail/LocalIP, 1657
2333
/etc/mail/LocalNames, 1657
/etc/mail/name_allow, 1657
/etc/mail/RelayTo, 1657
/etc/mail/relay_allow, 1657
/etc/mailman/mm_cfg.py, 1686
/etc/mgetty+sendfax/login.config, 1441
/etc/mgetty+sendfax/mgetty.config, 1440
/etc/minicom.users, 1371
/etc/minirc.dfl, 1371
/etc/mirror.defaults, 1869
/etc/motd, 1577
/etc/nail.rc, 1611
/etc/named.conf, 1324, 1335, 1419
/etc/networks, 1311
/etc/news/distrib.paths, 1817
/etc/news/expire.ctl, 1819
/etc/news/inn.conf, 1816
/etc/news/newsfeeds, 1818, 1827, 1829, 1830
/etc/news/nnrp.access, 1820
/etc/nologin, 1577
/etc/nsswitch.conf, 1505, 1506
/etc/ntp.conf, 1539
/etc/pine.conf, 1615
/etc/pine.conf.fixed, 1615
/etc/porttime, 2040
/etc/ppp/chap-secrets, 1379, 1388, 1424
/etc/ppp/ipv6-down, 1381
/etc/ppp/ipv6-up, 1381
/etc/ppp/ip-down.d/, 1396
/etc/ppp/ip-down, 1306, 1381, 1391
/etc/ppp/ip-up.d/, 1396
/etc/ppp/ip-up, 1306, 1381, 1391
/etc/ppp/options, 1379
/etc/ppp/options.ttyS*, 1379
/etc/ppp/pap-secrets, 1379, 1388, 1424
/etc/ppp/peers/wvdial, 1424
/etc/ppp/resolv.conf, 1391
/etc/protocols, 1245, 1298
/etc/queso.conf, 2069
/etc/radvd.conf, 1302
/etc/resolv.conf, 1312, 1419
/etc/rinetd.conf, 1992
/etc/rpc, 1480
/etc/rsyncd.conf, 1901
/etc/rsyncd.secrets, 1904
/etc/sendmail.cf, 1603
/etc/services, 1245
/etc/squid.conf, 1944
/etc/ssh//etc/ssh/ssh_host_dsa_key.pub, 2188
/etc/ssh//etc/ssh/ssh_host_dsa_key, 2188
/etc/ssh//etc/ssh/ssh_host_key.pub, 2188
/etc/ssh//etc/ssh/ssh_host_key, 2188
2334
/etc/ssh//etc/ssh/ssh_host_rsa_key.pub, 2188
/etc/ssh//etc/ssh/ssh_host_rsa_key, 2188
/etc/ssh/shosts.equiv, 2192
/etc/ssh/sshd_config, 2195
/etc/ssh/ssh_config, 2199
/etc/ssh/ssh_known_hosts, 2190
/etc/ssl/certs/apache.pem, 2175
/etc/ssl/certs/telnetd.pem, 2177
/etc/ssmtp/revaliases, 1674
/etc/ssmtp/ssmtp.conf, 1674
/etc/telnetrc, 1532
/etc/usertty, 2037
/etc/webalizer.conf, 1860
/etc/wgetrc, 1875
/etc/wvdial.conf, 1423, 1425
/etc/xinetd.conf, 1475
/etc/yp.conf, 1505, 1506
/etc/ypserv.conf, 1496, 1499
/etc/ypserv.securenets, 1496, 1500
/proc/net/if_inet6, 1298
/tftpboot/, 1536
/usr/lib/yp/makedbm, 1496
/usr/lib/yp/ypinit, 1501
/var/cache/bind/, 1324
/var/lib/news/active, 1821
/var/lib/news/history, 1822
/var/lib/nfs/rmtab, 1484
/var/log/xferlog, 1593
/var/mail/, 1661
/var/spool/mqueue/, 1604
/var/spool/rwho/, 1523
/var/yp/Makefile, 1501
10/100/1000base*, 1236
10/100base*, 1236
10base2, 1239
10base5, 1238
10baseT, 1239
10base*, 1236
6to4, 1295
ABC-nslookup, 2211
accesso remoto, 1518, 2027
accesso sequenziale, 2324
accounting: IP, 1982, 2003
Address Resolution Protocol, 1224
AIDE, 2064
aide.conf, 2064
alias IP, 1255
anycast, 1287, 1294
Apache, 1709, 1938
Apache-SSL, 2175
append, 2330
ARP, 1224, 1265
2335
arp, 1265
array, 2285, 2289
array(), 2289
autorità di certificazione, 2150
Balsa, 1616, 1618
baud, 1375
Boa, 1733
Bobcat, 2212
boolean, 2285, 2287
bot, 1546
bps, 1375
break, 2302, 2308
bridge, 1220
broadcast, 1225
cartella di messaggi, 1620
case, 2302
casella postale, 1620
cavallo di Troia, 2034
certificato, 2150
cfd.conf, 2126
Cfengine, 2104, 2114, 2125
CGI, 1738, 1762
CGI: accesso a una base di dati, 1782, 1789
CHAP, 1379
Chat, 1409
chiave privata, 2131
chiave pubblica, 2131
chroot, 2053, 2054
chrootuid, 2054
ciclo, 2303, 2305, 2305, 2306
cifratura, 2131
class, 2293
cloner, 1546
commutatore di pacchetto, 1240
contabilità del traffico IP, 1982, 2003
count(), 2327
crittografia, 2131
crittografia a chiave pubblica, 2131
crittografia a chiave segreta, 2131
crittografia asimmetrica, 2131
crittografia simmetrica, 2131
Crynwr, 2208
ctlinnd, 1823
CVS, 1906, 1921
datagramma, 1218
date(), 2278, 2289, 2327
DBMS, 2332
DCE, 1362
DHCP, 1510
dhcpcd, 1515
dhcpd, 1512
dhcrelay, 1515
2336
die(), 2295
Dig, 1330
DNS, 1233, 1313, 1316, 1333, 1417, 2024
DNS: alias, 1322, 1343
DNS: record A, 1341
DNS: record A6, 1341
DNS: record AAAA, 1341
DNS: record CNAME, 1343
DNS: record MX, 1341
DNS: record NS, 1340
DNS: record SOA, 1339
dnsserver, 1949
do..while, 2305
domainname, 1496
dominio, nome di, 1232
DOS, 2208
DOS: packet-driver, 2208
DOS: PPP, 2225
DosLynx, 2215
double, 2287
DTE, 1362
echo, 2278
Efax, 1443
else, 2299, 2299
elseif, 2300, 2302
email, 1599, 1622, 1640
escape, 2288
esempio: ppp-chiudi, 1414
esempio: ppp-connetti, 1412
Ethereal, 2091
Ethernet, 1235, 1250, 1257
exicyclog, 1673
Exim, 1659
exportfs, 1484
fax, 1443
fclose(), 2325, 2327, 2330
feof(), 2324, 2325, 2327
Fetchmail, 1625
fgets(), 2325, 2327
file, 2324
file(), 2295, 2325
filesize(), 2330
file_exists(), 2325
filtro di pacchetto IP, 1961, 1994
finger, 1524
Finger, 1524, 2022
fingerd, 1524
firewall, 1951, 1961, 1994
firma digitale, 2131
firma elettronica, 2131
float, 2287
flooder, 1546
2337
foalt, 2285
fopen(), 2324, 2325, 2327, 2330
for, 2305
foreach, 2306
form, 2311
fputs(), 2327, 2330
FQDN, 1232
frame, 1218
freeWAIS, 1841
freeWAIS-sf, 1841
FTP, 1564, 1576, 1579, 1834
ftp, 1565
FTP: anonimo, 1564, 1581, 2026
FTP: riproduzione speculare, 1866
ftpcount, 1594
ftpd, 1576, 1579
ftpwho, 1594
Fully Qualified Domain Name, 1232
function(), 2317, 2322
funzioni, 2315, 2315
gateway, 1220
get, 2311
get, 2311
gettype(), 2282, 2285
Getty_ps, 1428, 1452
Glimpse, 1803
global, 2317
GnomeICU, 1556, 1556
GnuPG, 2138
gpg, 2138
gpgm, 2138
Grepmail, 1620
handshaking, 1361
hash, 2285, 2289
Hayes, 1363
Host, 1329
hosts.nntp, 1826
ht://Dig, 1852
htdigconfig, 1853
htpasswd, 1728
htsearch, 1854
HTTP, 1697, 1709, 1733, 1738
HTTP: autenticazione, 1728
httpd, 1709
ICMP, 1247
icmplog, 2096
ICQ, 1555
IDENT, 2042
identd, 2042
identtestd, 2044
IEEE 802.3, 1235
if, 2287, 2298
2338
Ifconfig, 1249, 1253
imapd, 1623
impronta digitale, 2133
in.fingerd, 1524
in.ftpd, 1576, 1579
in.identd, 2042
in.identtestd, 2044
in.rlogind, 1519
in.rshd, 1520
in.talkd, 1528
in.telnetd, 1532
in.tftpd, 1536
include(), 2297, 2309, 2315
inclusione di file, 2309
incoming.conf, 1826
indicizzazione dei file, 1841
inetd, 1468
Info2www, 1804
INN, 1814
innd, 1822
innfeed.conf, 1827
integer, 2285, 2286
Internet domain socket, 1348, 1351
InterNet News, 1814
Internet Relay Chat, 1544
Internet service daemon, 1468
intero, 2286
interruzione, 2308
ip, 1279, 1279
IP aliasing, 1255
ipchains, 1995, 2005, 2007
IPlogger, 2096
ipop2d, 1623
ipop3d, 1623
Iproute, 1279
IPTables, 1962
IPTraf, 2085
IPv4, 1225, 1929
IPv4: classi, 1227
IPv4: rete privata, 1229
IPv4-compatible IPv6 addresses, 1294
IPv4-mapped IPv6 addresses, 1295
IPv6, 1245, 1286, 1298, 1310
IPv6: FTP, 1574, 1576
IRC, 1544
ircd, 1549
ISO 8802.3, 1235
ISO-OSI, 1218
ISP, 1452
is_array(), 2299
is_double(), 2299
is_integer(), 2299
2339
is_string(), 2299
I-seek-you, 1555
LAN, 1216
Lftp, 1574
Libident, 2044
linea dedicata, 1397, 1402
Links, 1705
Linuxconf, 2029
lista di posta elettronica, 1676
lockvc, 2100
login, 2037
login remoto, 1518, 2027
logoutd, 2040
loop, 2303, 2305, 2305, 2306
loopback, 1228, 1250, 1257
lsh, 2185
LSH, 2182
lshc, 2185
lshd, 2184
lsh-keygen, 2183
lsh-writekey, 2183
Lynx, 1698, 2212
mail, 1607
mailing-list, 1676
Mailman, 1685
mailq, 1604, 1659, 1670
Mailx, 1607
makedbm, 1496
MAN, 1216
man2HTML, 1803
maschera di rete, 1225
mascheramento, 1951
mascheramento IP, 2005
MAU, 1238
mesg, 1527
mgetty, 1438
Mgetty+Sendfax, 1438, 1460
MIME, 1629
Minicom, 1371
MiniTelnet, 2211
Mirror, 1867
mirror, 1866
mmsitepass, 1686
mm_cfg.py, 1686
modem, 1359, 1397, 1402
modem: baud, 1375
modem: bit/s, 1375
modem: bps, 1375
modem: configurazione, 1373
motore di ricerca, 1841
Mpack, 1638
MUA, 1606
2340
multicast, 1287, 1510
Nail, 1611
name server, 1316, 1333
named, 1324
NAT, 1275, 1951, 1986
nc6, 2096
NCSA, 2217
NCSA Telnet, 2217
NE2000, 1236, 2208
Netcat6, 2096
netiquette, 1866, 1887
netmask, 1225
Netstat, 2078
Netstd ftp, 1565
Network Address Translation, 1275, 1951
Network Time Protocol, 1538
newaliases, 1603, 1650
newlist, 1687
news, 1808
news.daily, 1825
NFS, 1484, 2023
NIS, 1491, 2028
nisdomainname, 1496
nnrpd, 1822
nntpget, 1830
nntpsend, 1829
nntpsend.ctl, 1828
nome di dominio, 1232, 1313
NOS, 2228
Nslookup, 1328, 2211
NTP, 1538
ntpd, 1539
ntpdate, 1538
Null-modem, 1362
numero a virgola mobile, 2287
object, 2293
OpenSSH, 2188
OpenSSL, 2162
operatori, 2293
operatori aritmetici, 2293
operatori di assegnazione, 2294
operatori di confronto, 2297
operatori di controllo degli errori, 2295
operatori di incremento e decremento, 2296
operatori logici, 2297
OSI, 1218
pacchetto, 1217
PAP, 1379
PAT, 1275, 1951, 1986
PCroute, 2222
PDU, 1220
percorso di fiducia, 2147
2341
Perl, 1762
Perl: CGI, 1762
Perl: Pg, 1787
phpinfo(), 2278, 2284
Pine, 1611
ping, 1264
pinger, 1949
PLIP, 1243, 1251, 1259, 2208
point-to-point, 1216, 1251, 1259, 1378
Popclient, 1624
POPMail, 2219
Port Address Translation, 1275, 1951
porta, 1245
porta seriale, 1359, 1397
portmap, 1480
post, 2313
post, 2311
posta elettronica, 1599, 1622
PostgreSQL, 1782, 1789
post_max_size, 2313
PPP, 1378, 1400, 1406, 1418, 1423, 1454
pppd, 1378
ppp-chiudi, 1414
ppp-connetti, 1412
PPRD, 2213
print_r(), 2289
proxy, 1419, 1934
proxy trasparente, 1988, 2006
psql, 1783, 1784
punto-punto, 1216, 1251, 1259, 1378
Queso, 2069
Raccess, 2070
Radvd, 1302
rdist, 1893
Rdist, 1888
rete, 1216
rete: configurazione, 1249
rete: geografica, 1216
rete: hardware, 1235
rete: indirizzo IP e nome, 1309
rete: instradamento, 1256, 1267
rete: locale, 1216
rete: metropolitana, 1216
rete: privata, 1229
rete: protocolli, 1245
rete: protocolli di trasporto e di rete, 1245
rete: servizi, 1245
return, 2317, 2322
ricorsione, 2322
rinetd, 1992
ripetitore, 1220, 1237, 1239
riproduzione speculare, 1866
2342
rlogin, 1519
rlogind, 1519
rmlist, 1687
rndc, 1324
Route, 1256, 1260
router, 1220, 1267, 1269
RPC, 2024
rpc.lockd, 1484
rpc.mountd, 1484
rpc.nfsd, 1484
rpc.rquotad, 1484
rpc.rusers, 1524
rpc.rwalld, 1530
rpc.statd, 1484
rpc.yppasswdd, 1496, 1503
rpc.ypxfrd, 1496, 1504
rpcinfo, 1481
rsh, 1520
Rsync, 1895
RS-232C, 1362
rundig, 1853
runq, 1670
rusers, 1524
rwall, 1530
rwalld, 1530
rwho, 1523
rwhod, 1523
safe_finger, 2052
SANTA, 2071
satan, 2075
SATAN, 2071
satan/config/paths.pl, 2073
satan/config/paths.sh, 2073
satan/config/satan.cf, 2073
scp, 2199
SECSH, 2158
Secure Shell, 2158, 2188
Sendmail, 1602, 1650, 1670, 2028
servente di chiavi, 2136
servente: CGI, 1738
servente: Finger, 1524, 2022
servente: FTP, 1576, 1579
servente: HTTP, 1709, 1733
servente: LSH, 2182
servente: Secure Shell, 2188
servizio di risoluzione dei nomi, 1316, 1333
setserial, 1359
settype(), 2282, 2285
Seyon, 1372
showmount, 1488
sicurezza, 2021, 2037, 2099, 2104
sito speculare, 1866
2343
sito virtuale, 1731
SLIP, 1404
SmartList, 1678
SMTP, 1599
Sniffit, 2088
socket, 1348, 1351
socket di dominio Internet, 1348, 1351
socket di dominio Unix, 1348, 1351
sottorete, 1225
SQL, 2332
Squid, 1419, 1942
ssh, 2199
SSH, 2158, 2188
sshd, 2195
SSHDOS, 2212
ssh-keygen, 2188
SSL, 2157, 2162
SSL: Apache, 2175
SSL: SSLwrap, 2178
SSL: Stunnel, 2180
SSL: TELNET, 2177
SSLwrap, 2178
sSMTP, 1674
stateless, 1289
string, 2285, 2288
stringa, 2288
Strutture di controllo, 2297
Stunnel, 2180
subnet router anycast address, 1294
substr(), 2315
supervisore di rete, 1468
switch, 1240
switch, 2302
Talk, 2215
talk, 1528
talkd, 1528
TCP, 1929
TCP/IP, 1222
TCP/IP: accesso remoto, 1518
TCP/IP: DOS, 2208
TCP/IP: informazioni sugli utenti, 1523
TCP/IP: messaggi sul terminale, 1527
TCP/IP: NFS, 1484
TCP/IP: NOS, 2228
TCP/IP: RPC, 1480
TCP/IP: servizi, 1468
TCP/IP: TELNET, 1532
tcpd, 1471
tcpdchk, 2050
tcpdmatch, 2051
tcpdump, 2080
Tcpdump, 2080
2344
tcplog, 2096
TCP wrapper, 1471, 2046
TELNET, 1532, 2217
telnet, 1532
telnetd, 1532
Telnet-SSL, 2177
Telnet NCSA, 2217
TFTP, 1536, 2027
tftp, 1536
tftpd, 1536
TLS, 2157, 2162
Traceroute, 1273
traffico di rete, 2078
trama, 1218
transparent proxy, 1988, 2006
Tripwire, 2057
Trivial FTP, 1536, 2027
trojan, 2034
Trout, 2214
try-from, 2052
tw.config, 2057
UCSPI, 1351
UDP, 1929
UIN, 1555
unicast, 1287
Universal Internet number, 1555
Unix client-server program interface, 1351
Unix domain socket, 1348, 1351
unlink(), 2327
unlinkd, 1949
URI, 1738
URL, 1738
Usenet, 1808
Uuencode, 1630
uugetty, 1428, 1430, 1452
variabili globali, 2317
Variabili http, 2284
variabili locali, 2317
verme, 2034
VH-man2HTML, 1803
virtual host, 1731
virus, 2034
vlock, 2100
W3M, 1707
WAIS, 1841
waisindex, 1844
waissearch, 1844
waisserver, 1841
waisserver.d, 1841
wall, 1527
WAN, 1216
WATTCP, 2209
2345
Webalizer, 1860
Wget, 1874
while, 2303
worm, 2034
write, 1527
WU-FTP, 1834
WvDial, 1423
wvdialconf, 1423
X, 2028
xferstats, 1593
Xinetd, 1474
xlock, 2101
xntpd, 1539
xtrlock, 2101
YP, 1491
ypbind, 1505, 1506
ypcat, 1507
ypchfn, 1507
ypchsh, 1507
ypdomainname, 1496
ypinit, 1501, 1503
ypmatch, 1507
yppasswd, 1507
ypserv, 1496, 1497
ypwhich, 1503, 1507
ypxfr_1perday, 1504
ypxfr_1perhour, 1504
ypxfr_2perhour, 1504
ytalk, 1528
~/.cvsignore, 1897
~/.efax.rc, 1443
~/.fetchmailrc, 1625
~/.forward, 1526, 1605, 1650, 1659, 1661
~/.gnome/balsa, 1616
~/.gnupg/options, 2138
~/.lsh/identity.pub, 2185
~/.lsh/identity, 2185
~/.lsh/known_hosts, 2185
~/.mailrc, 1610, 1611
~/.netrc, 1565, 1570
~/.plan, 1526
~/.poprc, 1624
~/.ppprc, 1379
~/.project, 1526
~/.rhosts, 1518, 2192
~/.shosts, 2192
~/.ssh/authorized_keys, 2193
~/.ssh/config, 2199
~/.ssh/identity.pub, 2188
~/.ssh/identity, 2188
~/.ssh/id_dsa.pub, 2188
~/.ssh/id_dsa, 2188
2346
~/.ssh/id_rsa.pub, 2188
~/.ssh/id_rsa, 2188
~/.ssh/known_hosts, 2190
~/.ssh/random_seed, 2188
~/.telnetrc, 1532
~/.wgetrc, 1875
~ftp/, 1577
~/.pinerc, 1615
$CFINPUTS, 2105
$CVSIGNORE, 1897
$CVSROOT, 1906, 1909
$CVS_RSH, 1924
$ftp_proxy, 1936
$gopher_proxy, 1936
$HTTP_GET_VARS, 2314
$HTTP_POST_VARS, 2314
$http_proxy, 1936
$HTTP_REFERER, 2284
$HTTP_USER_AGENT, 2284
$MAIL, 1605, 1606, 1661
$NNTPSERVER, 1816
$ORGANIZATION, 1816
$REMOTE_ADDR, 2284, 2327
$RESOLV_HOST_CONF, 1310
$RESOLV_SERV_MULTI, 1310
$RESOLV_SERV_ORDER, 1310
$RSYNC_PASSWORD, 1900
$RSYNC_RSH, 1897
$SCRIPT_NAME, 2284
$SERVER_NAME, 2284
$wais_proxy, 1936
2347
2348
Appunti di informatica libera 2003.01.01
Volume IV
Scrivere
2349
Appunti Linux
Copyright © 1997-2000 Daniele Giacomini
Appunti di informatica libera
Copyright © 2000-2003 Daniele Giacomini
Via Morganella Est, 21 -- I-31050 Ponzano Veneto (TV) -- daniele @ swlibero.org
Le informazioni contenute in questa opera possono essere diffuse e riutilizzate in base alle condizioni poste dalla licenza GNU General Public License, come pubblicato dalla Free Software
Foundation.
In caso di modifica dell’opera e/o di riutilizzo parziale della stessa, secondo i termini della licenza, le annotazioni riferite a queste modifiche e i riferimenti all’origine di questa opera, devono
risultare evidenti e apportate secondo modalità appropriate alle caratteristiche dell’opera stessa. In nessun caso è consentita la modifica di quanto, in modo evidente, esprime il pensiero,
l’opinione o i sentimenti del suo autore.
L’opera è priva di garanzie di qualunque tipo, come spiegato nella stessa licenza GNU General
Public License.
Queste condizioni e questo copyright si applicano all’opera nel suo complesso, salvo ove indicato
espressamente in modo diverso.
The informations contained inside this work can be spread and reused under the terms of the
GNU General Public License as published by the Free Software Foundation.
If you modify this work and/or reuse it partially, under the terms of the license, the notices about
these changes and the references about the original work, must be evidenced conforming to the
work characteristics. IN NO EVENT IS ALLOWED TO MODIFY WHAT ARE CLEARLY
THE THOUGHTS, THE OPINIONS AND/OR THE FEELINGS OF THE AUTHOR.
This work is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the GNU General Public License for more details.
These conditions and this copyright apply to the whole work, except where clearly stated in a
different way.
Una copia della licenza GNU General Public License, versione 2, si trova nell’appendice A.
A copy of GNU General Public License, version 2, is available in appendix A.
2350
The main distribution for Appunti di informatica libera is described below. For every distribution
channel the maintainer’s name and address is also reported.
Internet
• direct reading: <http://a2.swlibero.org/>
download: <ftp://a2.swlibero.org/a2/> and <http://a2.swlibero.org/ftp/>
Michele Dalla Silvestra, mds @ swlibero.org
• direct reading: <http://appuntilinux.torino.linux.it/>
download: <ftp://ftp.torino.linux.it/appunti-linux/>
Carlo Perassi, carlo @ linux.it
• direct reading: <http://sansone.crema.unimi.it/linux/a2/HTML/>
download: <http://sansone.crema.unimi.it/linux/a2/>
Fabrizio Zeno Cornelli, zeno @ filibusta.crema.unimi.it
• direct reading: <http://www.pctime.it/servizi/appunti-linux/>
download: <http://www.pctime.it/servizi/appunti-linux/a2-prelievo/>
Franco Lazzero, PCTIME, pctime @ pctime.net
• direct reading: <http://www.a2.prosa.it/>
download: <ftp://ftp.a2.prosa.it/>
Davide Barbieri, paci @ prosa.it
• direct reading: <http://linux.pueste.it/>
download: <http://linux.pueste.it/filearea/AppuntiLinux/>
David Pisa, david @ iglu.cc.uniud.it
• direct reading: <http://www.informasiti.com/Appunti/HTML/>
download: <http://www.informasiti.com/Appunti/>
Claudio Neri, Sincro Consulting, neri.c @ sincroconsulting.com
GNU distributions
• GNU/Linux Debian <http://packages.debian.org/appunti-informatica-libera>
Massimo Dal Zotto, dz @ cs.unitn.it
Italian magazine’s CD-ROM
• inter-punto-net <http://www.interpuntonet.it>
Michele Dalla Silvestra, mds @ swlibero.org
• Internet News <http://inews.tecnet.it>
Francesco Facconi, francescofacconi @ libero.it
Fabio Ferrazzo, fabio.fr @ tiscalinet.it
• Linux Magazine <http://www.edmaster.it/prodotti/linux/ult-riv.html>
Emmanuele Somma, esomma @ ieee.org
La diffusione di questa opera è incoraggiata in base ai termini della licenza.
The spread of this work is encouraged under the terms of the license.
2351
Parte xli Editoria e stile . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2355
219 Formati standard della carta . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2356
220 Nozioni elementari di tipografia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2359
221 Stile letterario . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2365
222 Evoluzione dell’editoria elettronica . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2389
Parte xlii Codifica . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2393
223 Introduzione alla codifica universale dei caratteri . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2394
224 Esempi di codifica dei caratteri . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2405
Parte xliii PostScript: un linguaggio per la composizione finale . . . . . . . . . . . . . . . . . 2411
225 Linguaggio PostScript: introduzione . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2412
226 PostScript: espressioni e funzioni . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2428
227 PostScript: caratteri da stampa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2435
228 Esempi di funzioni PostScript . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2443
Parte xliv TeX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2449
229 teTeX: la distribuzione Unix di TeX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2453
230 TeX: introduzione . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2464
231 TeX: caratteri . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2483
232 TeX: la pagina . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2492
233 TeX: paragrafi, righe, spazi, scatole e linee . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2498
234 TeX: tabelle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2522
235 TeX: ambienti matematici . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2532
236 LaTeX: introduzione . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2550
237 LaTeX: struttura . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2568
238 LaTeX: la pagina . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2575
239 LaTeX: caratteri . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2583
240 LaTeX: blocchi di testo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2590
241 LaTeX: spazi e scatole . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2603
242 LaTeX: riferimenti . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2613
243 LaTeX: tabelle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2624
244 LaTeX: figure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2635
245 LaTeX: ambienti matematici . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2641
246 LaTeX: file esterni . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2658
Parte xlv Texinfo: lo standard della documentazione GNU . . . . . . . . . . . . . . . . . . . . . . 2661
2352
247 Introduzione a Texinfo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2662
248 Texinfo: libro e ipertesto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2678
Parte xlvi SGML: un linguaggio per l’editoria e non solo . . . . . . . . . . . . . . . . . . . . . . . 2687
249 SGML: introduzione . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2689
250 Elaborazione SGML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2717
251 Dichiarazione SGML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2740
252 SGMLtools 1.0/LinuxDoc . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2749
253 DebianDoc . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2762
254 DocBook: introduzione ai suoi strumenti . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2768
Parte xlvii Sgmltexi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2773
255 Sgmltexi: installazione e utilizzo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2774
256 Sgmltexi: struttura . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2780
257 Sgmltexi: contenuti . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2796
258 Corrispondenza tra Texinfo e Sgmltexi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2810
Parte xlviii HTML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2833
259 URI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2835
260 HTML: aspetti generali . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2843
261 HTML: corpo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2855
262 CSS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2865
263 HTML2ps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2873
264 Introduzione a Amaya . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2884
265 HTMLDOC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2889
266 Essere presenti su Internet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2899
Parte xlix XML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2903
267 XML: cenni . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2904
268 XHTML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2910
Parte l Controllo dell’ortografia e dello stile . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2913
269 Analisi lessicale . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2914
270 Analisi sintattica e stilistica con Textchk . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2921
Parte li Alml . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2929
271 Alml: preparazione e visione generale . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2930
272 Il documento secondo Alml . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2946
273 Entità ISO gestite da Alml . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2981
2353
274 Stile di scrittura del sorgente . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2986
Parte lii Annotazioni particolari riferite all’opera «Appunti di informatica libera» 2991
275 Gestione di «Appunti di informatica libera» . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2992
276 Convenzioni di «Appunti di informatica libera» . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2996
277 Glossario stilistico di «Appunti di informatica libera» . . . . . . . . . . . . . . . . . . . . . . . . . . . 3008
Parte liii Sistemi vari di composizione elettronica . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3049
278 Introduzione a *roff . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3051
279 Introduzione a Lout . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3077
280 Introduzione a HieroTeX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3109
281 Trasformazione in altri formati . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3128
Indice analitico del volume . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3131
2354
Parte xli
Editoria e stile
219 Formati standard della carta . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2356
219.1 Caratteristiche fondamentali dello standard ISO 216 . . . . . . . . . . . . . . . . . . . . . . 2356
219.2 Utilizzo pratico dei vari formati ISO 216 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2357
219.3 Formati multipli . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2358
219.4 Riferimenti . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2358
220 Nozioni elementari di tipografia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2359
220.1 Caratteri . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2359
220.2 Tipometria . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2360
220.3 Il carattere nel software di composizione . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2362
220.4 Problemi legati ai caratteri . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2364
220.5 Riferimenti . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2364
221 Stile letterario . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2365
221.1 Uniformità . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2365
221.2 Regole di composizione del testo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2365
221.3 Traduzioni e termini stranieri . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2374
221.4 Strafalcioni comuni . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2376
221.5 Unità di misura . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2378
221.6 Rappresentazione di valori . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2380
221.7 Stile tipografico . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2381
221.8 Riferimenti . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2387
222 Evoluzione dell’editoria elettronica . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2389
222.1 Evoluzione . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2389
222.2 Codifica del testo (markup) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2390
222.3 SGML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2391
2355
Capitolo
219
Formati standard della carta
Lo standard ISO 2161 definisce i formati di carta più comuni, secondo una logica molto semplice. Vale la pena di riassumere brevemente i concetti legati a questo standard, ancor prima di
affrontare altri problemi legati alla scrittura.
219.1 Caratteristiche fondamentali dello standard ISO 216
Nello standard ISO 216, i lati del foglio di carta hanno un rapporto fisso, dove il lato lungo è pari
alla radice quadrata di due (circa 1,4142) per la lunghezza del lato corto (figura 219.1).
Figura 219.1. Il rapporto tra i lati di un foglio ISO 216.
.---------------.
|
|
|
|
|
|
|
|
b = radq(2) * a
|
| b
|
|
|
|
|
|
|
|
‘---------------’
a
.---------------.
|
|
|
| a
|
|
|
|
|---------------|
|
|
|
|
|
| a
|
|
‘---------------’
b
Questo rapporto ha una proprietà importante, che consente al foglio di carta di essere dimezzato
sul lato lungo, oppure di essere raddoppiato sul lato corto, mantenendo lo stesso rapporto tra i
lati.
Lo standard ISO 216 definisce tre diverse serie di questi formati, ognuna delle quali parte da una
dimensione di partenza, generando le altre dimensioni suddividendo quella precedente a metà, sul
lato lungo. La serie A, ha come punto di riferimento il formato A0, corrispondente a un foglio
con un’area di un metro quadro, tuttavia non si tratta del formato più grande, che è ottenuto
raddoppiando due volte il formato A0, ottenendo così quattro metri quadri.
La tabella 219.1 elenca le dimensioni di tutti i formati delle tre serie, denominate A, B e C. Come
si può osservare, i valori sono approssimati al millimetro, in aderenza al SI (sezione 221.5).
Tabella 219.1. ISO 216: formato A, B e C.
A
4A0
2A0
A0
A1
A2
A3
A4
A5
A6
A7
A8
A9
A10
1
mm
1682 x 2378
1189 x 1682
841 x 1189
594 x 841
420 x 594
297 x 420
210 x 297
148 x 210
105 x 148
74 x 105
52 x 74
37 x 52
26 x 37
B
--B0
B1
B2
B3
B4
B5
B6
B7
B8
B9
B10
mm
--1000 x 1414
707 x 1000
500 x 707
353 x 500
250 x 353
176 x 250
125 x 176
88 x 125
62 x 88
44 x 62
31 x 44
Altri standard analoghi a ISO 216 sono UNI 936 e DIN 476.
2356
C
--C0
C1
C2
C3
C4
C5
C6
C7
C8
C9
C10
mm
--917 x 1297
648 x 917
458 x 648
324 x 458
229 x 324
162 x 229
114 x 162
81 x 114
57 x 81
40 x 57
28 x 40
Formati standard della carta
2357
219.2 Utilizzo pratico dei vari formati ISO 216
Tabella 219.2. Esempi di utilizzo pratico dei vari formati.
Formati
A0, A1
A2, A3
A4
A5
C4
C5
C6
B4, A3
Utilizzo
Disegno tecnico; poster.
Disegno; diagrammi; tabelle di grandi dimensioni.
Lettere; riviste; cataloghi; carta per stampanti comuni e per
fotocopiatrici.
Blocchi per appunti.
Buste per il formato A4.
Buste per il formato A4 piegato a metà.
Buste per il formato A4 piegato due volte.
Giornali.
La percentuale di ingrandimento o di riduzione di un formato per ottenerne un altro, si determina
facilmente, tenendo conto che si sta facendo riferimento all’ampiezza e all’altezza del foglio, non
alla sua area. In pratica, riducendo un formato A4 al 50 %, si ottiene un formato A6, mentre per
arrivare al formato A5 occorre usare una riduzione al 71 %. In altri termini, 71 %, ovvero 0,71,
approssima la radice quadrata di 0,5. La tabella 219.3 riepiloga alcune trasformazioni tipiche, da
un formato a un altro dello standard ISO 216.
Tabella 219.3. Esempi di ingrandimento e riduzione dei formati più comuni.
Trasformazione richiesta
da An a An +1
da Bn a An
da An a Bn
da Bn a An -1
da An a An -1
rapporto
sqrt(0,5)
sqrt(sqrt(0,5))
sqrt(sqrt(2))
sqrt(sqrt(2))
sqrt(2)
percentuale (approssimata)
71 %
84 %
119 %
119 %
141 %
La massa di un foglio di serie A, può essere determinata facilmente, sapendo che A0 ha una
superficie di un metro quadro. In pratica, basta conoscere la densità superficiale della carta (la
cosiddetta grammatura) che si esprime normalmente in grammi per metro quadro, dividendone
opportunamente il valore: l’An avrà una massa pari a 2-n volte quella dell’A0. Per esempio, la
massa di un foglio A4 sarà 2-4 volte quella di un A0; ovvero 1/16; se la grammatura è 80 g/m2,
la massa di un foglio A4 è 5 g.
Le dimensioni dei fogli delle tre serie ISO 216 possono essere determinate anche attraverso
delle formule matematiche, come mostrato nella tabella 219.4. Si osservi che le misure che si
ottengono sono espresse in metri.
Tabella 219.4. Formule per calcolare le dimensioni della carta secondo lo standard
ISO 216.
Formato
An
Bn
Cn
Ampiezza in metri
2(-1/4-n /2)
2(-n /2)
2(-1/8-n /2)
Altezza in metri
2(1/4-n /2)
2(1/2-n /2)
2(3/8-n /2)
Formati standard della carta
2358
219.3 Formati multipli
Quando non si può utilizzare un formato in cui il rapporto tra la lunghezza dei lati sia quello delle
serie A, B o C comuni, si possono usare dei multipli di uno di questi formati. Come si vede nella
figura 219.2, si tratta di affiancare più fogli di un certo formato, estendendo il lato corto. Questi
formati estesi si indicano come An xm , dove m rappresenta quanti fogli di tipo An affiancare.
Per esempio, il formato A3 è equivalente al formato A4x2.
Figura 219.2. Formati multipli An xm .
.---------------------------------------------------------------.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
An
|
An
|
An
|
An
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
‘---------------------------------------------------------------’
<--------------------------- m volte -------------------------->
219.4 Riferimenti
• Markus Kuhn, International standard paper sizes
<http://www.cl.cam.ac.uk/~mgk25/iso-paper.html>
• Guide to international paper sizes, Concise tables of measurements, EDS Inc., 1997-2000
<http://www.twics.com/~eds/paper/papersize.html>
• R. Smith, F. Wright, T. Hastings, S. Zilles, J. Gyllenskog, RFC 1759: Printer MIB,
Appendix B - Media size names from ISO/IEC 10175 Document printing architecture, 1995
<http://www.cis.ohio-state.edu/cgi-bin/rfc/rfc1759.html>
<http://www.cis.ohio-state.edu/cs/Services/rfc/rfc-text/rfc1759.txt>
• T. Hastings, R. Herriot, R. deBry, S. Isaacson, P. Powell, RFC 2911: Internet printing
protocol/1.1: model and semantics, Appendix C: "media" keyword values, 2000
<http://www.cis.ohio-state.edu/cgi-bin/rfc/rfc2911.html>
<http://www.cis.ohio-state.edu/cs/Services/rfc/rfc-text/rfc2911.txt>
Appunti di informatica libera 2003.01.01 --- Copyright © 2000-2003 Daniele Giacomini -- daniele @ swlibero.org
Capitolo
220
Nozioni elementari di tipografia
Prima di studiare un programma di editoria elettronica conviene conoscere almeno qualche nozione di tipografia. Studiando la natura del problema si può comprendere la ragione di alcuni
comportamenti dei programmi più raffinati che rispecchiano nella loro impostazione la filosofia
della tipografia tradizionale.
220.1 Caratteri
Il carattere è qualunque segno grafico utilizzato in tipografia per rappresentare le lettere, i segni
di interpunzione, le cifre e altri grafemi. La conoscenza delle caratteristiche fondamentali del carattere da stampa è necessaria per poter comprendere il funzionamento e la logica dei programmi
di composizione tipografica. Sul carattere si possono distinguere diversi aspetti, in particolare:
• specie alfabetica;
• stile, o gruppo stilistico;
• serie alfabetica, o variante di serie;
• scala dimensionale.
Al di sopra di questa classificazione sta eventualmente il genere, intendendo con questo la distinzione in base ai suoi componenti: segni alfabetici, segni paralfabetici, segni estralfabetici, fregi,
iconografie, paraiconografie.
220.1.1 Specie alfabetica
La specie è una collezione di segni di un tipo di scrittura. Per quanto ci riguarda, la specie alfabetica comune è quella dell’alfabeto latino. All’interno di una specie alfabetica si possono distinguere diverse collezioni alfabetiche, per esempio come nella distinzione tra lettere maiuscole
e minuscole che avviene nell’alfabeto latino.
Dalla differenza tra gli alfabeti nasce a volte la necessità di rendere un testo attraverso un alfabeto
alternativo. La traslitterazione è il procedimento di traslazione da un sistema alfabetico a un
altro, in modo da ricomporre un testo facendo uso di un sistema alfabetico diverso da quello
originale. La traslitterazione punta a riprodurre un testo in modo che sia possibile in qualsiasi
momento il procedimento inverso per riottenere il testo originale. Il caso più comune in cui si ha
la necessità di utilizzare la traslitterazione è quello della citazione in cui l’originale utilizza un
alfabeto esotico per il quale non si dispone del carattere tipografico. Come si può immaginare, la
traslitterazione è regolata da norme internazionali.
220.1.2 Gruppo stilistico
Una volta definita la specie di un carattere si possono distinguere delle varianti che riguardano
lo stile, ovvero il disegno e il suo gusto estetico. Sull’alfabeto latino sono stati realizzati una
quantità così grande di stili diversi che è difficile persino riuscire a classificarli. In generale vi si
fa riferimento attraverso il nome. Gli stili più noti nella composizione elettronica sono: Times,
Helvetica e Courier.
2359
2360
Nozioni elementari di tipografia
I tre nomi citati rappresentano oggi, simbolicamente, le caratteristiche fondamentali di uno stile:
la presenza o l’assenza di grazie e la proporzionalità o meno della larghezza dei segni.1
Le grazie sono dei piedini terminali che hanno lo scopo di abbellire il carattere e di guidare la
vista durante la lettura. Il Times è il tipico stile con grazie, mentre Helvetica è il suo opposto.
I segni dei caratteri da stampa sono generalmente di larghezza diversa; solo le prime forme di
scrittura meccanica, come la macchina da scrivere e le prime stampanti, hanno creato la necessità
di utilizzare dei simboli a larghezza uniforme. Il Courier è il rappresentante di questo tipo di stile
a larghezza fissa.
In generale, uno stile riguarda esclusivamente un genere alfabetico, ma quando uno stile assume
importanza e notorietà, può succedere che venga adottato anche da altri generi. Per questo si può
distinguere tra Times Roman (Times New Roman), Times Greco, Times Cirillico e altri. Il primo
tra quelli citati è ovviamente il Times dell’alfabeto latino.
220.1.3 Serie
La serie alfabetica, o la variante di serie, rappresenta una distinzione all’interno di uno stile,
in base alla forma . Le forme comuni di uno stesso stile riguardano la pendenza, il tono e la
larghezza.
• La pendenza si riferisce all’inclinazione delle aste e si distingue generalmente tra tondo,
che rappresenta un carattere con aste verticali, e corsivo in cui le aste sono inclinate in
avanti. Generalmente, l’aspetto dei caratteri di un corsivo, pur restando all’interno della
stesso stile, è abbastanza diverso da quello del tondo. Quando si utilizza un sistema di
composizione elettronico può capitare di avere a disposizione uno stile nel quale manchi
il corsivo, che però viene ottenuto in qualche modo distorcendo il tondo. In questo caso si
parla preferibilmente di carattere «inclinato» in modo volutamente generico.
• Il tono, o lo spessore, rappresenta l’intensità del carattere che si percepisce visivamente.
Essendo un concetto che deriva dalla stampa con inchiostro nero, si distingue generalmente
tra chiarissimo , chiaro, nero (neretto) e nerissimo .
• La larghezza è una caratteristica di cui dispongono solo alcuni stili, ovvero li può riguardare
direttamente, nel senso che uno stile per sua natura può essere «stretto» o «largo». In base
alla larghezza si distinguono solitamente: lo strettissimo, lo stretto, il normale, il largo e il
larghissimo .
È bene chiarire che ogni stile può disporre o meno di varianti seriali adatte. Alcuni stili, spesso
riferiti a specie alfabetiche simboliche, dispongono di una serie unica.2
1
Questi tre stili sono molto importanti, in parte per motivi storici, ma soprattutto perché sono quelli che si hanno a
disposizione più di frequente.
2
Alcuni sistemi di composizione riescono a trarre il corsivo e il neretto da stili che per loro natura non hanno tali
varianti. Per ottenerlo si utilizzano tecniche di deformazione e di trascinamento. In generale sarebbe bene evitare di
sfruttare tali possibilità, dal momento che se uno stile non dispone di una serie, significa che non è adatto per quella.
Nozioni elementari di tipografia
2361
220.2 Tipometria
La tipometria è la misurazione degli elementi che riguardano la composizione e l’impaginazione. Le voci più importanti sono costituite dai corpi (l’altezza dei caratteri), dalla spaziatura,
dall’interlinea, dalla giustezza e dalla giustificazione. In breve, il corpo è l’altezza del carattere,
la spaziatura è la distanza tra una parola e l’altra in una riga, l’interlinea è lo spazio verticale
aggiuntivo tra le righe, la giustezza è lo spazio orizzontale che le righe di testo hanno a disposizione, la giustificazione è il procedimento di regolazione della spaziatura e dell’interlinea in
modo da ottenere un allineamento delle righe con i margini (sia in orizzontale che in verticale).
220.2.1 Corpo, dimensioni e scala
La dimensione del carattere si misura in senso verticale e si definisce corpo. Per misurare il corpo
e le altre dimensioni che riguardano i caratteri si possono utilizzare diverse unità di misura, ma
quando si tratta di sistemi di composizione elettronica a mezzo di software, è molto probabile
che si disponga solo del pica e del punto anglo-americano:
• 1 pica = 1/6 di pollice;
• 1 punto = 1/12 di pica = 1/72 di pollice.
Per comprendere cosa sia il corpo di un carattere è bene descrivere le varie componenti dell’altezza di questo. La figura 220.1 mostra schematicamente la parola «Agglomerato» (abbreviata)
suddivisa orizzontalmente secondo le componenti verticali della dimensione del carattere.
Figura 220.1. Le dimensioni del carattere.
_____________________________________________________________________
spalla superiore
_____________________________________________________________________
/\
parte ascendente
|
|
______/ \_______________________|
|_______________________________
/
\
/--\/
/--\/
|
|
/--\
/--\ /--\ parte
/------\
|
|
|
|
|
|
|
|
|
|
| mediana
__ /
\___\--/|____\--/|___|___|____\--/____|
|
|__*_____
|
|
parte discendente
____________________/________/_______________________________________
spalla inferiore
_____________________________________________________________________
^
|
|
|
|
| corpo
|
|
|
|
v
Il carattere si appoggia su una linea che rappresenta la base della «parte mediana»; le lettere come
la «l» si alzano occupando anche la «parte ascendente»; altre, come la «g», si allungano in basso
a occupare la «parte discendente». Il corpo del carattere include anche uno spazio aggiuntivo: la
«spalla». Si distingue una spalla superiore, che è uno spazio minimo sopra la parte ascendente,
e la spalla inferiore, che si trova al di sotto della parte discendente (nella figura la spalla è molto
grande, in proporzione, rispetto alla realtà).
La distanza tra la base di una riga (la base della parte mediana) e la base di quella successiva
dovrebbe essere superiore o al minimo uguale alla grandezza del corpo. Quando questa distanza
è superiore, lo spazio aggiuntivo è l’interlinea . Con i sistemi di composizione elettronica per
mezzo di software, si misura generalmente lo spazio tra le basi delle righe ed è ammissibile anche
l’utilizzo di distanze inferiori all’altezza del carattere, ottenendo in pratica una sovrapposizione
della parte mediana inferiore di una riga con la parte mediana superiore di quella successiva.
La rappresentazione di un carattere con un corpo di una data dimensione dipende dalla disponibilità di questo. Con i sistemi tipografici tradizionali era necessario disporre di una serie di
caratteri mobili differenti, distinti in base a una scala. Con i sistemi di composizione elettronica
2362
Nozioni elementari di tipografia
via software si possono trovare dei caratteri riproducibili in qualsiasi corpo, eventualmente generando dei file opportuni per la scala richiesta. Tuttavia, in presenza di dimensioni particolarmente
piccole si rischia di perdere dei dettagli importanti dei segni che compongono lo stile utilizzato e,
di conseguenza, potrebbe essere preferibile l’utilizzo di una variante dello stile che sia più adatta
alle dimensioni ridotte.
220.2.2 Giustezza, spaziatura e giustificazione orizzontale
La giustezza è lo spazio orizzontale a disposizione delle righe di testo; in altri termini, è la
larghezza della colonna all’interno della quale si può distribuire il testo. La spaziatura è lo spazio
tra la fine di una parola e l’inizio di quella successiva.
Nei testi in italiano, la spaziatura è uniforme, senza eccezioni, a differenza della tradizione
tipografica di altri paesi. Per esempio, la spaziatura dopo un punto fermo è esattamente uguale
a quella di qualunque altra situazione. Quando si utilizza il sistema di composizione TeX per
scrivere un testo in italiano, si dovrebbe inserire il comando ‘\frenchspacing’ per evitare
anomalie nella spaziatura.
Quando si vuole ottenere un allineamento del testo all’inizio e alla fine della giustezza, si parla
di giustificazione (orizzontale). Per ottenerla, è necessario che la spaziatura sia adattata in modo
da arrivare a questo risultato. La giustificazione orizzontale è solo una delle scelte stilistiche che
il tipografo ha a disposizione: non si tratta di una convenzione obbligatoria.
220.2.3 Giustificazione verticale
Come nel caso della giustificazione orizzontale, ci può essere la necessità o l’opportunità di
adattare l’interlinea in modo da riempire completamente le pagine. Ciò si ottiene attraverso la
giustificazione verticale.
220.3 Il carattere nel software di composizione
Utilizzando i programmi di composizione tipografica si è costretti generalmente a fare i conti
con la terminologia dei paesi di lingua inglese e con altri problemi legati alla rappresentazione
simbolica dei segni all’interno del software. La tradizione tipografica di questi ha generato dei
termini che non sono perfettamente traducibili con concetti della tradizione italiana, per cui si
utilizzano alcuni termini di origine anglofona, eventualmente tradotti in modo letterale.
220.3.1 Terminologia
In inglese si utilizza normalmente il termine font per fare riferimento al carattere tipografico.
In generale si preferisce non tradurre questo termine in qualcosa che riguardi la tradizione tipografica italiana, mantenendo piuttosto il termine inglese invariato, oppure utilizzando la forma
fonte .
Se il contesto non richiede un’aderenza perfetta con il termine originale inglese, si possono
usare forme meno impegnative come «carattere», «tipo di carattere», «carattere tipografico» o
«carattere da stampa».
Nozioni elementari di tipografia
2363
220.3.2 Caratteristiche di una fonte
La fonte tipografica, intesa come il carattere per il software applicativo di composizione, ha una
serie di caratteristiche, alcune delle quali sono fondamentali.
• foundry , fonderia
La fonderia è il produttore di una fonte, cioè chi ha creato la tipizzazione, pur senza esserne
il disegnatore. Per fare un esempio comune, Adobe è la fonderia dello stile Times New
Roman.
• family , famiglia
La famiglia del carattere, inteso come traduzione del termine font family, corrisponde simultaneamente alla specie e allo stile del carattere. In altri termini, rappresenta sia la specie
alfabetica che lo stile. Per fare un esempio, la famiglia Times New Roman è un carattere di
specie latina e di stile Times.
• All’interno di una famiglia si distinguono normalmente le serie riferite alla forma: spessore
(weight), inclinazione (slant) e larghezza (set, o width).
• codifica
La codifica rappresenta l’elemento nuovo più importante nelle caratteristiche di un carattere tipografico per l’elaborazione via software. Il problema viene descritto nella prossima
sezione.
220.3.3 Codifica
L’utilizzo dei caratteri con i sistemi di composizione basati sul software richiede un abbinamento tra segni e simboli binari. Questo abbinamento è definito dalla codifica. Il problema si può
intendere meglio se si pensa a un programma a composizione differita.
In questi casi si parte da un file sorgente, scritto probabilmente secondo la codifica ISO 8859-1,
con il quale il programma deve comporre il risultato, utilizzando le fonti a disposizione.
La fonte tipografica utilizzata dal programma di composizione è contenuta normalmente all’interno di file, da cui questo estrae le informazioni necessarie attraverso un riferimento dato da un
codice numerico. In condizioni normali, il programma di composizione fa riferimento al simbolo
binario utilizzato nel sorgente per ottenere il segno corrispondente all’interno della fonte utilizzata (eventualmente attraverso una qualche traslazione). In pratica, alla lettera «A» nel sorgente
dovrebbe corrispondere la lettera «A» della fonte che si sta utilizzando, ma se la fonte è organizzata in modo differente, si potrebbe ottenere qualcosa di diverso. Questo problema si avverte
di solito quando si utilizza una famiglia di caratteri che fa riferimento a una specie simbolica, o
comunque a un alfabeto che non ha alcuna corrispondenza con la codifica utilizzata nel sorgente.
In questi casi, di solito, per rappresentare i segni si può fare uso di comandi speciali interpretati
opportunamente dal programma di composizione.
Un programma di composizione potrebbe disporre di fonti che hanno solo una corrispondenza
parziale con la codifica utilizzata per scrivere il sorgente, per esempio, potrebbero mancare alcuni
segni che vengono messi a disposizione attraverso altre fonti.
Il problema viene riproposto nel capitolo 223, dedicato alla codifica universale.
Nozioni elementari di tipografia
2364
220.4 Problemi legati ai caratteri
Nelle origini della tipografia, molti caratteri mobili rappresentavano l’unione di più lettere o altri
segni in logotipo (cioè l’unione in un simbolo unico). L’unione di questi derivava da delle consuetudini stilistiche o dalla forma dei segni adiacenti che per qualche motivo potevano richiedere
un avvicinamento o un adattamento.
Il legato (in inglese ligature) è l’unione di due o più segni per motivi storici o estetici; i più
comuni sono le sequenze «fi», «fl» e «ffi», dove le lettere vengono avvicinate in modo particolare
fino a unirsi o a inglobarsi. Alcune forme di legato si sono tradotte in segni indipendenti, come
nel caso di «AE» che si è trasformato in «Æ», «sz» che nella lingua tedesca è ormai «ß» e anche
«et» (latino) che è divenuto «&», ovvero l’attuale e-commerciale.
L’avvicinamento delle lettere, era ed è motivato dalla forma di queste, per evitare il formarsi di
vuoti visivi che potrebbero creare difficoltà alla lettura. I casi più comuni sono le sequenze «AV»,
«AT», «AY».
220.5 Riferimenti
• Scienza, tecnologia e arte della stampa e della comunicazione, Arti poligrafiche europee
<http://www.apenet.it/grafica/libri/Grafica/Grafica01/indice02.html>
<http://www.apenet.it/grafica/libri/Grafica/Grafica02/indice02.html>
<http://www.apenet.it/grafica/libri/Grafica/Grafica03/indice02.html>
• Scienza, tecnologia e arte della stampa e della comunicazione: Giuseppe Pellitteri, Luigi
Farinelli, Grafismi, Arti poligrafiche europee
<http://www.apenet.it/grafica/libri/Grafica/Grafica01/1123.html>
Appunti di informatica libera 2003.01.01 --- Copyright © 2000-2003 Daniele Giacomini -- daniele @ swlibero.org
Capitolo
221
Stile letterario
Questo capitolo, vuole essere solo un riferimento essenziale alla definizione di uno stile letterario
e il contenitore di una piccola raccolta di regole, che dovrebbero semplificare la vita di chi scrive
documenti elettronici.
L’autore di questo documento non ha una competenza specifica su questo problema; tuttavia, è
importante almeno affrontare l’argomento sottolineando alcuni concetti importanti.1
221.1 Uniformità
Il concetto di stile letterario potrebbe essere espresso semplicemente spiegando l’esigenza di
realizzare un documento uniforme : sia dal punto di vista visivo, sia dal punto di vista espressivo.
Questo coinvolge quindi l’aspetto grammaticale (ortografia, sintassi, lessico, ecc.) e l’aspetto
tipografico (impaginazione, tipi di carattere, dimensione, ecc.) o artistico.
L’esigenza di un’uniformità visiva deriva dal piacere e dal rilassamento che può dare al lettore
un documento impaginato e strutturato in un modo ordinato e chiaro, per la facilità nella lettura
che ne deriva. Nello stesso modo è importante l’uniformità grammaticale, cosa particolarmente
delicata in una lingua come la nostra in cui sono consentite molte variazioni, data la varietà
linguistico-culturale delle varie regioni.
Il novello scrittore di documentazione tecnica, che scrive e impagina senza l’aiuto di un editore,
tende a comprendere l’esigenza di uno stile tipografico, dimenticando che esiste anche uno stile
espressivo-grammaticale.
Il problema dell’uniformità stilistica si accentua quando si deve collaborare alla realizzazione di
un progetto letterario. L’uniformità non è più solo un fatto di coerenza personale, ma di coerenza
complessiva di tutto il gruppo.
La coordinazione dei vari collaboratori è un problema delicato e diviene essenziale la stesura di
uno standard letterario complessivo. Alle volte questo ferisce la sensibilità di alcuni collaboratori
e genera discussioni senza fine e senza soluzione.2
221.2 Regole di composizione del testo
Il modo migliore per definire uno stile grammaticale è lo studio su un testo di grammatica. Qui
si vogliono solo raccogliere alcuni punti essenziali che non possono essere ignorati. In effetti, il
tipico autore di testi a carattere tecnico, specialmente quando non si tratta di un’attività professionale remunerata, ha un’ottima conoscenza dell’argomento trattato e una pessima padronanza
della lingua.
221.2.1 Punteggiatura e spaziatura
La punteggiatura si compone di quei simboli che consentono di separare le parole e di delimitare
le frasi.
1
Come sempre, tutte le segnalazioni di errore sull’ortografia, la sintassi e il contenuto di questo documento, sono
gradite. :-)
2
Il vero artista è colui che crea qualcosa di nuovo e non accetta di sottostare alle regole generali. È evidente quindi che
costui non potrà lavorare in un gruppo perché non si sottometterà mai alle regole poste dagli altri o dalla consuetudine.
2365
2366
Stile letterario
• Ogni parola è separata da un solo spazio.
Tipograficamente, lo spazio è una separazione di ampiezza non definita, spesso ampliato
o compresso, per ottenere un allineamento del testo sia a sinistra che a destra. Un autore
non deve pensare a queste cose quando scrive la propria opera; si deve limitare a spaziare
le parole con un solo carattere spazio.3
La dattilografia insegnava a ottenere testi allineati a sinistra e a destra con l’inserzione
opportuna di spazi aggiuntivi, vicino alle parole composte da poche lettere (congiunzioni,
articoli, ecc.). Questo tipo di tecnica è ormai da abbandonare, lasciando semmai che siano
i programmi di composizione a prendersi cura di questi problemi, anche quando il risultato
finale deve essere un file di testo puro e semplice.
I programmi di composizione più evoluti facilitano il compito dello scrittore eliminando gli
spazi superflui, per cui con questi non c’è l’esigenza di porre attenzione alla dimensione
delle spaziature.4
• I simboli di punteggiatura normale sono attaccati alla parola che precede e separati con uno
spazio dalla parola che segue.
Si tratta di: punto, virgola, due punti, punto e virgola, punto interrogativo e punto
esclamativo.
Alle volte, l’autore di documenti tecnici di informatica si lascia confondere dall’uso che si
fa di tali simboli in un particolare linguaggio di programmazione o in altri ambiti analoghi.
È chiaro, per esempio, che se si deve indicare un’estensione di un file, come «.sgml», non
si può rispettare tale regola, ma il punto che precede quell’estensione non rappresenta un
simbolo di punteggiatura del testo.
• Le parentesi sono attaccate al testo che racchiudono e, rispetto alla punteggiatura esterna,
si comportano come un’unica parola.
La parentesi di apertura è separata con uno spazio dalla parola che precede, mentre quella
di chiusura è separata con uno spazio dalla parola che segue. I simboli di punteggiatura
normale che dovessero seguire una parentesi chiusa vanno attaccati a questa ultima.
Nella lingua italiana non è consentito racchiudere all’interno di parentesi un periodo terminante con il punto fermo. Questa modalità è tipica della lingua inglese e i traduttori devono
tenerne conto, al limite togliendo le parentesi nella frase tradotta.
• Il testo riportato tra virgolette si comporta come quello racchiuso tra parentesi.
La lingua italiana prevede l’uso di virgolette uncinate (in basso), virgolette elevate doppie
e singole. Secondo la grammatica, le virgolette uncinate, o virgolette basse, sono da preferire. Tuttavia, dal momento che le virgolette elevate possono essere ottenute anche utilizzando soltanto il codice ASCII tradizionale a 7 bit, molti autori preferiscono accontentarsi
e utilizzare solo quelle elevate.5
• Il trattino di unione è corto e unito alle parole da collegare.
Si usa per unire insieme due parole in modo da formare una parola composta. I programmi
di composizione tendono a considerare un trattino singolo come un trattino corto, proprio
per questo scopo.
3
Secondo una regola della tipografia del passato, ormai condannata generalmente, era necessario aumentare lo spazio
che divide la fine di un periodo dall’inizio del successivo. Per qualche ragione si trovano ancora documenti in lingua
inglese che seguono questa regola, anche quando si tratta di file di testo.
4
Purtroppo LaTeX segue la vecchia regola dell’allungamento dello spazio dopo il punto fermo che chiude il periodo,
con l’aggravante che per riuscire a determinarlo può fare solo delle supposizioni, che a volte sono errate. Per fare in modo
che LaTeX eviti di applicare questa regola errata, si può utilizzare il comando ‘\frenchspacing’ nel preambolo del
documento.
5
Quando il sistema di composizione si basa su TeX e si usano virgolette elevate, le virgolette doppie si ottengono
preferibilmente attraverso una coppia di apici singoli aperti (‘‘‘’) e una coppia di apici singoli chiusi (‘’’’). In altri casi,
soprattutto quando si tratta di file di testo puri e semplici, gli apici doppi si indicano con le virgolette normali (‘"..."’).
Stile letterario
2367
• La lineetta, o trattino lungo, serve per introdurre un discorso diretto, oppure un inciso.
Il trattino utilizzato per delimitare un discorso diretto, viene usato normalmente solo in
apertura. Può apparire anche un trattino in chiusura quando al discorso diretto segue un
commento. Se il trattino si usa per delimitare un inciso, si usa per aprirlo e solitamente
anche per chiuderlo, come se si trattasse di parentesi.
Generalmente, il trattino lungo è preceduto e seguito da uno spazio; davanti al trattino di
chiusura vanno collocati il punto interrogativo, il punto esclamativo e i puntini, mentre per
gli altri simboli di punteggiatura non esiste una convenzione precisa.6
221.2.2 Utilizzo dei simboli di interpunzione
L’uso della punteggiatura nella lingua italiana è definito da regole molto vaghe che si prestano a
facili eccezioni di ogni tipo. Qui si elencano solo alcuni concetti fondamentali.
• ,
La virgola è un segno di interpunzione che collega due segmenti di testo separati da un
pausa debole.
• ;
Il punto e virgola è un segno di interpunzione che si colloca a metà strada tra la virgola e il
punto. Non segna la chiusura di un periodo.
• :
I due punti sono un simbolo di interpunzione esplicativo. Collegano due segmenti di testo
separati dal punto di vista sintattico, in cui la seconda parte, quella che segue il simbolo,
elenca, chiarisce o dimostra il concetto espresso nella prima parte.
• .
Il punto fermo è un segno di interpunzione che collega due segmenti di testo separati da
un pausa forte. Generalmente segna la conclusione di un periodo. La parola successiva al
punto ha l’iniziale maiuscola.
• !
Il punto esclamativo indica generalmente la conclusione di un’esclamazione affermativa.
Generalmente, quando conclude un periodo, il testo che segue ha l’iniziale maiuscola.
• ?
Il punto di domanda indica un tono interrogativo alla fine di una frase. Generalmente,
quando conclude un periodo, il testo che segue ha l’iniziale maiuscola.
• ...
I punti di sospensione sono in numero fisso di tre e indicano che il discorso non viene
portato a conclusione. Generalmente, sono uniti alla parola o al segno di interpunzione che
li precede, oppure distanziati, a seconda che siano solo una sospensione oppure indichino
l’omissione di un nome o di un’altra parola.
Se si trovano alla fine di un periodo, dove andrebbe collocato un punto, questo non viene
aggiunto e la frase successiva inizia con la maiuscola. Nello stesso modo, se si trovano alla
fine di un’abbreviazione che termina con un punto, questo punto viene assorbito.
6
TeX permette l’uso di tre trattini di lunghezza differente: il trattino corto che si ottiene con un trattino singolo, il
trattino medio che si ottiene con due trattini in sequenza e il trattino lungo che si ottiene con tre. Nella lingua italiana
vanno usati solo i primi due, dove il trattino medio di TeX corrisponde al trattino lungo della nostra grammatica.
Stile letterario
2368
• ecc.
Il punto di abbreviazione, quando si trova alla fine di un periodo, conclude da solo anche il
periodo stesso, ed è seguito da iniziale maiuscola.
• ( )
Le parentesi, generalmente tonde, servono per delimitare un inciso, come un commento,
una nota dello scrivente, un chiarimento, ecc. Generalmente, i commenti del redattore o
del traduttore sono terminati, entro l’ambito delle parentesi, con le sigle NdR (nota del
redattore) e NdT (nota del traduttore).
221.2.3 Accenti e troncamenti
Nella lingua italiana scritta, l’uso degli accenti è un fatto puramente convenzionale. Ciò significa
che l’accento non indica necessariamente il suono che ha effettivamente la lettera accentata,
ma solo la sua rappresentazione consueta (più avanti, nella sezione 221.2.4 è riportato il testo
originale della norma UNI 6015 sul «segnaccento obbligatorio»).7
• Nella lingua scritta è prevista (ed è obbligatoria) solo l’accentazione delle vocali finali delle
parole nelle quali il tono della voce si rafforza sull’ultima sillaba (accento grafico).
È possibile l’uso dell’accento per le vocali interne quando ciò serva per togliere ambiguità
tra termini omografi (scritti nello stesso modo) che abbiano significati differenti. Generalmente, questa ambiguità è risolta dal contesto e raramente si incontra la necessità di
utilizzare accenti interni.
• Si utilizza comunemente solo l’accento grave (àèìòù), con l’eccezione della vocale «e» che
può avere l’accento acuto (é).
• Vogliono l’accento acuto le parole terminanti in ché (perché, poiché, ecc.), oltre a né
(congiunzione) e sé (pronome tonico). In particolare, sé viene scritto generalmente senza
accento quando è seguito da stesso, anche se la grammatica non lo richiede.
• Vogliono l’accento alcuni monosillabi contenenti due vocali: ciò, già, giù, più e può.
• Vogliono l’accento i monosillabi che senza potrebbero avere un significato differente. La
tabella 221.1 mostra l’elenco dei monosillabi accentati più importanti.
• Non vogliono l’accento alcuni monosillabi tra cui: qui, qua, sto e sta.
• Solo alcune parole tronche richiedono la segnalazione di tale troncamento con l’apostrofo
finale. In particolare: po’ (poco), mo’ (modo), ca’ (casa) e alcuni imperativi.
• L’accento circonflesso (^) non si usa più. Serviva per i nomi terminanti in -io che al plurale
terminerebbero in -ii (per esempio: armadio, armadii). Attualmente, si tende a usare questi
plurali con una sola -i finale, a parte i casi in cui ciò genera ambiguità (assassino, assasini;
assassinio, assassinii).
7
Nell’ambito della documentazione tecnica, sarebbe consigliabile di evitare l’uso di accentazioni non comuni, anche
se queste potrebbero essere preferibili in ambienti più raffinati.
Stile letterario
2369
Tabella 221.1. Elenco dei monosillabi accentati più importanti e dei loro equivalenti
(omografi) non accentati.
dà
è
là
lì
né
sé
sì
indicativo di dare (dà valore)
verbo
avverbio (resta là)
avverbio (vado lì)
congiunzione (né questo né quello)
pronome tonico (pieno di sé)
avverbio (dice di sì)
da
e
la
li
ne
se
si
preposizione (da voi)
congiunzione
articolo
pronome
pronome (ne voglio ancora)
pronome atono o congiunzione
pronome
Alle volte, l’uso delle vocali accentate può creare problemi tecnici, dovuti alla loro mancanza
nell’insieme di caratteri a disposizione. In Italia, come nei paesi dell’Europa centrale, si utilizza
la codifica ISO 8859-1 (Latin 1) che contiene tutte le nostre lettere accentate. Nelle circostanze
in cui ciò non è attuabile (per esempio quando si dispone di un sistema configurato male, o la
tastiera non dispone dei simboli necessari), occorre utilizzare delle tecniche di rappresentazione
che dipendono dal programma utilizzato per la composizione.
221.2.3.1 SGML e XML
SGML e XML, comprendendo in queste categorie anche HTML e XHTML, dispongono di una
serie di entità standard, a cui corrispondono in particolare le macro elencate nella tabella 221.2.
Tabella 221.2. Vocali accentate attraverso l’uso di macro SGML e XML.
Vocale accentata
à, À
è, È
ì, Ì
ò, Ò
ù, Ù
é, É
Macro corrispondente
&agrave;, &Agrave;
&egrave;, &Egrave;
&igrave;, &Igrave;
&ograve;, &Ograve;
&ugrave;, &Ugrave;
&eacute;, &Eacute;
221.2.3.2 TeX/LaTeX
TeX (e di conseguenza LaTeX) dispone di una serie di codici elencati nella tabella 221.3.
Tabella 221.3. Vocali accentate per TeX.
Vocale accentata
à, À
è, È
ì, Ì
ò, Ò
ù, Ù
é, É
Codice TeX corrispondente
\‘a, \‘A
\‘e, \‘E
\‘{\i}, \‘I
\‘o, \‘O
\‘u, \‘U
\’e, \’E
Stile letterario
2370
221.2.3.3 Lout
Lout dispone del comando ‘@Char’ per indicare simbolicamente i segni tipografici che per qualche ragione non possono essere scritti letteralmente attraverso la codifica a disposizione. La
tabella 221.4 mostra i comandi necessari a ottenere le vocali accentate.
Tabella 221.4. Vocali accentate per Lout.
Vocale accentata
à, À
è, È
ì, Ì
ò, Ò
ù, Ù
é, É
Comando di Lout
@Char agrave, @Char Agrave
@Char egrave, @Char Egrave
@Char igrave, @Char Igrave
@Char ograve, @Char Ograve
@Char ugrave, @Char Ugrave
@Char eacute, @Char Eacute
221.2.3.4 Testo puro
Quando si scrive un file di testo puro e semplice, ma non è possibile utilizzare la codifica ISO
8859-1, si può aggiungere un apice opportuno subito dopo la vocale da accentare. Naturalmente
questa tecnica può valere solo per la lingua italiana in cui gli accenti si pongono solo nelle vocali
finali. Visivamente il risultato è molto simile a quello corretto.
Tabella 221.5. Trucco per rappresentare le vocali accentate quando non si può fare
altrimenti.
Vocale accentata
à, À
è, È
ì, Ì
ò, Ò
ù, Ù
é, É
Vocale apostrofata corrispondente
a‘, A‘
e‘, E‘
i‘, I‘
o‘, O‘
u‘, U‘
e’, E’
221.2.4 Segnaccento obbligatorio (UNI 6015)
Quello che segue è la norma UNI 6015 sull’uso degli accenti. Il testo è stato ottenuto da Scienza, tecnologia e arte della stampa e della comunicazione, Preparazione del manoscritto <http://
www.apenet.it/grafica/libri/Grafica/Grafica01/1206.html>.
Segnaccento obbligatorio nell’ortografia della lingua italiana (Uni 601567):
1. Scopo
La presente unificazione ha lo scopo di stabilire le regole ortografiche per il
segnaccento nei testi stampati in lingua italiana, quando esso sia obbligatorio.
2. Definizione
2.1 Il segnaccento (o segno d’accento, o accento scritto) serve a indicare
esplicitamente la vocale tonica, per esempio: andrà, colpì, temé, virtù.
2.2. Il segnaccento può essere grave (‘‘’) o acuto (‘’’).
3. Uso
Stile letterario
2371
Il segnaccento è obbligatorio nei casi seguenti:
3.1. Su alcuni monosillabi, per distinguerli da altri monosillabi che si scrivono con le
stesse lettere ma senza accento:
ché («poiché», congiunzione causale) per distinguerlo da che (congiunzione in ogni
altro senso, o pronome);
dà (indicativo presente di dare) per distinguerlo da da (preposizione) e da’ (imperativo
di dare);
dì («giorno») per distinguerlo da di (preposizione) e di’ (imperativo di dire);
è (verbo) per distinguerlo da e (congiunzione);
là (avverbio) per distinguerlo da la (articolo, pronome, nota musicale);
lì (avverbio) per distinguerlo da li (articolo, pronome);
né (congiunzione) per distinguerlo da ne (pronome, avverbio);
sé (pronome tonico) per distinguerlo da se (congiunzione, pronome atono);
sì («così», o affermazione) per distinguerlo da si (pronome, nota musicale);
té (pianta, bevanda) per distinguerlo da te (pronome).
3.2. Sui monosillabi: chiù, ciò, diè, fé, già, giù, piè, più, può, scià.
3.3. Su tutte le parole polisillabe su cui la posa della voce cade sulla vocale che è alla
fine della parola, per esempio: pietà, lunedì, farò, autogrù.
4. Forma
4.1. Il segnaccento, nei casi in cui è obbligatorio, è sempre grave sulle vocali: a, i, o,
u.
4.2. Sulla e, il segnaccento obbligatorio è grave se la vocale è aperta, è acuto se la
vocale è chiusa:
- è sempre grave sulle parole seguenti:
ahimè e ohimè, caffè, canapè, cioè, coccodè, diè e gilè, lacchè, piè, tè; inoltre sulla
maggior parte dei francesismi adattati, come bebè, cabarè, purè, ecc. e sulla maggior
parte dei nomi propri, come Giosuè, Mosè, Noè, Salomè, Tigrè;
- è acuto sulle parole seguenti:
ché («poiché») e i composti di che (affinché, macché, perché, ecc.), fé e i composti
affé, autodafé, i composti di re e di tre (viceré, ventitré), i passati remoti (credé, temé,
ecc., escluso diè), le parole mercé, né, scimpanzé, sé, testé.
4.3. Anche per la o si possono distinguere i due timbri (aperto o chiuso) con i due
accenti (grave ed acuto) ma solo in casi in cui l’accento è facoltativo, per esempio:
còlto (participio passato di cogliere, e cólto («istruito»).
221.2.5 Uso della «d» eufonica
Le congiunzioni e, o e la preposizione a, consentono l’aggiunta di una d eufonica, per facilitarne
la pronuncia quando la parola che segue inizia per vocale. Si tratta di una possibilità e non di una
regola; di questa d si potrebbe benissimo fare a meno.
Ognuno tende a usare questa d eufonica in modo differente, a seconda della propria cadenza
personale, che ne può richiedere o meno la presenza. Quando si scrive, bisognerebbe mantenere
lo stesso stile, anche sotto questo aspetto, quindi ognuno deve stabilire e seguire un proprio modo.
2372
Stile letterario
Esiste tuttavia un suggerimento che punta all’uso moderato di queste d eufoniche: usare la d solo
quando la vocale iniziale della parola successiva è la stessa; e non usarla nemmeno quando, pur
essendoci la stessa vocale iniziale nella parola successiva, ci sia subito dopo una d che possa
complicare la pronuncia.
221.2.6 Elisione davanti alla lettera «h»
In linea di massima, l’articolo che si mette davanti a un termine che inizia con la lettera h, è
quello che si userebbe pronunciando quella parola come se iniziasse per vocale. Secondo questo
principio, va usata l’elisione, così come si fa con i termini che iniziano per vocale, senza alcuna
«h» anteriore. Per esempio: l’harem; l’hotel; l’host.
Tuttavia, quando si tratta di un termine che, proveniendo da un’altra lingua, non è ancora diventato di uso comune e nella lingua originale si pronuncia con la lettera «h» iniziale aspirata, si
preferisce evitare l’elisione.
221.2.7 Uso delle maiuscole
L’iniziale maiuscola si utilizza all’inizio del periodo e per evidenziare i nomi propri. Nel dubbio
è meglio evitare di utilizzare le maiuscole. La lingua italiana fa un uso diverso delle maiuscole
rispetto ad altre lingue. Il novello scrittore di documenti tecnici tende a lasciarsi influenzare
dall’uso che si fa delle maiuscole nella lingua inglese. Per questo è bene ribadire che in italiano
l’uso di queste deve essere ridotto al minimo indispensabile.
221.2.8 Plurali
Ci sono alcuni aspetti del plurale nella lingua italiana che vale la pena di annotare. In particolare,
nel caso di chi deve utilizzare anche termini stranieri, si pone il problema di decidere se questi
siano invariabili o meno. A questo proposito, esistono due regolette semplici e pratiche:
• le parole terminanti per consonante sono invariate al plurale;
• i termini di provenienza straniera non ancora assimilati sono invariati al plurale.
In particolare, per quanto riguarda la seconda, la logica è che non si può applicare un plurale
secondo le regole di una lingua straniera mentre si usa l’italiano. Inoltre, dato che nella maggior
parte dei casi si tratta di termini inglesi, che nella loro lingua prenderebbero quasi sempre una
terminazione in -s al plurale, diventerebbe anche difficile la loro pronuncia in italiano.
221.2.8.1 Interfacce o interfaccie?
Esiste una regoletta che permette di stabilire facilmente come debba essere ottenuto il plurale
delle parole che terminano in -cia e -gia: la i rimane se la c e la g sono precedute da vocale,
oppure se la i viene pronunciata con accento, mentre viene eliminata se queste consonanti sono
precedute da un’altra consonante.
Quindi si ha: camicia, camicie e interfaccia, interfacce; ciliegia, ciliegie e spiaggia, spiagge;
energia, energie.
Stile letterario
2373
221.2.9 Elenchi
Gli elementi puntati, o numerati, possono essere composti da elementi brevi, oppure da interi
periodi. Se tutti gli elementi sono brevi:
• l’elenco deve essere introdotto da una frase terminante con due punti;
• ogni elemento deve essere terminato con un punto e virgola, a eccezione dell’ultimo che
termina normalmente con un punto.
La descrizione appena fatta mostra un esempio di elenco del genere. Se anche uno solo degli
elementi è troppo lungo, è bene trasformare tutti gli elementi in periodi terminati da un punto. In
tal caso, se l’elenco viene introdotto da una frase, anch’essa termina con un punto.
Ci possono essere situazioni in cui queste indicazioni non sono applicabili: come sempre è
necessario affidarsi al buon senso.
221.2.10 Citazioni
Le citazioni, cioè le frasi o i brani riprodotti letteralmente da altri documenti, devono apparire
distinte chiaramente dal testo normale. Si usano normalmente queste convenzioni:
• quando la citazione è incorporata nel testo viene delimitata attraverso le virgolette, oppure
utilizzando il corsivo se la citazione è particolarmente breve;
• le citazioni incluse in un’altra citazione già virgolettata si evidenziano attraverso l’uso di un
altro tipo di virgolette, cominciando da quelle uncinate («»), utilizzando poi quelle elevate
doppie (‘‘’’) e terminando con quelle singole (‘’);
• quando la citazione è molto lunga e occupa diversi capoversi, conviene utilizzare un corpo
minore o un altro espediente tipografico per distinguerla dal testo normale, come con l’uso
di rientri differenti;
• quando la citazione è lunga e non si vogliono utilizzare altri espedienti per evidenziarla, si
utilizzano le virgolette, ripetendo quelle di apertura all’inizio di ogni capoverso;
• all’interno delle citazioni possono apparire dei commenti o chiarimenti inseriti da chi scrive,
delimitandoli attraverso l’uso di parentesi quadre;
• all’interno delle citazioni vanno indicate le omissioni, che possono essere segnalate attraverso l’uso dei puntini di sospensione racchiusi tra parentesi quadre (come per i
commenti);
• quando si fanno delle omissioni nella citazione all’inizio o alla fine del brano, è preferibile l’uso dei puntini di sospensione senza che questi siano racchiusi tra parentesi quadre;
all’inizio i puntini di sospensione sono staccati dalla prima parola, mentre alla fine sono
attaccati all’ultima.
Stile letterario
2374
221.3 Traduzioni e termini stranieri
Le traduzioni rappresentano un problema in più, dal punto di vista dell’uniformità stilistica
espressiva, soprattutto perché sono frequentemente il risultato di un lavoro di gruppo. Il problema
più grave è rappresentato dalla traduzione o dall’acquisizione di quei termini che non fanno parte
del linguaggio comune.
• Una traduzione non può essere letterale, perché lingue diverse hanno strutture differenti e
il significato che si attribuisce alle parole dipende dal contesto. Quello che conta, quindi, è
che il significato sia mantenuto.
• Quando si tratta di termini tecnici di origine straniera, la loro traduzione può essere inopportuna, soprattutto quando chi deve esprimersi con quei concetti utilizza già abitualmente
il termine in questione, nella forma originale, senza tradurlo.
In pratica, è importante che gli utenti esperti possano trovare familiare la traduzione di un
documento tecnico rivolto a loro.
• Una traduzione utilizzata largamente sul campo deve essere privilegiata al momento della
scelta. È importante evitare che gli utenti esperti possano essere confusi da una traduzione.
In pratica: gli utenti esperti devono trovare familiari le traduzioni scelte.
• Quando un termine straniero ha un significato più specifico della sua traduzione letterale,
allora non conviene tradurlo.
L’esempio più importante che deriva da questa affermazione è il termine file, che in italiano
identifica precisamente il concetto di archivio elettronico generico .
L’attività di traduzione è tanto più delicata se si considerano i vincoli posti dalle convenzioni
internazionali che regolano l’editoria. In breve, la traduzione deve essere autorizzata dall’autore
originale, verso il quale ci si assume la responsabilità del buon esito di questa operazione.
Per questo, la traduzione non può alterare il contenuto espresso dall’autore originale e nemmeno
chiarirlo. Nello stesso modo, una traduzione deve sempre essere accompagnata dall’indicazione
dei nomi dei traduttori che l’hanno realizzata.
221.3.1 Acquisizione di termini inglesi
Quando si decide di lasciare inalterato il termine straniero nel testo italiano, si pone il problema
di stabilire il modo con cui questo possa convivere con il resto del testo. L’unica regola sicura è la
verifica dell’uso generale, attraverso la discussione nelle liste specializzate. Tuttavia si possono
definire alcune regole di massima, per dare l’idea del problema.
È importante osservare che nell’ambito delle traduzioni di documenti tecnici, nella stragrande
maggioranza dei casi, si ha a che fare con l’inglese. Infatti, l’acquisizione di un termine straniero
tende a seguire logiche differenti a seconda della lingua di origine. Per comprenderlo basta pensare con quanta facilità si potrebbe acquisire un termine francese, come «console», rispetto a un
termine inglese.
• La prima cosa da fare di fronte a un termine da non tradurre è di verificare in un vocabolario
di lingua italiana; se c’è, il problema è risolto. Questo potrebbe sembrare un consiglio
banale; ma attualmente appaiono già parole come «input» e «output» che non sono poi di
uso così generalizzato.
Stile letterario
2375
• Un termine inglese può assumere il genere che avrebbe se tradotto in italiano, oppure quello
che suona meglio dandogli un significato italiano. In caso di dubbio è importante controllare
l’uso comune (se esiste).
• I termini inglesi non tradotti sono invariabili al plurale, cioè quando sono inseriti in testi in
italiano vanno scritti sempre al singolare, senza aggiungere la lettera «s» finale, anche se ci
si riferisce a una quantità maggiore di uno.
A titolo di esempio si pensi al termine «mouse» che al plurale inglese diventa «mice». Chi
usa questo termine, probabilmente è costretto a farlo, dato che l’italiano offre poche alternative; forse si potrebbe indicare come «dispositivo di puntamento», ma questa definizione
è troppo generica e probabilmente non verrebbe compresa. Pertanto, chi usa questi termini
non può essere anche costretto a conoscere perfettamente l’inglese e il modo corretto di
usare i plurali in quella lingua.
In altri termini, la lingua italiana non può incorporare le regole di un’altra lingua.
Quando il termine che non si traduce non è di uso comune nell’ambiente a cui si rivolge il
documento, dovrebbe essere evidenziato in corsivo tutte le volte che viene utilizzato. Per chiarire
meglio il concetto, un termine tecnico può essere o meno di uso comune per il pubblico di lettori
a cui si rivolge: se si tratta di un termine considerato normale per quell’ambiente, non è il caso di
usare alcuna evidenziazione.
221.3.2 Stesura di un glossario
Quando si traduce un documento è importante la preparazione di un glossario, inteso come una
raccolta di traduzioni standard che permettono di mantenere uniformità nel documento tradotto.
Questo diventa tanto più importante quando si lavora in gruppo, o si partecipa alla traduzione di
un gruppo di opere che fanno parte di uno stesso ambito tecnico.
Un glossario del genere non può essere un documento statico, in quanto si ha la necessità di
aggiornare continuamente il suo contenuto; se non altro per estenderlo.
Nell’ambito della documentazione GNU, ci si può iscrivere alla lista [email protected] per chiedere
informazioni sul lavoro già svolto e per discutere termini non ancora definiti dal glossario in corso
di realizzazione. Per iscriversi basta inviare un messaggio a [email protected] contenente
nel corpo (e non nell’oggetto) il testo seguente:
‘subscribe it’
L’invio di messaggi al gruppo di discussione va indirizzato poi a [email protected].
Eventualmente si può scaricare il glossario attuale da <ftp://ftp.linux.it/pub/People/md/glossario.tgz>,
tenendo presente che il moderatore della lista desidera che non sia distribuito ulteriormente, in
modo da evitare che si diffondano versioni obsolete.
Come ultima nota è opportuno chiarire che un glossario per la traduzione può essere solo uno
strumento, per l’utilizzo da parte di persone in grado di capire il contesto in cui i termini sono usati e di stabilire se le voci corrispondenti del glossario sono applicabili alle situazioni
particolari.
Stile letterario
2376
221.3.3 Opere originali
Anche l’autore di un’opera originale di carattere tecnico, si imbatte in problemi simili a quelli
dei traduttori. Infatti, quando l’acquisizione di un termine tecnico straniero riguarda solo l’ambito
specializzato per il quale si scrive, si può dubitare del modo giusto di utilizzarlo.
Per questo, anche gli autori di opere originali possono avere la necessità di preparare un glossario
e di discutere le espressioni migliori per un concetto determinato.
221.4 Strafalcioni comuni
L’influenza della lingua inglese porta a deformazioni sempre più frequenti nella lingua italiana.
Queste annotazioni vogliono essere di aiuto a chi scrive in italiano sotto l’influenza della prosa
inglese, sia perché sta traducendo, sia perché è abituato a leggere solo documentazione tecnica
scritta in inglese. Il problema più evidente, ma più facile da affrontare, è quello dei «falsi amici»:
quei termini che, pur assomigliandosi (e pur avendo, spesso, la stessa etimologia), hanno significati diversi nelle due lingue. Gli esempi più celebri sono «factory» che diventa erroneamente
«fattoria» e «cold» che si trasforma in «caldo».
Il problema meno evidente e per questo più insidioso è dato dalle altre differenze fra le due lingue:
la punteggiatura, l’uso delle maiuscole e la struttura delle frasi. Trascurando queste particolarità
si rischia di ottenere un testo che è formalmente in italiano, ma che non «suona» come tale.
Per completare il quadro, viene mostrato qualche esempio comune per chiarire questi concetti,
ma è bene ricordare che le possibilità sono infinite e che l’unico modo per scrivere in buon italiano
è leggere tanto buon italiano (così come avviene per qualsiasi linguaggio di programmazione).
221.4.1 Falsi amici
I «falsi amici» sono quei termini inglesi che sembrano avere una traduzione ovvia in italiano, che
però non è corretta. Lo specchietto che si vede nella tabella 221.6 mostra la traduzione corretta
di alcuni termini, frequenti nei testi informatici, lasciando intuire l’errore comune che si fa al
riguardo.
Tabella 221.6 Traduzioni corrette dei «falsi amici».
consistent
exhaustive
line
re... (recursive)
set
to set
subject
to process
to assume
proper (agg.)
proper (avv.)
to support
to return something
coerente
esauriente
riga (quasi sempre)
ri... (ricorsivo)
insieme («set» è tennistico)
impostare («settare» è di pessimo gusto)
oggetto (di una lettera o di un messaggio)
elaborare
supporre
giusto, corretto
vero e proprio
si usi, per quanto possibile, una perifrasi
restituire qualcosa («ritornare» è intransitivo)
Stile letterario
2377
221.4.2 Ortografia e sintassi
Quello che segue è un elenco di annotazioni riguardo all’uso dell’ortografia e della sintassi.
• La «e» o la «o» che introduce l’ultimo termine di un elenco non va preceduta da virgola.
In inglese americano la norma è di usare la virgola (ma gli inglesi non la usano); a volte in
italiano la virgola è ammissibile, ma si tratta di eccezioni.
• Se le frasi sono negative, allora devono essere separate con «né». Per esempio:
File che hanno questo bit settato non possono essere cancellati con DEL
o modificati.
va sostituito con:
I file che hanno questo bit impostato non possono essere cancellati con
DEL né modificati.
• I periodi italiani sono più complessi di quelli inglesi, a parità di registro. Come buona
regola, metà dei punti fermi vanno sostituiti con congiunzioni, subordinate, due punti o
punti e virgola. L’esempio seguente di traduzione viene da hostname(1).
-F, --file filename
Read the host name from the specified file.
(lines starting with a ‘#’) are ignored.
Comments
-F, --file nomefile
Legge il nome dell’host dal file specificato, ignorando
i commenti (righe che iniziano con ‘#’).
• L’uso del futuro in inglese è diverso da quello dell’italiano. L’esempio proviene da
mpage(1).
-O
Print 2 normal pages per sheet. But, this option
will print every first and forth page of every set
of four pages. This option will ignore the -a and
-l options.
-O
Stampa due pagine normali per foglio: questa opzione,
però, stampa la prima e la quarta pagina per ogni dato
insieme di quattro pagine. Questa opzione ignora le
opzioni -a e -l.
• I nomi dei mesi sono minuscoli.
• I numeri piccoli vanno scritti preferibilmente per esteso.
• In italiano si usa, di solito, la sequenza nome+aggettivo; il contrario, aggettivo+nome, per
quanto accettabile, ha spesso un significato diverso. Per esempio, si osservi la differenza tra
«pover’uomo» e «uomo povero».
• Bisogna sempre concordare il genere grammaticale: «la directory padre» non ha senso.
• Spesso chi scrive in inglese usa contorsioni grammaticali assurde per evitare di denotare il
genere della terza persona singolare; in particolare, si può trovare «they» o «their» usati al
singolare: ovviamente in italiano ciò non va fatto. L’esempio proviene da finger(1):
Mail status is shown as ‘‘No Mail.’’ if there is no mail at all, ‘‘Mail
last read DDD MMM ## HH:MM YYYY (TZ)’’ if the person has looked at their
mailbox since new mail arriving, or ‘‘New mail received ...’’, ‘‘
Unread since ...’’ if they have new mail.
Stile letterario
2378
221.5 Unità di misura
Nella documentazione a carattere scientifico diventa fondamentale la coerenza e la precisione
nel modo in cui si indicano le grandezze e le unità di misura, oltre che la scelta di queste. In
generale, ogni ambiente tecnico particolare tende a utilizzare le proprie grandezze e le proprie
unità di misura, tralasciando gli sforzi di standardizzazione internazionale, contribuendo così a
complicare inutilmente il proprio settore.
Purtroppo, l’ambito informatico costituisce l’esempio più problematico sotto questo aspetto, dal
momento che l’esigenza di mantenere una compatibilità con il sistema binario ha attribuito a
delle denominazioni ben precise del sistema decimale un significato differente rispetto a quello
comune a tutti gli altri ambiti scientifici.
Lo standard internazionale sulle unità di misura è costituito dal SI, ovvero Le Système international d’unités, in italiano Sistema internazionale di unità. Il punto di riferimento per questo lavoro
di armonizzazione è il BIPM (Bureau international des poids et mesures), con sede in Francia
(<http://www.bipm.fr/>).
221.5.1 Come si scrive una grandezza
Per esprimere una quantità riferita a una grandezza in modo grafico, occorre disporre del simbolo
(la sigla) che ne esprime l’unità di misura o un multiplo opportuno di tale unità, al quale si fa
precedere il numero, in cifre, di tale quantità:
n simbolo
È importante che tra il numero e la sigla ci sia uno spazio, che non deve poter essere interrotto in
fase di impaginazione del testo. Per esempio: si può scrivere 5 kg, ma non 5kg.
221.5.2 Nomi e simboli
È bene chiarire il significato di alcuni termini che riguardano la misurazione di qualcosa:
grandezza
ciò che viene misurato, come la lunghezza, la massa8 , il tempo;
unità di misura
il nome attribuito a ciò che si usa per misurare, come il metro, il kilogrammo9 , il secondo;
simbolo
il simbolo che rappresenta l’unità di misura in modo standard, come «m», «kg», «s»;
I nomi delle unità di misura si esprimono generalmente senza iniziale maiuscola, mentre i simboli
usati per rappresentarle simbolicamente vanno espressi esattamente come stabilito dagli standard,
per quanto riguarda l’uso delle lettere maiuscole o minuscole.
8
Secondo il SI, questa è la definizione corretta, mentre il «peso» è la forza applicata a un oggetto.
Secondo il SI, questa è l’unità di misura della massa, tenendo conto che i prefissi si utilizzano facendo riferimento al
grammo.
9
Stile letterario
2379
Tabella 221.7. Esempi di grandezze e unità di misura.
Grandezza
lunghezza
massa
tempo
corrente elettrica
Unità di misura
metro
kilogrammo
secondo
ampere
Simbolo
m
kg
s
A
221.5.3 Prefissi moltiplicatori
Oltre alla definizione dei simboli che esprimono le unità di misura, si aggiungono dei simboli che
rappresentano un multiplo ben preciso di tali unità. Tali simboli di moltiplicazione si pongono
davanti al simbolo di unità a cui si riferiscono; per esempio, il simbolo «km» rappresenta mille
unità «m», ovvero mille volte il metro.
I simboli che rappresentano tali moltiplicatori hanno anche un nome che normalmente si esprime senza iniziale maiuscola, indipendentemente dalla forma, maiuscola o minuscola, che ha il
simbolo stesso.
I moltiplicatori riferiti alle unità di misura hanno un significato e un valore ben preciso. È un
errore l’uso dei termini «kilo», «mega», «giga» e «tera», per rappresentare moltiplicatori pari
a 210, 220, 230 e 240, come si fa abitualmente per misurare grandezze riferite a bit o a byte.
Tabella 221.8. Prefissi del Sistema internazionale di unità (SI).
Nome
yotta
zetta
exa
peta
tera
giga
mega
kilo
hecto, etto
deca
Simbolo
Y
Z
E
P
T
G
M
k
h
da
deci
centi
milli
micro
nano
pico
femto
atto
zepto
yocto
d
c
m
µ
n
p
f
a
z
y
Valore
1024
1021
1018
1015
1012
109
106
103
102
10
1
10-1
10-2
10-3
10-6
10-9
10-12
10-15
10-18
10-21
10-24
Note
Lettera «k» minuscola.
Nessun moltiplicatore.
Stile letterario
2380
221.5.4 Prefissi per multipli binari
Lo standard IEC 60027-2 introduce un gruppo nuovo di prefissi da utilizzare in alternativa a quelli
del SI, per risolvere il problema dell’ambiguità causata dall’uso improprio dei prefissi del SI in
ambito informatico. A questo proposito, una discussione particolareggiata su questo argomento
si può trovare nel documento Standardized Units for Use in Information Technology, di Markus
Kuhn, <http://www.cl.cam.ac.uk/~mgk25/information-units.txt>.
Tabella 221.9. Prefissi IEC 60027-2.
Origine
kilobinary
megabinary
gigabinary
terabinary
petabinary
exabinary
zettabinary
yottabinary
Nome
kibi
mebi
gibi
tebi
pebi
exbi
zebi
yobi
Simbolo
Ki
Mi
Gi
Ti
Pi
Ei
Zi
Yi
Valore
210
220
230
240
250
260
270
280
Note
Si usa la «K» maiuscola.
La tabella 221.9 riporta l’elenco di questi prefissi speciali.
221.6 Rappresentazione di valori
La rappresentazione di valori numerici tende a seguire forme differenti a seconda del contesto e
delle convenzioni nazionali. Nella Guide for the Use of the International Systems of Units (SI),
pubblicato dal NIST (National institute of standards and technology), si trovano alcuni criteri per
risolvere il problema in modo non ambiguo, validi anche al di fuori della realtà inglese.
221.6.1 Valori percentuali
In generale, l’uso del simbolo ‘%’ va inteso come una forma abbreviata per 0,01 e in questo
modo va usato, senza eccedere. In particolare, il simbolo di percentuale va posto dopo un valore
numerico, staccato da questo, ma non separabile in fase di composizione tipografica:
n %
Per esempio, si può scrivere ‘x = 0,025 = 2,5 %’, mentre non è corretta la forma
‘x = 0,025 = 2,5%’.
221.6.2 Valori numerici
Nella lingua italiana, come in molte altre, si usa la virgola come segno di separazione tra la
parte intera e quella decimale, mentre nei paesi di lingua inglese, si utilizza il punto. A parte
il problema di scegliere il segno opportuno in base alle proprie convenzioni nazionali, si pone
piuttosto la difficoltà nel rappresentare numeri composti da un grande numero di cifre.
La Guide for the Use of the International Systems of Units (SI) indica un metodo molto semplice
e non equivoco: si separano le cifre a gruppi di tre, usando semplicemente uno spazio, sia prima
che dopo il marcatore decimale, come si vede in questi esempi:
123 456 789
3 456 789,012 345 6
6 789,012 3
Stile letterario
2381
Naturalmente, lo spazio in questione non può consentire l’interruzione della riga in fase di
composizione.
È ammissibile anche un’eccezione in presenza di raggruppamenti di sole quattro cifre, prima o
dopo il marcatore decimale. In quel caso si può evitare la separazione:
1234
23,2345
Un altro problema è quello della rappresentazione di valori numerici espressi con una base
maggiore di 10, per i quali si utilizzano le prime 10 cifre numeriche e per il resto si usano le
lettere alfabetiche. Queste lettere andrebbero utilizzate coerentemente, possibilmente in forma
maiuscola.
221.7 Stile tipografico
La definizione dello stile tipografico è un altro punto delicato nella definizione dello stile letterario generale. Di solito, la sua preparazione, è compito del tipografo o del coordinatore di un
gruppo di autori o traduttori.
Il modo migliore per stabilire e utilizzare uno stile tipografico è quello di usare un sistema SGML,
attraverso cui definire un DTD che non permetta alcun dubbio nella relazione che ci deve essere tra le varie componenti di un documento. In questo modo, gli autori hanno solo il compito
di qualificare correttamente le varie componenti del testo, senza pensare al risultato finale, per
modificare il quale si può semmai intervenire sul sistema di conversione successivo.
Le sezioni seguenti trattano dei problemi legati alla definizione di uno stile tipografico per la
redazione di documenti tecnico-informatici, mostrando prevalentemente esempi in SGMLtoolsLinuxDoc e a volte anche in LaTeX. L’idea è presa dalla guida di stile del gruppo di documentazione di Linux: LDP (Linux documentation project), ma le indicazioni si basano sulle
consuetudini tipografiche italiane.
221.7.1 Blocchi di testo
Scrivendo documenti che riguardano l’uso dell’elaboratore, si incorre frequentemente nella necessità di scrivere nomi, o intere parti di testo, che devono essere trattati in modo letterale. Possono essere nomi di file e directory, comandi, porzioni del contenuto di file, listati di programmi,
ecc. In questi casi è sconsigliabile l’uso di un tipo di carattere proporzionale, perché si rischierebbe di perdere delle informazioni importanti. Si pensi al trattino utilizzato nelle opzioni della
maggior parte dei comandi Unix: utilizzando un carattere proporzionale, attraverso un sistema
di composizione come LaTeX, si otterrebbe un trattino corto, mentre due trattini posti di seguito
genererebbero un trattino normale; e ancora, da tre trattini si otterrebbe un trattino largo.
Altri tipi di problemi sono dati da nomi di altro genere, come i marchi di fabbrica, e dalla necessità
di marcare dei concetti quando appaiono per la prima volta.
221.7.1.1 Nomi di file e directory
• I nomi di file, di qualunque tipo, dovrebbero essere rappresentati attraverso un tipo di
carattere a spaziatura fissa.
• I nomi di questi tipi di entità sono sensibili alla differenza tra maiuscole e minuscole.
Per questo vanno scritti sempre così come sono, anche quando si trovano all’inizio di un
periodo, senza acquisire un’eventuale iniziale maiuscola.
2382
Stile letterario
• I nomi di file eseguibili, in quanto tali, sono indicati preferibilmente senza il percorso
necessario al loro avvio.
• I nomi di programmi per i sistemi Dos dovrebbero essere indicati utilizzando lettere
maiuscole, senza tralasciare l’estensione.
221.7.1.2 Schermate, listati e simili
Il testo ottenuto da listati di vario tipo, come i pezzi di un programma sorgente, il risultato dell’elaborazione di un comando, o il contenuto di una schermata, possono essere rappresentati convenientemente attraverso un ambiente di inclusione di testo letterale a spaziatura fissa. Generalmente, con LinuxDoc si utilizza l’ambiente ‘verb’ contenuto in ‘tscreen’ (l’uso dell’ambiente
‘code’ è sconsigliabile).
Il problema sta nel fatto che l’ampiezza di tale testo non può superare i margini del corpo del
documento, in base al tipo di impaginazione finale che si ritiene dover applicare. Infatti, tale
testo non può essere continuato nella riga successiva perché ciò costituirebbe un’alterazione delle
informazioni che si vogliono mostrare.
Generalmente, non è possibile superare un’ampiezza di 80 colonne, pari a quella di uno schermo
a caratteri normale.
221.7.1.3 Variabili di ambiente
• I nomi di variabili di ambiente dovrebbero essere rappresentati attraverso un tipo di
carattere a spaziatura fissa.
• I nomi di questi tipi di entità sono sensibili alla differenza tra maiuscole e minuscole. Per
questo vanno scritti sempre così come sono, anche quando si trovano all’inizio o all’interno
di un periodo.
• A seconda del tipo di documentazione, potrebbe essere stata definita la convenzione per cui
queste debbano essere indicate sempre precedute dal simbolo dollaro (‘$’).
La scelta di rappresentare le variabili utilizzando il dollaro come prefisso è motivata dalla facilità
con cui questa può essere identificata durante la lettura del testo. Tuttavia, questa scelta potrebbe
essere discutibile, perché il dollaro non appartiene al nome della variabile e perché potrebbe
indurre il lettore a utilizzarlo sempre, anche quando negli script non si deve. Quindi, il buon
senso deve guidare nella decisione finale.
221.7.1.4 Comandi e istruzioni
A volte si ha la necessità di indicare un comando, o un’istruzione, all’interno del testo normale.
Per questo, è opportuno utilizzare un carattere a spaziatura fissa, come nel caso dei nomi di file e
directory, però qui si pone un problema nuovo dovuto alla possibile presenza di spazi e trattini.
I programmi di composizione normali tendono a interrompere le righe, quando necessario, in
corrispondenza degli spazi ed eventualmente anche dei trattini. Se il comando o l’istruzione che
si scrive è breve, è consigliabile l’utilizzo di spazi e trattini non interrompibili.10
Quando si utilizza SGML (compreso HTML), si può usare l’entità ‘&nbsp;’ per indicare uno
spazio non interrompibile, mentre se si usa solo LaTeX, è il carattere tilde (‘~’) che ha questa
funzione.
10
Naturalmente questo ha senso se poi il programma di composizione non tenta di suddividere le parole in sillabe.
Stile letterario
2383
Il problema del trattino non è semplice, perché non esiste un trattino generico non separabile,
fine a se stesso. Di trattini ne esistono di varie misure e non sempre esistono corrispondenti per
diversi tipi di programmi di composizione.
221.7.1.5 Nomi di applicativi
Quando si fa riferimento al nome di un programma si pongono due alternative: l’indicazione del
file eseguibile oppure del nome attribuito dall’autore al suo applicativo.
Per comprendere la differenza, si può pensare a Apache: il servente HTTP. Non si tratta di un
semplice eseguibile, ma di un applicativo composto da diverse parti, in cui l’eseguibile è ‘httpd’.
Nello stesso modo, nel caso di Perl (il linguaggio di programmazione), si può pensare all’applicativo in generale, composto dalle librerie e tutto ciò che serve al suo funzionamento; oppure si
può voler fare riferimento solo all’eseguibile: ‘perl’.
• I nomi di programmi applicativi dovrebbero essere indicati nello stesso modo in cui lo fa
il loro autore, rispettando l’uso delle maiuscole e delle minuscole, in qualunque posizione
del testo.
• I nomi di questi tipi di entità non dovrebbero essere evidenziati in modo particolare.
Esempi
Ghostscript è un programma molto importante.
nanoBase è un semplice applicativo per Dos.
221.7.1.6 Concetti e termini nuovi
• I concetti e i termini che non si ritengono familiari per il lettore, dovrebbero essere
evidenziati la prima volta che si presentano.
Per questo tipo di evidenziazione si utilizza un neretto oppure un corsivo. L’uso del neretto è
contrario alla tradizione dei testi italiani, in cui questo viene fatto normalmente utilizzando solo
il corsivo. Tuttavia, il neretto si presta meglio alla composizione in formati molto diversi; per
esempio si ottiene facilmente anche su un documento da visualizzare attraverso uno schermo a
caratteri.
Esempi
Questo meccanismo permette di inserire le cosiddette entità interne , con cui si possono
definire delle macro.
221.7.1.7 Termini stranieri
A volte è opportuno utilizzare termini stranieri, non tradotti. Quando si tratta di termini non ben
acquisiti nel linguaggio comune, almeno per il pubblico a cui si rivolge il documento, è opportuno
utilizzare il corsivo tutte le volte in cui il termine viene adoperato.
Un termine tecnico può essere o meno di uso comune per il pubblico di lettori a cui si rivolge:
se si tratta di un termine considerato normale per quell’ambiente, non è il caso di usare alcuna
evidenziazione.
Stile letterario
2384
221.7.1.8 Nomi proprietari e logotipi
L’indicazione di nomi che fanno riferimento a marchi di fabbrica o simili, va fatta come appare nel copyright o nella nota che fa riferimento al brevetto, rispettando l’uso delle maiuscole e
dell’eventuale punteggiatura. Si dovrebbe evitare, quindi, di prendere in considerazione un eventuale logo grafico del prodotto. Non è opportuno fare risaltare maggiormente i nomi di questo
tipo.11
All’interno del testo non è conveniente fare riferimento al detentore del copyright o del brevetto.
Eventualmente, di questo problema dovrebbero farsi carico delle note opportune all’inizio del
documento che si scrive.12
Esempi
Sistema di stampa PostScript...
Scheda SCSI Adaptec...
Unità magneto-ottica Fujitsu...
Hewlett Packard
221.7.2 Titoli
Nei testi di lingua italiana, i titoli vanno scritti come se si trattasse di testo normale, con le
particolarità seguenti:
• non viene mai posto il punto fermo finale;
• si cerca di evitare l’inserzione di altri segni di punteggiatura, a meno che ciò sia necessario
per qualche motivo;
• non si usano evidenziazioni particolari di parole o nomi come invece potrebbe avvenire nel
testo normale.
Un documento a carattere tecnico viene normalmente suddiviso in segmenti a più livelli. Per
avere maggiore facilità nella trasformazione del documento in diversi formati tipografici finali,
conviene limitare la scomposizione a un massimo di due livelli. Nel caso di LinuxDoc, significa
limitarsi a usare ‘sect’ e ‘sect1’.
221.7.2.1 Didascalie
Gli elementi che non fanno parte del flusso normale di un documento, come tabelle e figure, sono
accompagnate generalmente da un titolo e da una didascalia. Il titolo serve a identificarle, mentre
la didascalia ne descrive il contenuto.
I titoli di tabelle, figure e oggetti simili, seguono le regole dei titoli normali, mentre il testo
delle didascalie segue le regole del testo normale. Tuttavia, quando si utilizzano programmi di
composizione che permettono di abbinare solo una nota descrittiva, che funga sia da titolo che
da didascalia, occorre fare una scelta:
11
A questa regola si può aggiungere che, nel caso il nome sia scritto utilizzando solo lettere maiuscole, può essere
opportuno limitarsi a indicarlo utilizzando solo l’iniziale maiuscola, lasciando il resto in minuscolo.
12
In generale, non è indispensabile fare alcun tipo di riferimento di questo genere, se lo scopo di ciò che si scrive non
è quello di trattare espressamente di questo o quel prodotto.
Stile letterario
2385
• quando le note sono brevi, è opportuno che si comportino come i titoli, cioè non contengano
simboli di punteggiatura;
• quando sono più lunghe, si può decidere di trattarle come didascalie vere e proprie, con
tutti i simboli di punteggiatura necessari per una comprensione corretta del contenuto.
Naturalmente, la scelta fatta deve valere per tutte le descrizioni che si abbinano a questi oggetti
di un particolare documento: brevi o lunghe che siano.
221.7.2.2 Elenchi descrittivi
Gli elenchi descrittivi, come quelli che si ottengono con LinuxDoc utilizzando la struttura seguente, possono essere insidiosi, perché potrebbero tradursi in modo differente a seconda del
tipo di programma di composizione utilizzato.
<descrip>
<tag>Primo elemento</tag>
Descrizione del primo elemento,...
Bla bla bla...
</descrip>
L’elemento descrittivo dell’elenco è in pratica un titolo che introduce una parte di testo generalmente rientrata. Sotto questo aspetto, la voce descrittiva segue le regole già viste per i titoli.
Tuttavia, il problema sta nel fatto che si potrebbe essere indotti a riprendere un discorso lasciato
in sospeso quando veniva introdotto l’elenco, come nell’esempio seguente:
Bla bla bla bla...
Primo elemento
Descrizione del primo elemento,...
Bla bla bla...
Qui si riprende il discorso precedente all’elenco descrittivo.
...
Infatti, l’utilizzo dei rientri fa percepire immediatamente la conclusione dell’elenco stesso. Quando si scrive un documento che deve poter essere convertito in molti formati differenti, che quindi
potrebbe essere elaborato da programmi di composizione di vario tipo, può darsi che i rientri vengano perduti e gli elementi descrittivi dell’elenco appaiano come dei titoli veri e propri. Ma se
ciò accade, quando si ricomincia «il discorso lasciato in sospeso», sembra che questo appartenga
all’argomento dell’ultimo titolo apparso.
Bla bla bla bla...
Primo elemento
Descrizione del primo elemento,...
Bla bla bla...
Qui si riprende il discorso precedente all’elenco descrittivo.
...
Pertanto, se si vogliono utilizzare strutture di questo tipo, è consigliabile che appaiano alla fine
di una sezione, quando quello che viene dopo è un titolo di una sezione o di qualcosa di simile.
Stile letterario
2386
221.7.3 Richiami in nota
I richiami in nota (le note a piè pagina e quelle alla fine del documento) sono composti con le
stesse regole del testo normale. Quando il riferimento a una nota si trova alla fine di una parola
cui segue un segno di interpunzione, è opportuno collocare tale riferimento dopo il simbolo di
interpunzione stesso.
221.7.4 Indicizzazione
La costruzione di un indice analitico deriva dall’inserzione di riferimenti all’interno del testo,
attraverso istruzioni opportune definite dal tipo di programma usato per la composizione.
Nel caso particolare di LinuxDoc si utilizzano gli ambienti ‘nidx’ e ‘ncdx’, che vengono poi
gestiti solo nella composizione attraverso LaTeX e ignorati in tutti gli altri casi. ‘ncdx’ si usa per
i nomi tecnici (file, directory, variabili di ambiente, ecc.), mentre ‘nidx’ per tutti gli altri tipi di
riferimento.
Le voci inserite in questi riferimenti, che poi formeranno l’indice generale, vanno scelte in modo
da essere uniformi, secondo alcune regole molto semplici.
• Si utilizzano le lettere minuscole, a meno che si tratti di nomi particolari che vanno sempre
scritti in un modo prestabilito:
– i nomi proprietari vanno scritti come indicato dalla casa produttrice;
– i nomi di applicativi software vanno scritti come indicato dall’autore;
– i nomi di file e directory vanno scritti esattamente come sono, tenendo conto che i file
eseguibili vanno indicati senza percorso, mentre gli altri dovrebbero contenerlo;
– i nomi di variabili di ambiente vanno scritti esattamente come sono, prefissati dal
simbolo dollaro.
• Si utilizza solo il singolare;
I riferimenti per la generazione dell’indice analitico vanno posti preferibilmente nei luoghi opportuni, in modo da evitare inutili rimandi a pagine che non contengono ciò che si cerca. Per
esempio, la parola file potrebbe trovarsi in quasi tutte le pagine di un testo di informatica, mentre
è conveniente che l’indice analitico riporti solo le pagine in cui si parla del concetto che questa
parola rappresenta.
I nomi di programmi eseguibili e di file di dati standard dovrebbero essere inseriti nell’indice
analitico ogni volta che appaiono nel testo.
221.7.5 Riferimenti bibliografici e simili
Esiste una forma precisa e molto articolata per la stesura delle bibliografie, che corrisponde allo
standard ISO 690. A ogni modo, vale la regola generale per cui un riferimento bibliografico
deve contenere tutti i dati necessari a reperire il documento a cui si fa riferimento. In condizioni
normali, le informazioni essenziali per identificare una pubblicazione sono quelle seguenti:
• l’autore o gli autori;
• il titolo completo;
• l’editore;
Stile letterario
2387
• la data di edizione;
• l’URI (se il documento è disponibile attraverso la rete).
Generalmente è consigliabile comporre gli elenchi bibliografici indicando le opere a partire dall’autore, mettendo il titolo in testo corsivo o inclinato, separando le varie componenti di ogni
riferimento bibliografico attraverso delle virgole, come nell’esempio seguente:
Claudio Beccari, LaTeX, Guida a un sistema di editoria elettronica, Hoepli, 1991,
ISBN 88-203-1931-4
Se non si dispone di un sistema automatico per la gestione dei riferimenti bibliografici, quando
si cita un documento all’interno del testo, è bene seguire alcune regole elementari.
• I riferimenti ad altri documenti, all’interno del testo normale, vanno fatti indicando il titolo
completo, in corsivo o inclinato, aggiungendo il nome dell’autore o degli autori.
• Il titolo è separato con una virgola da un eventuale sottotitolo.
• I riferimenti a un testo già citato possono essere fatti utilizzando solo il titolo o solo l’autore,
o attraverso altri mezzi, purché si sia certi di non creare ambiguità o disagio al lettore.
Segue un esempio molto semplice di come può essere fatto un riferimento del genere all’interno
del testo normale:
Questa sezione fa riferimento a concetti contenuti in LaTeX, Guida a un sistema di
editoria elettronica, di Claudio Beccari.
221.8 Riferimenti
• Michele Dalla Silvestra, Scrittura testi per l’ILDP
• Robert Kiesling, The LDP Style Mini-HOWTO
<http://www.linux.org/docs/ldp/howto/HOWTO-INDEX/howtos.html>
• Claudio Beccari, LaTeX, Guida a un sistema di editoria elettronica, Hoepli, 1991, ISBN
88-203-1931-4
• M. Fazio, Dizionario e manuale delle unità di misura, Zanichelli
• Scienza, tecnologia e arte della stampa e della comunicazione, Arti poligrafiche europee
<http://www.apenet.it/grafica/libri/Grafica/Grafica01/indice02.html>
<http://www.apenet.it/grafica/libri/Grafica/Grafica02/indice02.html>
<http://www.apenet.it/grafica/libri/Grafica/Grafica03/indice02.html>
• Scienza, tecnologia e arte della stampa e della comunicazione: Giuseppe Orsello,
Preparazione del manoscritto, Arti Poligrafiche Europee
<http://www.apenet.it/grafica/libri/Grafica/Grafica01/1206.html>
• Marco Gaiarin, Linux Italian HOWTO
<http://www.linux.org/docs/ldp/howto/HOWTO-INDEX/howtos.html>
Stile letterario
2388
• Maurizio Pistone, Lingua italiana e altra linguistica
<http://www.freeweb.org/letteratura/pistone/linguaitaliana.html>
• Dictionnaire panlatin de l’informatique
<http://www.tele3.net/dicoinfo/_bdt.htm>
• NetGlos - The Multilingual Glossary of Internet Terminology
<http://wwli.com/translation/netglos/netglos.html>
• Amiga Translators’ Organization
<http://bilbo.di.unipi.it/~ato-it/>
• Bureau International des Poids et Mesures
<http://www.bipm.org/>
• Bureau International des Poids et Mesures, Le Système international d’unités (SI)
<http://www.bipm.org/pdf/brochure-si.pdf>
• Bureau International des Poids et Mesures, The International System of Units (SI)
(traduzione in inglese)
<http://www.bipm.org/pdf/si-brochure.pdf>
• National Institute of Standards and Technology, International System of Units (SI)
<http://physics.nist.gov/Pubs/SP330/sp330sl.pdf>
• National Institute of Standards and Technology, Guide for the Use of the International
System of Units (SI), 1995
<http://physics.nist.gov/cuu/pdf/sp811.pdf>
• Markus Kuhn, Standardized Units for Use in Information Technology, 1995
<http://www.cl.cam.ac.uk/~mgk25/information-units.txt>
• National Institute of Standards and Technology, Prefixes for binary multiples
<http://physics.nist.gov/cuu/Units/binary.html>
• Excerpts from ISO 690-2, Information and documentation -- Bibliographic references -Part 2: Electronic documents or parts thereof
<http://www.nlc-bnc.ca/iso/tc46sc9/standard/690-2e.htm>
Appunti di informatica libera 2003.01.01 --- Copyright © 2000-2003 Daniele Giacomini -- daniele @ swlibero.org
Capitolo
222
Evoluzione dell’editoria elettronica
Con il termine «editoria elettronica», si vuole fare riferimento agli strumenti utilizzabili per
produrre documentazione di buona qualità dal punto di vista tipografico. L’approccio di un
programma per l’editoria può essere fondamentalmente di due tipi:
• a formattazione visuale o WYSIWYG (What you see is what you get);1
• a composizione differita.
Nel primo caso, durante la stesura, il documento appare sullo schermo con lo stesso aspetto che
avrebbe se venisse stampato in quel momento. Nel secondo, si scrive un file di testo normale con
l’inserimento di comandi, come se si trattasse di un linguaggio di programmazione; quindi si passa alla composizione (una sorta di compilazione) attraverso la quale viene generato normalmente
il file finale pronto per essere inviato alla stampa.
Il primo tipo di composizione è decisamente più pesante sotto l’aspetto elaborativo, prestandosi
in particolare per i documenti brevi. Il secondo ha lo svantaggio di non permettere la verifica
del risultato finale fino a quando non avviene la composizione, però richiede solo l’utilizzo di un
programma normalissimo per la creazione e la modifica di file di testo, mentre solo al momento
della composizione c’è bisogno di un’elaborazione consistente. In questo senso è più adatto alla
redazione di documenti di grandi dimensioni.
Raramente si riescono a trovare programmi in grado di conciliare entrambe le esigenze. Nel
sistema operativo Dos, il programma Ventura Publisher è stato un precursore di questa doppia
filosofia: permetteva sia la formattazione visuale che differita, perché si basava su un sorgente
che poteva essere modificato con un programma di scrittura a caratteri.
222.1 Evoluzione
L’editoria elettronica non è più solo cartacea. In particolare esistono gli ipertesti, cioè documenti elettronici la cui consultazione avviene attraverso riferimenti e non in modo puramente
sequenziale.
In questo senso, se l’editoria elettronica viene vista come mezzo di documentazione generale
non più orientata a un supporto particolare, non può avere immediatamente una rappresentazione finale definitiva. Per esempio, un documento in HTML non potrà mai essere identico a un
documento stampato.
Quando si vuole produrre un documento compatibile con diversi tipi di supporti (carta, ipertesto HTML, guida interna, ecc.) non si possono avere pretese stilistiche particolari; quindi, un
programma visuale diventa quasi inutile.
A fianco di questi problemi di compatibilità, si aggiungono delle esigenze nuove, come per esempio la possibilità di estrarre dal documento elettronico determinati tipi di informazioni necessarie
ad alimentare una base di dati. In questo senso, le informazioni cercate, oltre che riconoscibili
all’interno del formato utilizzato, devono essere coerenti e complete.
Comunque, anche nell’ambito dell’editoria cartacea tradizionale, la prima esigenza che è stata sentita è quella dell’uniformità stilistica, cosa che sarebbe bene fosse controllabile anche
attraverso il sistema elettronico di composizione.
1
«Ciò che si vede è ciò che si ottiene»
2389
2390
Evoluzione dell’editoria elettronica
222.2 Codifica del testo (markup)
Il termine markup (o marcatura) deriva dall’ambiente tipografico dove è stato usato per definire le annotazioni fatte su una bozza, allo scopo di segnalare al compositore o al dattilografo il
modo con cui alcune parti del testo andavano evidenziate o corrette. A tale proposito, esiste uno
standard nella simbologia da utilizzare in questi casi, che si può trovare ancora nei libri di tipografia. Queste annotazioni simboliche possono riferirsi all’aspetto dei caratteri, all’allineamento
dei paragrafi, alle spaziature e via dicendo.
Nell’editoria elettronica, il concetto alla base del termine markup si è esteso in modo da includere
i simboli speciali, o meglio, la codifica inserita nel testo per permetterne l’elaborazione.
Volendo generalizzare, la codifica del testo è tutto ciò che ne esplicita l’interpretazione. A livello
umano, la stessa punteggiatura e certe forme di spaziatura, sono la codifica che serve a chiarire
il significato del testo, diventando parte essenziale di questo. Oggi non sarebbe comprensibile
separare concettualmente la punteggiatura dal testo, però in passato è stato così. Basta pensare ai
telegrammi, o all’apparizione di questi simboli nella storia della scrittura.
222.2.1 Linguaggio di markup
La tecnica di composizione del testo utilizzando l’inserimento di marcatori o di codici, richiede
la definizione di una serie di convenzioni, tali da definire un linguaggio di markup . Un tale
linguaggio deve specificare quale tipo di marcatura è utilizzabile, quale è richiesta, in che modo
si distingua dal testo e quale sia il suo significato.
I linguaggi di markup possono essere diversi e si distinguono due gruppi fondamentali: linguaggi
procedurali e linguaggi descrittivi.
Un linguaggio di markup procedurale serve a definire il processo da svolgere in un punto particolare del documento. È come un linguaggio di programmazione in cui si usano chiamate di
funzioni, o di procedure, per compiere le operazioni richieste. Per esempio può trattarsi di ordini
riferiti alla scrittura del testo, allo spostamento, alla definizione di margini, del salto pagina e
di tutto ciò che si rende necessario. In questo senso, un linguaggio di markup procedurale consente generalmente la definizione completa di tutto ciò che serve a stabilire l’aspetto finale del
documento stampato (o visualizzato).
Un linguaggio di markup descrittivo, al contrario, usa la codifica dei marcatori per classificare le
parti del documento, dando loro un nome. In pratica, si delimitano queste porzioni di testo e si
definisce la loro appartenenza a una categoria determinata, identificata da un nome. In tal modo,
questo tipo di linguaggio di markup non è in grado di fornire indicazioni sull’aspetto finale del
documento, in quanto il suo scopo è solo quello di definire la struttura del testo. Evidentemente
sarà compito di un’altra applicazione utilizzare le informazioni sulla struttura del testo per generare un formato finale, secondo regole e definizioni stabilite al di fuori del linguaggio descrittivo
stesso.
222.2.2 Vantaggi di un linguaggio descrittivo
Un linguaggio di markup descrittivo, nel momento in cui non si prende carico di definire l’aspetto
finale del documento, pone l’accento sul contenuto e non sull’apparenza. Questo è fondamentale
quando il «documento» viene inteso come informazione pura che possa materializzarsi in forme
molto diverse.
L’informazione «pura», in quanto tale, richiede anche che sia espressa attraverso un formato
indipendente dalle piattaforme, ma soprattutto che sia indipendente dai formati proprietari.
Evoluzione dell’editoria elettronica
2391
222.3 SGML
L’SGML è un linguaggio di markup descrittivo, definito dallo standard ISO 8879: Information
processing---Text and office systems---Standard Generalized Markup Language (SGML), (1986).
L’SGML è uno standard internazionale per la definizione di metodi di rappresentazione del testo
in forma elettronica in modo indipendente dall’hardware e dal sistema utilizzato.
222.3.1 Linguaggio descrittivo
Come accennato, l’SGML è un linguaggio di markup descrittivo. Questo permette a un documento steso secondo questo linguaggio, di essere elaborato da programmi differenti, per scopi
diversi, dove la stampa o comunque la semplice lettura testuale del contenuto sia solo uno dei
tanti possibili obiettivi da raggiungere. Si è già accennato alla possibilità di estrarre informazioni
da un documento per l’utilizzo in una base di dati e questo particolare dovrebbe essere sufficiente
per intuire il senso di tale approccio descrittivo.
222.3.2 Definizione del tipo di documento
L’SGML utilizza il concetto di «tipo di documento» e di «definizione del tipo di documento».
Per la precisione di parla di DTD, ovvero, Document type definition. In pratica, nell’ambito dell’SGML, è necessario che sia stato definito il modo in cui i vari elementi del testo possono
essere utilizzati. Ciò che non è definito, non può essere usato, ma quello che è stato definito deve
rispettare le regole stabilite.
A titolo di esempio, si può immaginare la definizione di un tipo di documento riferito alla scrittura
di lettere commerciali. La lettera deve contenere degli elementi essenziali: il mittente, uno o più
destinatari, la data, l’oggetto, il corpo, l’indicazione di colui che la firma e la sigla del dattilografo
che la scrive materialmente. Tutti questi elementi devono essere presenti, probabilmente anche
con un certo ordine (l’indicazione di chi firma deve trovarsi in fondo e non all’inizio). Inoltre,
questi elementi possono scomporsi in altri elementi più dettagliati; per esempio, l’informazione
sulla persona che firma può comporsi della qualifica, il titolo personale, il nome e il cognome. Il
DTD deve prendersi carico di definire tutto questo, stabilendo ciò che è valido e cosa invece non
lo è.
In questo modo, poi, un documento SGML può essere analizzato da un programma speciale, l’analizzatore SGML (SGML parser), per la verifica del rispetto di queste regole, prima di utilizzare
in qualunque modo questo documento.
L’SGML, assieme al DTD, garantendo l’uniformità dei documenti dello stesso tipo, consente di
uniformare i procedimenti successivi. Per tornare all’esempio precedente, da un punto di vista
di puro contenuto del testo, non dovrebbe essere importante l’ordine degli elementi che lo compongono, quando sia possibile distinguerli. Tuttavia, una lettera che inizia con la firma e finisce
con l’indicazione del destinatario, non è scritta nel modo corretto; così il DTD potrebbe essere
progettato in modo da imporre un certo ordine, a vantaggio delle elaborazioni successive.
222.3.3 Indipendenza dei dati
Nella definizione di SGML si è affermato che si tratta di uno standard indipendente dall’hardware
e dal sistema utilizzato. Questa indipendenza riguarda la rappresentazione del testo, che non può
fare affidamento su una codifica particolare.
Si pensi all’uso di lettere accentate e di simboli speciali che non possono essere rappresentati
con lo standard tradizionale dell’ASCII a 7 bit. Si pensi a cosa accadrebbe se un testo scritto
2392
Evoluzione dell’editoria elettronica
con caratteri ISO Latin 1 venisse elaborato in un sistema configurato per una codifica differente:
quei simboli e quelle lettere potrebbero risultare modificati. D’altro canto, la stessa scrittura di
determinati caratteri potrebbe essere un problema, non disponendo di una tastiera adatta.
Ecco quindi il significato dell’indipendenza dall’hardware (fondamentalmente la tastiera) e dal
sistema (principalmente la codifica dei simboli utilizzati).
Per ottenere questo risultato, l’SGML utilizza un meccanismo di sostituzione di stringhe, attraverso quelle che vengono chiamate entità, per mezzo del quale si stabilisce il rimpiazzo di tali
entità con qualcosa di adeguato, quando il documento viene elaborato.
Appunti di informatica libera 2003.01.01 --- Copyright © 2000-2003 Daniele Giacomini -- daniele @ swlibero.org
Parte xlii
Codifica
223 Introduzione alla codifica universale dei caratteri . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2394
223.1 Lettera, codifica e carattere da stampa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2394
223.2 Ambiguità nel concetto di «carattere» . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2396
223.3 Unicode e ISO 10646 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2399
223.4 Apparenza e realtà . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2403
223.5 Riferimenti . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2403
224 Esempi di codifica dei caratteri . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2405
224.1 ASCII (ISO 646) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2405
224.2 ISO 8859-n . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2407
224.3 Riferimenti . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2410
2393
Capitolo
223
Introduzione alla codifica universale dei caratteri
La codifica dei caratteri, intendendo ciò come il modo di rappresentare i simboli tipografici in
forma elettronica, diventa un problema serio nel momento in cui si esce dallo schema abituale
delle lingue di origine latina.
Nella storia dell’informatica è stata definita una quantità enorme di codifiche differenti, per adattare la limitatezza degli 8 bit tradizionali all’insieme di caratteri che serve in ogni circostanza
particolare. Inoltre, nelle situazioni in cui 8 bit non potevano bastare, sono state ideate codifiche
più complesse, attraverso l’abbinamento di sequenze di simboli elementari che ne rappresentano
uno più complesso.
In generale, verrebbe da pensare che sarebbe stato meglio prevedere subito il problema, definendo
delle unità di codifica più grandi (non più il byte, ma stringhe binarie più lunghe). Tuttavia, c’è
da considerare che proprio la semplicità dell’alfabeto inglese (che non ha nemmeno le lettere
accentate) ha permesso lo sviluppo rapido di tecnologia relativamente «semplice», che altrimenti
sarebbe stata materialmente irraggiungibile.
Il byte stesso è stata una grande conquista. Ancora oggi ci sono sistemi di comunicazione che
riconoscono unità di codifica a soli 7 bit, dove in pratica si può usare solo l’ASCII; prima ancora
sono state utilizzate anche unità di codifica a soli 6 bit.
Questo capitolo ha l’intento di raccogliere alcuni concetti legati alla codifica dei caratteri, assieme
a qualche indicazione sul funzionamento dello standard di codifica universale: Unicode o ISO
10646. Alcuni concetti che sono trattati qui, riprendono quanto già descritto in parte nel capitolo
220.
223.1 Lettera, codifica e carattere da stampa
Per comprendere il problema della codifica, è necessario considerare prima i problemi che riguardano la definizione dei caratteri da stampa. La prima fase è la definizione di un repertorio
astratto, all’interno del quale si elencano, senza un ordine preciso, le lettere e gli altri segni necessari per un certo scopo. L’insieme di questi simboli è astratto, nel senso che non è ancora
stabilito l’aspetto finale, compito riservato a una fase successiva.
Il simbolo di un repertorio astratto è qualcosa di diverso dal simbolo che compone un carattere
da stampa, dal momento che il secondo rappresenta il modo preciso in cui il simbolo astratto
viene reso tipograficamente. Per comprendere il concetto, si pensi alla lettera «a» e all’aspetto
che questo simbolo astratto può avere utilizzando stili, serie e corpi differenti. Evidentemente, si
tratta sempre della stessa lettera, ma resa in modo diverso.
Figura 223.1. La lettera «a» minuscola resa tipograficamente in modo differente.
Alcuni gruppi di simboli astratti tendono a essere rappresentati tipograficamente in un simbolo
solo, in un legato, ovvero attraverso l’avvicinamento e la sovrapposizione parziale. Il caso tipico
è rappresentato dalla sequenza di lettere «fi» e «ffi», come si vede nella figura 223.2. In certi casi,
la sequenza di lettere che si avvicina rappresenta una parola intera, generando così un «logotipo»; spesso, la loro importanza storica ha fatto sì che questi siano diventati dei simboli astratti
2394
Introduzione alla codifica universale dei caratteri
2395
autonomi. Per esempio, la parola latina «et» è diventata la e-commerciale odierna, «&»; la parola
latina «ad» è diventata la chiocciola odierna, «@».1
Figura 223.2. Il legato «fi» e «ffi».
La composizione tipografica elettronica, può avvenire attraverso la sovrapposizione di simboli
elementari differenti, senza la necessità di legarli assieme. Nelle lingue di origine latina, il caso
più comune di questa possibilità si ha con gli accenti, che potrebbero essere simboli tipografici separati da sovrapporre alle lettere a cui sono destinati. Nello stesso modo, il repertorio di
simboli astratti potrebbe essere realizzato con questo criterio; per esempio, per fare riferimento a un simbolo complesso potrebbe essere necessario indicare una sequenza di simboli astratti
elementari.
Alcune lingue hanno dei simboli che nella composizione tipografica devono cambiare forma a
seconda del contesto. Per comprendere il concetto, si può pensare a una scrittura manuale, in cui
le lettere cambiano leggermente forma a seconda di ciò che appare prima e dopo; chi conosce una
scrittura stenografica manuale, può intendere ancora meglio il problema. Ad aggravare ancora
di più il problema, l’adattamento contestuale di un simbolo potrebbe dipendere da una scelta
stilistica, in parte arbitraria.
A volte, la larghezza di un testo deve essere adattata per esigenze estetiche, come avviene nel caso
dell’allineamento simultaneo a sinistra e a destra. Nelle lingue di origine latina si ottiene questo
attraverso l’allargamento degli spazi tra le parole e tra le lettere all’interno delle parole; tuttavia,
alcune lingue richiedono degli adattamenti differenti, per esempio attraverso l’introduzione di
altri simboli appropriati.
Da quello che è stato scritto si intende che la composizione tipografica elettronica si può considerare come l’ultima fase di un processo composto da tre livelli: definizione di un repertorio
astratto di simboli; definizione di una codifica; composizione tipografica a partire dalla codifica.
repertorio astratto ----> codifica ----> composizione
La codifica non può corrispondere esattamente al repertorio astratto ideale: deve fare delle scelte.
In generale, il repertorio simbolico preso in considerazione dalla codifica è identificabile come
un insieme di punti di codifica (code point, secondo la documentazione di Unicode).
I problemi legati alla composizione tipografica che sono stati descritti, sono solo alcuni di quelli
che si incontrano. A seconda dei casi, implicano un approccio differente per ciò che riguarda la
codifica e la composizione. In breve:
1. lo stile tipografico è qualcosa che normalmente è gestito dal sistema di composizione, senza
richiedere la definizione di punti di codifica differenti;
2. il legato può essere un problema risolto a livello di composizione finale, oppure può richiedere la definizione di punti di codifica aggiuntivi, quando si tratta di legati molto importanti
o di logotipi;
3. l’adattamento contestuale richiede spesso la definizione di tanti punti di codifica quante
1
Nella nostra lingua si è perso l’uso di questo legato, che oggi si riacquisisce solo attraverso la lingua inglese, pertanto
lo si conosce solitamente solo nella sua definizione inglese: at
Introduzione alla codifica universale dei caratteri
2396
sono le varianti contestuali del simbolo astratto, specialmente se esiste un margine di scelta
da parte dell’autore;
4. l’adattamento della larghezza del testo dovrebbe essere compito del sistema di
composizione, anche quando questo implica l’inserzione di simboli speciali.
223.2 Ambiguità nel concetto di «carattere»
In informatica, il termine «carattere» ha acquisito un significato ambiguo che dipende dal contesto. Per esempio, può riferirsi a un simbolo del repertorio astratto, a un punto di codifica,
all’unità di memorizzazione (unità di codifica, o code unit), o al segno che viene ottenuto alla
fine del processo di composizione.2
Di certo non si può pretendere che si smetta di usare questa parola per passare invece a una terminologia più precisa. Tuttavia è importante rendersi conto della vastità della cosa e dei problemi
che ci stanno sotto.
Il modello di Unicode suddivide il problema della codifica in cinque livelli:
1. ACR (Abstract character repertoire)
definizione di un repertorio astratto di simboli;
2. CCS (Coded character set)
definizione di una mappa in cui si abbina un numero intero, non negativo, a ogni simbolo
del repertorio astratto che si intende gestire;
3. CEF (Character encoding form)
definizione di una mappa in cui si abbinano i numeri ottenuti dal livello precedente a un
insieme di sequenze dell’unità di codifica prescelta;
4. CES (Character encoding scheme)
definizione di una mappa di trasformazione delle unità di codifica in una sequenza seriale
di byte;
5. TES (Transfer encoding syntax)
definizione di un metodo reversibile di trasformazione dei dati codificati in base alle
limitazioni del mezzo trasmissivo.
Da un punto di vista leggermente differente, si potrebbe scomporre il problema in strati, per
distinguere le fasi che vanno dalla scrittura alla trasmissione del testo e dalla ricezione del testo
alla lettura. La scrittura potrebbe essere descritta con l’elenco di operazioni seguenti:
1. selezioni dei simboli e digitazione attraverso la tastiera (o un altro mezzo);
2. codifica, attraverso cui si trasforma il simbolo in un numero intero non negativo;
3. trasformazione in unità di codifica, in base alla forma prescelta;
4. adattamento in sequenze di byte;
5. adattamento prima del trasferimento dei dati.
2
Per fare un esempio in merito all’unità di codifica, basta pensare al byte, che spesso viene confuso con il carattere,
mentre ormai è da intendersi come un’unità di memorizzazione troppo piccola per questo scopo nel sistema globale.
Introduzione alla codifica universale dei caratteri
2397
Il processo di lettura dei dati, a partire dalla ricezione, è opposto:
1. interpretazione dei dati ricevuti e ricostruzione delle sequenze di byte di partenza;
2. trasformazione delle sequenze di byte in sequenze di unità di codifica;
3. trasformazione dalle sequenze di unità di codifica in numeri interi non negativi;
4. decodifica dei numeri interi non negativi;
5. composizione tipografica (su schermo o su carta).
Prima di questa sezione è già stato affrontato il problema dell’abbinamento tra il repertorio astratto di simboli e la codifica, senza precisare in che modo sia organizzata questa ultima. Nelle
sezioni seguenti si accenna alle problematiche successive.
223.2.1 CCS: insieme di caratteri codificato
L’insieme di caratteri codificato è in pratica il repertorio simbolico disponibile effettivamente,
ottenuto dopo la definizione di un repertorio astratto e dopo lo studio dei problemi legati alla cultura e alle consuetudini del linguaggio per il quale è stato realizzato. Questo insieme di caratteri
abbina un numero intero a ogni simbolo, senza bisogno che ci sia continuità nella sequenza di
tale valore (l’unica limitazione è quella per cui deve trattarsi di un valore non negativo).
Il numero che rappresenta il simbolo di un insieme di caratteri codificato, è il punto di codifica.
Nella documentazione tecnica si fa spesso riferimento al concetto di «insieme di caratteri», ovvero character set, per intendere quello che qui si indica come «insieme di caratteri
codificato», ovvero CCS, Coded character set.
Alcuni esempi tradizionali di insiemi di caratteri codificati sono:
• ASCII (ISO 646)
127 punti di codifica;
• ISO 8859-1
i primi 127 punti di codifica sono uguali all’ASCII;
• ISO 8859-2
i primi 127 punti di codifica sono uguali all’ASCII, mentre nella parte restante il repertorio
dei simboli è diverso dall’ISO 8859-1.
Alcuni insiemi di caratteri codificati prevedono l’abbinamento con una descrizione (in inglese), allo scopo di facilitarne l’identificazione. Si utilizza questa descrizione per evitare ambiguità nell’identificazione del simbolo, quando questo potrebbe essere confuso con un altro, o più
semplicemente quando potrebbe essere male interpretato.
Per rappresentare un punto di codifica, basta indicare il suo numero intero (qualunque sia la
sua base di numerazione). Di solito, per evitare ambiguità, quando si tratta di Unicode o di ISO
10646, si fa uso normalmente della forma ‘U+n n n n ’, oppure ‘U-nn n n n n n n ’, dove n è una
2398
Introduzione alla codifica universale dei caratteri
cifra esadecimale. Evidentemente, la seconda forma è utile per individuare punti di codifica più
grandi.3
Tuttavia, in questo documento si preferisce l’uso di una forma differente, mediata dall’XML,
‘#xn ’, dove n rappresenta una o più cifre esadecimali in base alla necessità.
In questa fase della scomposizione del problema della codifica, il «carattere» è il numero intero
che rappresenta il punto di codifica. Attraverso un linguaggio di programmazione che sia adeguato al problema della codifica universale, il tipo di dati carattere deve corrispondere a un intero
senza segno per il quale non ci si pone il problema del limite (anche se in questo momento dovrebbe essere almeno un intero a 32 bit); di conseguenza, il tipo stringa dovrebbe essere un array
del tipo carattere.
223.2.2 CEF: forma codificata del carattere
La forma codificata del carattere è il risultato di una trasformazione dal numero intero non negativo che costituisce il livello precedente, in una sequenza di unità di codifica. L’unità di codifica
è un raggruppamento di bit di una lunghezza opportuna.
La sequenza di unità di codifica non è composta necessariamente dalla stessa quantità di queste
unità per tutti gli elementi dell’insieme di caratteri. A questo proposito, si distingue tra forme
codificate del carattere a lunghezza fissa e a lunghezza variabile.
L’esempio più semplice di forma codificata del carattere a lunghezza fissa è dato dall’ASCII
tradizionale: l’insieme di caratteri codificato è costituito da 128 punti di codifica, rappresentati
da tutti gli interi che vanno da 0 a 127. L’unità di codifica utilizzata in questa situazione è un
gruppo singolo di 7 bit con i quali si rappresenta lo stesso numero intero.
Il caso più comune di forma codificata del carattere a lunghezza variabile è dato dall’UTF-8, che
utilizza un’unità di codifica di un ottetto (un byte), in cui i punti di codifica con valori tra 0 e 127
(da 0016 a 7F16) utilizzano una sola unità di codifica, mentre tutti gli altri ne utilizzano più di una.
In fase di interpretazione delle sequenze di unità di codifica si possono presentare i casi seguenti:
1. la sequenza potrebbe non essere valida, perché incompleta, o perché esclusa esplicitamente;
2. la sequenza potrebbe fare riferimento a un punto di codifica possibile ma non ancora
assegnato a un simbolo;
3. la sequenza potrebbe corrispondere a un punto di codifica assegnato a un simbolo stabilito,
oppure lasciato all’attribuzione libera senza un vincolo preciso.
Il problema delle sequenze incomplete si intende nel momento in cui si accetta il fatto che un
forma di codifica possa prevedere una lunghezza variabile delle sequenze di unità di codifica.
Il caso dei punti di codifica lasciati al libero arbitrio degli utilizzatori, è una particolarità della
codifica universale (Unicode e ISO 10646); se ne può comprendere la necessità di fronte a un
sistema di codifica che vuole essere completo, ma che in pratica è appena all’inizio della sua
opera di catalogazione.
A questo livello della scomposizione del problema, il «carattere» è ciò che idealmente è scritto
in un «file di testo» (non più solo un «file ASCII»). Anche se è stato stabilito in che modo è organizzato l’insieme di caratteri codificato, la sua rappresentazione binaria «ideale» nel file di testo
3
Per la precisione, questa notazione è la rappresentazione delle codifiche UCS-2 e UCS-4 a cui non si intende fare
riferimento direttamente. In generale, non c’è alcun bisogno di rappresentare un punto di codifica in questo modo; tuttavia,
si tratta di una simbologia immediata che dovrebbe semplificare la lettura e la comprensione del testo.
Introduzione alla codifica universale dei caratteri
2399
dipende dalla forma prescelta. Qui si parla di rappresentazione ideale, perché la rappresentazione
reale dipende dal livello successivo, in cui tutto viene tradotto a livello di byte.
223.2.3 CES: schema di codifica del carattere
Lo schema di codifica del carattere è un sistema di trasformazione attraverso il quale, le unità di
codifica vengono rese in sequenze di byte messe in serie.
Per tornare all’esempio dell’ASCII, l’unità di codifica è di 7 bit, ma il «carattere» ASCII si
gestisce in pratica all’interno di un byte, dove il bit più significativo viene lasciato azzerato.
In generale, il byte è un’unità di memorizzazione standard in tutte le architetture dei sistemi
elaborativi e in tutti i sistemi di trasmissione dati. Questo spiega la necessità di trasferire tutto a
livello di byte o di multipli di questa unità.
Dovendo utilizzare più byte per rappresentare un oggetto unico, si pone il problema dello scambio
tra coppie di byte che avviene in alcune architetture. Come è noto, si distingue tra big-endian,
in cui il primo byte è quello più significativo, e little-endian, in cui il primo byte è quello meno
significativo. Pertanto, in questa situazione, si impone la necessità di specificare l’ordine dei byte.
223.2.4 TES: sintassi di codifica per il trasferimento
La sintassi di codifica per il trasferimento è un metodo di trasformazione reversibile di una
codifica, che si deve attuare a causa di qualche tipo di esigenza. Per esempio:
• la necessità di evitare l’utilizzo di alcuni valori nei byte che potrebbero confondere un
sistema di comunicazione o di memorizzazione;
• la necessità di ridurre la dimensione dei dati utilizzando algoritmi di compressione.
Mentre il secondo caso dovrebbe essere chiaro, per comprendere il primo basta pensare alle limitazioni che ha storicamente il protocollo SMTP (posta elettronica), per cui è necessario evitare
di trasmettere byte in cui il primo bit sia diverso da zero.
223.3 Unicode e ISO 10646
Il lavoro per la realizzazione del sistema di codifica universale non può partire da zero, per l’esigenza di mantenere qualche forma di compatibilità con il passato (diversamente, non verrebbe
nemmeno preso in considerazione). Pertanto, le incongruenze che si possono rilevare sono dovute principalmente a questo motivo: la necessità di riutilizzare gli insiemi di caratteri codificati
più importanti che erano già esistenti.
Unicode e ISO 10646 sono due standard compatibili reciprocamente che definiscono un insieme
di caratteri codificato particolarmente grande, che poi deve essere trasformato nella forma codificata del carattere prescelta per la sua rappresentazione pratica in unità di codifica. Pertanto,
quando di parla di Unicode, o di ISO 10646, senza specificare altro, si pensa generalmente ai
punti di codifica e non alla rappresentazione finale.4
I primi punti di codifica di questi standard corrispondono esattamente all’ISO 8859-1. Per esempio: #x20 è lo spazio normale; #xA0 è lo spazio non interrompibile; #xAB sono le virgolette
angolari aperte; #xBB sono le virgolette angolari chiuse.
4
In generale, per maggiore chiarezza, i punti di codifica dell’Unicode e di ISO 10646 si indicano nella forma
‘U+n nn n ’, oppure ‘U-nn n n n n nn ’, dove n è una cifra esadecimale; ma come è già stato mostrato, qui si userà la
notazione ‘#xn ’ dell’XML.
Introduzione alla codifica universale dei caratteri
2400
Attualmente, la codifica universale utilizza principalmente tre forme codificate del carattere UTF
(Unicode transformation format): UTF-8, UTF-16 e UTF-32. Ogni forma codificata del carattere
del tipo UTF-n rappresenta un punto di codifica come una sequenza di una o più unità di codifica
(che a sua volta occupa n bit), ottenuta attraverso una trasformazione reversibile del valore.
Con questo sistema, i punti di codifica che possono essere rappresentati vanno teoricamente da
#x0 a #x7FFFFFFF (in particolare, secondo Unicode si arriva solo fino a #x10FFFF), salvo alcuni
valori che sono stati esclusi espressamente. I punti di codifica esclusi più importanti sono #xFFFE
e #xFFFF.
Le forme codificate del carattere che utilizzano le unità di codifica più piccole, richiedono l’uso
di sequenze multiple di tali unità con maggiore frequenza. Per esempio, si può osservare il caso
di UTF-8, in cui l’unità di codifica è il byte (un ottetto): mano a mano che il valore del punto di
codifica cresce, è necessario utilizzare più unità di codifica per la sua rappresentazione.
È necessario sottolineare il fatto che i valori che compongono l’insieme dei punti di codifica,
non vengono trasferiti tali e quali nella forma codificata, dal momento che ci possono essere
delle limitazioni nella rappresentazione.
Allo stato attuale dello sviluppo della codifica universale, le varie forme codificate del carattere
possono utilizzare gli spazi seguenti:
• UTF-8
da uno a sei unità di codifica da 8 bit (mentre secondo Unicode, che è più restrittivo dello
standard ISO 10646, si hanno al massimo quattro unità);
• UTF-16
da uno a due unità di codifica da 16 bit;
• UTF-32
attualmente si prevede una sola unità di codifica da 32 bit.
223.3.1 UTF-8
UTF sta per Unicode transformation format e significa implicitamente che si tratta di una mappa
di trasformazione da punti di codifica Unicode a unità di codifica (è già stato descritto il fatto che
il numero che segue la sigla UTF-n indica la dimensione in bit dell’unità di codifica).
In particolare, vale la pena di osservare un po’ meglio UTF-8, che è il cardine della transizione
verso la codifica universale nei sistemi operativi in cui non è conveniente l’utilizzo di unità di
codifica più grandi. In effetti, UTF-8 è un sistema molto complesso per rappresentare simboli di
qualunque lingua diversa dall’inglese, perché richiede spesso l’utilizzo di più unità per un solo
simbolo.
Le caratteristiche di UTF-8 sono le seguenti:
• i punti di codifica da #x0 a #x7F, corrispondenti in pratica all’ASCII, sono tradotti
semplicemente in byte da 0016 a 7F16, esattamente come si fa già con l’ASCII stesso;
• i punti di codifica che vanno da #x80 in su, vengono tradotti in sequenze multiple di byte,
ognuno dei quali ha il bit più significativo a uno, così da evitare che i byte da 0016 a 7F16
possano apparire all’interno delle sequenze multiple;
Introduzione alla codifica universale dei caratteri
2401
• il primo byte di una sequenza multipla che rappresenta un punto di codifica che vada da
#x80 in su, contiene sempre valori nell’intervallo da C016 a FD16 e serve a indicare quanti
byte vengono utilizzati per rappresentare il carattere;
• i byte di una sequenza multipla che sono successivi al primo contengono valori che vanno
da 8016 a BF16;
• si possono definire sequenze di byte in numero massimo di sei;
• i valori FE16 e FF16 non sono mai usati.
La tabella 223.1 dovrebbe chiarire meglio il concetto, abbinando i valori dei punti di codifica
Unicode alle sequenze di byte con cui possono essere rappresentati. Si osservi che la lettera x
serve a indicare un bit variabile.
Tabella 223.1. Sequenze multi-byte teoriche nell’UTF-8.
da
#x0
#x80
#x800
#x10000
#x200000
#x4000000
a
#x7F
#x7FF
#xFFFF
#x1FFFFF
#x3FFFFFF
#x7FFFFFFF
sequenze di ottetti
0xxxxxx x
110xx xxx 10xxxx x x
1110xx xx 10xxx x xx 10x xx xx x
11110xxx 10xx x xx x 10xx xx x x 10xx x xx x
111110x x 10x x xx x x 10xxx xx x 10x xx x xx 10xx xx xx
1111110x 10x xxx x x 10xx xx x x 10xx x xx x 10xxx xx x 10x xx x xx
Un esempio dovrebbe chiarire ancora meglio il meccanismo. La lettera accentata «è» si rappresenta attraverso il punto di codifica #xE8, che in pratica si può rendere in binario come
1110 10002, si traduce in UTF-8 come si vede nella figura 223.3.
Figura 223.3. #xE8 in UTF-8.
1110 1000
|
| si scinde a gruppi di sei bit
V
11 101000
|
| si inseriscono i bit iniziali secondo lo schema di UTF-8
V
110000 11 10 101000
primo
secondo
ottetto
ottetto
1100 0011 1010 1000
0xc3
0xa8
Un altro esempio interessante è il punto di codifica #xFEFF (1111 1110 1111 11112); lo si vede
nella figura 223.4.
Figura 223.4. #xFEFF in UTF-8.
1111 1110 1111 1111
|
| si scinde a gruppi di sei bit
V
1111 111011 111111
|
| si inseriscono i bit iniziali secondo lo schema di UTF-8
V
1110 1111 10 111011 10 111111
primo
secondo
terzo
ottetto
ottetto
ottetto
1110 1111 1011 1011 1011 1111
0xef
0xbb
0xbf
Introduzione alla codifica universale dei caratteri
2402
Da questo si dovrebbe intendere il passaggio a un numero superiore di byte.
In base al modello di UTF-8, si potrebbero realizzare anche sequenze più lunghe del necessario
per rappresentare un punto di codifica. Evidentemente, è compito del software che le genera
evitare di sprecare dello spazio inutilmente.
223.3.2 Schema di codifica e firma di riconoscimento
Di fronte a diverse forme codificate del carattere UTF c’è la necessità di poterle identificare
facilmente. Per questo si utilizza una sorta di firma iniziale, costituita in pratica dal punto di
codifica #xFEFF, che quando viene trasformato in base allo schema di codifica del carattere,
permette anche di controllare se l’ordine dei byte è normale o è stato invertito.
Il punto di codifica #xFEFF viene anche identificato con il nome ZWNBSP, ovvero Zero width
no-break space; tuttavia, anche se si intende che si tratta di qualcosa di «innoquo» (uno spazio
non interrompibile di ampiezza nulla), se è stato inserito come firma iniziale, non va inteso come
parte del testo. Questo significa, che i programmi per la gestione di file di testo devono tenere conto che la firma iniziale va tolta prima di fare qualunque elaborazione (si pensi al concatenamento
con un comando ‘cat’ o simile).
Gli schemi di codifica del carattere riferiti alle forme codificate UTF, si possono precisare aggiungendo delle sigle alla fine del nome UTF-n . La tabella 223.2 mostra gli schemi di codifica
UTF-n *, assieme alla firma iniziale (quando questa è prevista).
Tabella 223.2. Schemi di codifica UTF-n .
Schema
UTF-8
UTF-8N
UTF-16
UTF-16
UTF-16
UTF-16BE
UTF-16LE
UTF-32
UTF-32
UTF-32
UTF-32BE
UTF-32LE
Firma iniziale
EFBBBF16
FEFF16
FFFE16
0000FEFF16
FFFE000016
Note
In condizioni normali è prevista la firma iniziale.
Si indica esplicitamente l’assenza della firma.
UTF-16 big-endian in modo predefinito.
UTF-16 big-endian.
UTF-16 little-endian.
UTF-16 big-endian senza firma.
UTF-16 little-endian senza firma.
UTF-32 big-endian in modo predefinito.
UTF-32 big-endian.
UTF-32 little-endian.
UTF-32 big-endian senza firma.
UTF-32 little-endian senza firma.
223.3.3 Tipi di dati nuovi
Si è già accennato al modo in cui un linguaggio di programmazione può gestire i punti di codifica
di questo tipo. Tuttavia, non si può dimenticare il passato; così, in tutte le situazioni in cui il
«carattere» è implicitamente un intero senza segno a 8 bit, è necessario usare un’altra definizione
per i punti di codifica: il carattere esteso, ovvero wide char. Nello stesso modo, dovendo parlare
di stringhe, se c’è bisogno di chiarire che si tratta di una stringa secondo Unicode o ISO 10646,
si parla di stringa estesa, ovvero di wide string.
Introduzione alla codifica universale dei caratteri
2403
223.4 Apparenza e realtà
La disponibilità di un sistema di codifica che faccia riferimento a un repertorio simbolico molto
ampio, risolve tanti problemi del passato in cui era necessario risparmiare. Per esempio, nell’ASCII tradizionale, il trattino è unico (non si distingue la sua lunghezza) ed è anche un segno
«meno». Disponendo di un repertorio molto grande, diventa importante utilizzare il simbolo giusto in base al contesto. Per esempio, la lettera latina «A» maiuscola, è diversa dalla lettera greca
alfa maiuscola, anche se i due simboli possono avere lo stesso aspetto.
La descrizione che viene abbinata ai punti di codifica serve proprio per questo, in modo da evitare
confusione.
Per fare un esempio più convincente, si pensi alla lettera «ß» nell’insieme ISO 8859-1. Il nome
abbinato a questa lettera è «LATIN SMALL LETTER SHARP S»; come si legge non si tratta
della lettera greca beta, ma di qualcosa di diverso. Per la precisione è un legato che si usa nella
lingua tedesca; in mancanza del segno tipografico può essere reso come «ss» (infatti si tratta di
una lettera minuscola). Utilizzare questo simbolo al posto della lettera beta sarebbe un errore;
infatti, un sistema di composizione o di lettura, potrebbe anche decidere di convertire il segno
nella forma semplificata che è appena stata mostrata.
223.5 Riferimenti
• Jukka Korpela, A tutorial on character code issue
<http://www.hut.fi/~jkorpela/chars.html>
• Unicode Home Page
<http://www.unicode.org/>
• Mark Davis, Draft Unicode FAQ
<http://www.unicode.org/unicode/faq/>
• Ken Whistler, Mark Davis, Unicode Technical Report #17, Character Encoding Model
<http://www.unicode.org/unicode/reports/tr17/>
• Mark Davis, Forms of Unicode
<http://www.ibm.com/developerworks/library/utfencodingforms/>
• C. Weider, C. Preston, K. Simonsen, H. Alvestrand, R. Atkinson, M. Crispin, P. Svanberg,
RFC 2130: The Report of the IAB Character Set Workshop held 29 February - 1 March,
1996
<http://www.cis.ohio-state.edu/cgi-bin/rfc/rfc2130.html>
<http://www.cis.ohio-state.edu/cs/Services/rfc/rfc-text/rfc2130.txt>
• Markus Kuhn, UTF-8 and Unicode FAQ for UNIX/Linux
<http://www.cl.cam.ac.uk/~mgk25/unicode.html>
• Bruno Haible, The Unicode HOWTO
<ftp://ftp.ilog.fr/pub/Users/haible/utf8/Unicode-HOWTO.html>
• D. Goldsmith, M. Davis, RFC 2152: UTF-7, a mail-safe transformation format of Unicode,
1997
<http://www.cis.ohio-state.edu/cgi-bin/rfc/rfc2152.html>
<http://www.cis.ohio-state.edu/cs/Services/rfc/rfc-text/rfc2152.txt>
Introduzione alla codifica universale dei caratteri
2404
• F. Yergeau, RFC 2279: UTF-8, a transformation format of ISO 10646, 1998
<http://www.cis.ohio-state.edu/cgi-bin/rfc/rfc2279.html>
<http://www.cis.ohio-state.edu/cs/Services/rfc/rfc-text/rfc2279.txt>
• Indrek Hein, An online character database
<http://www.eki.ee/letter/>
Appunti di informatica libera 2003.01.01 --- Copyright © 2000-2003 Daniele Giacomini -- daniele @ swlibero.org
Capitolo
224
Esempi di codifica dei caratteri
In questo capitolo si raccolgono le descrizioni di alcuni esempi di insiemi di caratteri codificati e
di forme codificate del carattere tradizionali. È il caso di ricordare che nella sezione 342.1.1 viene
descritto il funzionamento del programma di servizio ‘recode’, specializzato nella conversione
dei file di testo.
224.1 ASCII (ISO 646)
L’ASCII è una codifica molto semplice, in cui ogni punto di codifica corrisponde direttamente
a un gruppo di 7 bit, inteso come un intero senza segno, senza bisogno di trasformazioni. Sulla
base di questa codifica si sono sviluppate molte varianti, soprattutto a 8 bit. Tuttavia, oggi, quando si parla di ASCII si tende a fare riferimento prevalentemente allo standard originale, in cui
si utilizzavano valori compresi tra 0 e 127, per rappresentare i quali bastano solo 7 bit. Eventualmente, volendo essere precisi, per fare riferimento all’ASCII tradizionale si può utilizzare la
denominazione «US-ASCII».
L’ASCII non si occupa solo di definire la codifica dei segni tipografici, ma include anche dei
codici di controllo, ai quali abbina un nome, ma senza potervi attribuire un significato univoco
valido in tutti i contesti. Si tratta dei punti di codifica da 0 a 31 e del 127 in decimale (il punto di
codifica 32 rappresenta lo spazio normale).
La tabella 224.1 mostra nel dettaglio la codifica ASCII.
Tabella 224.1. US-ASCII (ISO 646).
Binario
000000002
000000012
000000102
000000112
000001002
000001012
000001102
000001112
000010002
000010012
000010102
000010112
000011002
000011012
000011102
000011112
000100002
000100012
000100102
000100112
000101002
000101012
000101102
000101112
000110002
000110012
000110102
000110112
000111002
Esadecimale
0016
0116
0216
0316
0416
0516
0616
0716
0816
0916
0A16
0B16
0C16
0D16
0E16
0F16
1016
1116
1216
1316
1416
1516
1616
1716
1816
1916
1A16
1B16
1C16
Ottale
0008
0018
0028
0038
0048
0058
0068
0078
0108
0118
0128
0138
0148
0158
0168
0178
0208
0218
0228
0238
0248
0258
0268
0278
0308
0318
0328
0338
0348
2405
Decimale
00010
00110
00210
00310
00410
00510
00610
00710
00810
00910
01010
01110
01210
01310
01410
01510
01610
01710
01810
01910
02010
02110
02210
02310
02410
02510
02610
02710
02810
Carattere
<NUL>
<SOH>
<STX>
<ETX>
<EOT>
<ENQ>
<ACK>
<BEL>
<BS>
<HT>
<LF>
<VT>
<FF>
<CR>
<SO>
<SI>
<DLE>
<DC1>
<DC2>
<DC3>
<DC4>
<NAK>
<SYN>
<ETB>
<CAN>
<EM>
<SUB>
<ESC>
<FS>
\0
\a
\b
\t
\n
\v
\f
\r
Esempi di codifica dei caratteri
2406
Binario
000111012
000111102
000111112
001000002
001000012
001000102
001000112
001001002
001001012
001001102
001001112
001010002
001010012
001010102
001010112
001011002
001011012
001011102
001011112
001100002
001100012
001100102
001100112
001101002
001101012
001101102
001101112
001110002
001110012
001110102
001110112
001111002
001111012
001111102
001111112
010000002
010000012
010000102
010000112
010001002
010001012
010001102
010001112
010010002
010010012
010010102
010010112
010011002
010011012
010011102
010011112
010100002
010100012
010100102
010100112
010101002
010101012
Esadecimale
1D16
1E16
1F16
2016
2116
2216
2316
2416
2516
2616
2716
2816
2916
2A16
2B16
2C16
2D16
2E16
2F16
3016
3116
3216
3316
3416
3516
3616
3716
3816
3916
3A16
3B16
3C16
3D16
3E16
3F16
4016
4116
4216
4316
4416
4516
4616
4716
4816
4916
4A16
4B16
4C16
4D16
4E16
4F16
5016
5116
5216
5316
5416
5516
Ottale
0358
0368
0378
0408
0418
0428
0438
0448
0458
0468
0478
0508
0518
0528
0538
0548
0558
0568
0578
0608
0618
0628
0638
0648
0658
0668
0678
0708
0718
0728
0738
0748
0758
0768
0778
1008
1018
1028
1038
1048
1058
1068
1078
1108
1118
1128
1138
1148
1158
1168
1178
1208
1218
1228
1238
1248
1258
Decimale
02910
03010
03110
03210
03310
03410
03510
03610
03710
03810
03910
04010
04110
04210
04310
04410
04510
04610
04710
04810
04910
05010
05110
05210
05310
05410
05510
05610
05710
05810
05910
06010
06110
06210
06310
06410
06510
06610
06710
06810
06910
07010
07110
07210
07310
07410
07510
07610
07710
07810
07910
08010
08110
08210
08310
08410
08510
Carattere
<GS>
<RS>
<US>
<SP>
!
"
#
$
%
&
’
(
)
*
+
,
.
/
0
1
2
3
4
5
6
7
8
9
:
;
<
=
>
?
@
A
B
C
D
E
F
G
H
I
J
K
L
M
N
O
P
S
R
S
T
U
Esempi di codifica dei caratteri
Binario
010101102
010101112
010110002
010110012
010110102
010110112
010111002
010111012
010111102
010111112
011000002
011000012
011000102
011000112
011001002
011001012
011001102
011001112
011010002
011010012
011010102
011010112
011011002
011011012
011011102
011011112
011100002
011100012
011100102
011100112
011101002
011101012
011101102
011101112
011110002
011110012
011110102
011110112
011111002
011111012
011111102
011111112
Esadecimale
5616
5716
5816
5916
5A16
5B16
5C16
5D16
5E16
5F16
6016
6116
6216
6316
6416
6516
6616
6716
6816
6916
6A16
6B16
6C16
6D16
6E16
6F16
7016
7116
7216
7316
7416
7516
7616
7716
7816
7916
7A16
7B16
7C16
7D16
7E16
7F16
2407
Ottale
1268
1278
1308
1318
1328
1338
1348
1358
1368
1378
1408
1418
1428
1438
1448
1458
1468
1478
1508
1518
1528
1538
1548
1558
1568
1578
1608
1618
1628
1638
1648
1658
1668
1678
1708
1718
1728
1738
1748
1758
1768
1778
Decimale
08610
08710
08810
08910
09010
09110
09210
09310
09410
09510
09610
09710
09810
09910
10010
10110
10210
10310
10410
10510
10610
10710
10810
10910
11010
11110
11210
11310
11410
11510
11610
11710
11810
11910
12010
12110
12210
12310
12410
12510
12610
12710
Carattere
V
W
X
Y
Z
[
\
]
^
_
‘
a
b
c
d
e
f
g
h
i
j
k
l
m
n
o
p
q
r
s
t
u
v
w
x
y
z
{
|
}
~
\\
<DEL>
224.2 ISO 8859-n
Le codifiche ISO 8859-n , dove n è un numero da 1 a 15, rappresentano per il passato l’evoluzione
più coerente dell’ASCII, in quanto utilizzano tutte gli stessi punti di codifica iniziali da 0 a 127,
corrispondenti esattamente all’ASCII originale.
Come nel caso dell’ASCII, non c’è distinzione tra punto di codifica e forma codificata del
carattere; in questa situazione si usano valori fino a 255, attraverso un byte intero.
Le codifiche ISO 8859-n introducono altri codici di controllo, nell’intervallo di punti di codifica
che va da 128 a 159.
Esempi di codifica dei caratteri
2408
Per quanto riguarda le lingue occidentali, la codifica ISO 8859 più comune è ISO 8859-1, conosciuta anche come ISO Latin 1, che comunque, nel prossimo futuro potrebbe essere sostituita da
ISO 8859-15 (ISO Latin 9), in cui si inserisce il simbolo dell’Euro al posto del simbolo di valuta
generico.
La tabella 224.2 mostra nel dettaglio la codifica ISO 8859-1. Si tenga presente che nel caso di
ISO 8859-15, il punto di codifica 164 viene abbinato al simbolo dell’Euro.
Tabella 224.2. ISO 8859-1.
Ottale
2408
2418
2428
2438
2448
2458
2468
2478
2508
2518
2528
2538
2548
2558
2568
2578
2608
2618
2628
2638
2648
2658
2668
2678
2708
2718
2728
2738
2748
2758
2768
2778
3008
3018
3028
3038
3048
3058
3068
3078
3108
3118
3128
3138
3148
3158
Decimale
16010
16110
16210
16310
16410
16510
16610
16710
16810
16910
17010
17110
17210
17310
17410
17510
17610
17710
17810
17910
18010
18110
18210
18310
18410
18510
18610
18710
18810
18910
19010
19110
19210
19310
19410
19510
19610
19710
19810
19910
20010
20110
20210
20310
20410
20510
Esadecimale
A016
A116
A216
A316
A416
A516
A616
A716
A816
A916
AA16
AB16
AC16
AD16
AE16
AF16
B016
B116
B216
B316
B416
B516
B616
B716
B816
B916
BA16
BB16
BC16
BD16
BE16
BF16
C016
C116
C216
C316
C416
C516
C616
C716
C816
C916
CA16
CB16
CC16
CD16
Carattere
¡
¢
£
¤
¥
¦
§
ĺ
©
ª
«
¬
®
¯
°
±
2
3
’
µ
¶
.
¸
1
º
»
¼
½
¾
¿
À
Á
Â
Ã
Ä
Å
Æ
Ç
È
É
Ê
Ë
Ì
Í
Denominazione in inglese
NO-BREAK SPACE
INVERTED EXCLAMATION MARK
CENT SIGN
POUND SIGN
CURRENCY SIGN
YEN SIGN
BROKEN BAR
SECTION SIGN
DIAERESIS
COPYRIGHT SIGN
FEMININE ORDINAL INDICATOR
LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
NOT SIGN
SOFT HYPHEN
REGISTERED SIGN
MACRON
DEGREE SIGN
PLUS-MINUS SIGN
SUPERSCRIPT TWO
SUPERSCRIPT THREE
ACUTE ACCENT
MICRO SIGN
PILCROW SIGN
MIDDLE DOT
CEDILLA
SUPERSCRIPT ONE
MASCULINE ORDINAL INDICATOR
RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
VULGAR FRACTION ONE QUARTER
VULGAR FRACTION ONE HALF
VULGAR FRACTION THREE QUARTERS
INVERTED QUESTION MARK
LATIN CAPITAL LETTER A WITH GRAVE
LATIN CAPITAL LETTER A WITH ACUTE
LATIN CAPITAL LETTER A WITH CIRCUMFLEX
LATIN CAPITAL LETTER A WITH TILDE
LATIN CAPITAL LETTER A WITH DIAERESIS
LATIN CAPITAL LETTER A WITH RING ABOVE
LATIN CAPITAL LETTER AE
LATIN CAPITAL LETTER C WITH CEDILLA
LATIN CAPITAL LETTER E WITH GRAVE
LATIN CAPITAL LETTER E WITH ACUTE
LATIN CAPITAL LETTER E WITH CIRCUMFLEX
LATIN CAPITAL LETTER E WITH DIAERESIS
LATIN CAPITAL LETTER I WITH GRAVE
LATIN CAPITAL LETTER I WITH ACUTE
Esempi di codifica dei caratteri
Ottale
3168
3178
3208
3218
3228
3238
3248
3258
3268
3278
3308
3318
3328
3338
3348
3358
3368
3378
3408
3418
3428
3438
3448
3458
3468
3478
3508
3518
3528
3538
3548
3558
3568
3578
3608
3618
3628
3638
3648
3658
3668
3678
3708
3718
3728
3738
3748
3758
3768
3778
Decimale
20610
20710
20810
20910
21010
21110
21210
21310
21410
21510
21610
21710
21810
21910
22010
22110
22210
22310
22410
22510
22610
22710
22810
22910
23010
23110
23210
23310
23410
23510
23610
23710
23810
23910
24010
24110
24210
24310
24410
24510
24610
24710
24810
24910
25010
25110
25210
25310
25410
25510
Esadecimale
CE16
CF16
D016
D116
D216
D316
D416
D516
D616
D716
D816
D916
DA16
DB16
DC16
DD16
DE16
DF16
E016
E116
E216
E316
E416
E516
E616
E716
E816
E916
EA16
EB16
EC16
ED16
EE16
EF16
F016
F116
F216
F316
F416
F516
F616
F716
F816
F916
FA16
FB16
FC16
FD16
FE16
FF16
2409
Carattere
Î
Ï
Ð
Ñ
Ò
Ó
Ô
Õ
Ö
×
Ø
Ù
Ú
Û
Ü
Ý
Þ
ß
à
á
â
ã
ä
å
æ
ç
è
é
ê
ë
ì
í
î
ï
ð
ñ
ò
ó
ô
õ
ö
÷
ø
ù
ú
û
ü
ý
þ
ÿ
Denominazione in inglese
LATIN CAPITAL LETTER I WITH CIRCUMFLEX
LATIN CAPITAL LETTER I WITH DIAERESIS
LATIN CAPITAL LETTER ETH
LATIN CAPITAL LETTER N WITH TILDE
LATIN CAPITAL LETTER O WITH GRAVE
LATIN CAPITAL LETTER O WITH ACUTE
LATIN CAPITAL LETTER O WITH CIRCUMFLEX
LATIN CAPITAL LETTER O WITH TILDE
LATIN CAPITAL LETTER O WITH DIAERESIS
MULTIPLICATION SIGN
LATIN CAPITAL LETTER O WITH STROKE
LATIN CAPITAL LETTER U WITH GRAVE
LATIN CAPITAL LETTER U WITH ACUTE
LATIN CAPITAL LETTER U WITH CIRCUMFLEX
LATIN CAPITAL LETTER U WITH DIAERESIS
LATIN CAPITAL LETTER Y WITH ACUTE
LATIN CAPITAL LETTER THORN
LATIN SMALL LETTER SHARP S
LATIN SMALL LETTER A WITH GRAVE
LATIN SMALL LETTER A WITH ACUTE
LATIN SMALL LETTER A WITH CIRCUMFLEX
LATIN SMALL LETTER A WITH TILDE
LATIN SMALL LETTER A WITH DIAERESIS
LATIN SMALL LETTER A WITH RING ABOVE
LATIN SMALL LETTER AE
LATIN SMALL LETTER C WITH CEDILLA
LATIN SMALL LETTER E WITH GRAVE
LATIN SMALL LETTER E WITH ACUTE
LATIN SMALL LETTER E WITH CIRCUMFLEX
LATIN SMALL LETTER E WITH DIAERESIS
LATIN SMALL LETTER I WITH GRAVE
LATIN SMALL LETTER I WITH ACUTE
LATIN SMALL LETTER I WITH CIRCUMFLEX
LATIN SMALL LETTER I WITH DIAERESIS
LATIN SMALL LETTER ETH
LATIN SMALL LETTER N WITH TILDE
LATIN SMALL LETTER O WITH GRAVE
LATIN SMALL LETTER O WITH ACUTE
LATIN SMALL LETTER O WITH CIRCUMFLEX
LATIN SMALL LETTER O WITH TILDE
LATIN SMALL LETTER O WITH DIAERESIS
DIVISION SIGN
LATIN SMALL LETTER O WITH STROKE
LATIN SMALL LETTER U WITH GRAVE
LATIN SMALL LETTER U WITH ACUTE
LATIN SMALL LETTER U WITH CIRCUMFLEX
LATIN SMALL LETTER U WITH DIAERESIS
LATIN SMALL LETTER Y WITH ACUTE
LATIN SMALL LETTER THORN
LATIN SMALL LETTER Y WITH DIAERESIS
Esempi di codifica dei caratteri
2410
224.3 Riferimenti
• Jukka Korpela, A tutorial on character code issue
<http://www.hut.fi/~jkorpela/chars.html>
• Jukka Korpela, The ISO Latin 1 character repertoire - a description with usage and notes
<http://www.hut.fi/~jkorpela/latin1/>
• Roman Czyborra, The ISO 8859 Alphabet Soup
<http://czyborra.com/charsets/iso8859.html>
• Roman Czyborra, Codepages & Co.
<http://czyborra.com/charsets/codepages.html>
Appunti di informatica libera 2003.01.01 --- Copyright © 2000-2003 Daniele Giacomini -- daniele @ swlibero.org
Parte xliii
PostScript: un linguaggio per la
composizione finale
225 Linguaggio PostScript: introduzione . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2412
225.1 Impostazione generale . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2412
225.2 Linee e aree . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2416
225.3 Salvare e recuperare le impostazioni grafiche . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2421
225.4 Spostamento del piano cartesiano e modifica della scala . . . . . . . . . . . . . . . . . . 2422
225.5 Ripetizione . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2424
225.6 Testo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2424
225.7 Salvataggio e recupero delle impostazioni della pagina nel complesso . . . . . . 2426
225.8 Riferimenti . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2427
226 PostScript: espressioni e funzioni . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2428
226.1 Lo stack . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2428
226.2 Funzioni comuni . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2429
226.3 Operazioni sulle stringhe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2430
226.4 Funzioni . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2432
226.5 Dizionari . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2433
226.6 Riferimenti . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2434
227 PostScript: caratteri da stampa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2435
227.1 Aspetto dei caratteri da stampa comuni . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2436
227.2 Distorsione e spostamento dei caratteri da stampa . . . . . . . . . . . . . . . . . . . . . . . . 2439
227.3 Riferimenti . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2441
228 Esempi di funzioni PostScript . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2443
228.1 Unità di misura . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2443
228.2 Funzioni diagnostiche . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2443
228.3 Gestione di stringhe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2444
228.4 Riferimenti . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2446
2411
Capitolo
225
Linguaggio PostScript: introduzione
Benché il linguaggio PostScript sia nato per le stampanti, disponendo di Ghostscript potrebbe
essere usato anche per scrivere direttamente. Lo scopo di questo capitolo è quello di introdurre
all’uso diretto del linguaggio PostScript, in modo molto semplice, facendo riferimento prevalentemente al livello 1, eventualmente con qualche annotazione sul livello 2, mentre il livello 3
diventa troppo complesso e non più utile per un utilizzo diretto.
A ogni modo, gli esempi che si fanno sono stati verificati con Ghostscript e non con una vera
stampante PostScript.
225.1 Impostazione generale
Un file PostScript è un file di testo, in cui le righe sono terminate indifferentemente con <LF>
oppure con <CR><LF>, che inizia con una riga simile al modello seguente:
%!PS-Adobe-livello_ps
[EPSF-livello_eps]
Il livello è in pratica il numero di versione del linguaggio; per quanto riguarda il livello PostScript,
si fa riferimento generalmente ai valori 1.0, 2.0 e 3.0. Il modello sintattico mostra la possibilità
di aggiungere la stringa ‘EPSF-livello_eps’, con la quale si vuole specificare che si tratta di un
file PostScript incapsulato. In altri termini, un file PostScript normale inizia più o meno come
nell’esempio seguente, dove si fa riferimento al livello 2:
%!PS-Adobe-2.0
In tal caso si intende lavorare su una serie di pagine; al contrario, se si sta realizzando una
sola immagine nell’ambito di uno spazio determinato, si aggiunge la dichiarazione del tipo
incapsulato:
%!PS-Adobe-2.0 EPSF-1.2
In generale, il simbolo di percentuale (‘%’) serve a introdurre dei commenti che non generano un
risultato nella stampa; tuttavia, una sequenza di due simboli di percentuale ha un ruolo speciale
per la dichiarazione di direttive importanti; inoltre, la stessa dichiarazione iniziale del tipo di file
è preceduta da un simbolo percentuale. In generale, onde evitare equivoci, si indica un commento
con un solo simbolo di percentuale seguito da almeno uno spazio:
% testo_commentato
Il commento può essere piazzato ovunque, tenendo presente che vale dal punto in cui appare,
fino alla fine della riga.
Le direttive particolari che iniziano con due simboli di percentuale hanno la forma seguente:
[
%%direttiva : argomenti
]
In pratica, il nome delle direttive deve essere attaccato ai segni di percentuale; inoltre, se è prevista l’aggiunta di argomenti alla direttiva, dopo il nome della stessa appaiono due punti, seguiti da
almeno uno spazio e dopo dagli argomenti previsti. Quello che segue è l’esempio di una struttura
possibile per un file PostScript articolato su più pagine:
2412
Linguaggio PostScript: introduzione
2413
%!PS-Adobe-2.0
%%Creator: nome_del_redattore_del_file
%%DocumentPaperSizes: formato
%%EndComments
%%BeginProlog
prologo
%%EndProlog
%%Page: numero_mostrato pagina_reale
istruzioni_ps
showpage
%%Page: numero_mostrato pagina_reale
istruzioni_ps
showpage ...
%%Trailer
%%EOF
[
]
[
]
Il tutto dovrebbe essere abbastanza intuitivo: le prime istruzioni speciali, fino a
‘%%EndComments’, descrivono il documento specificando in particolare le dimensioni della pagina; le istruzioni racchiuse tra ‘%%BeginProlog’ e ‘%%EndProlog’ possono servire per dichiarare delle funzioni utilizzate nel documento; le istruzioni relative a ogni singola pagina sono
introdotte da ‘%%Page: m n ’; la visualizzazione della pagina, dopo la sua costruzione, si ottiene
con l’istruzione ‘showpage’; il file termina con ‘%%Trailer’ e ‘%%EOF’.
A questo punto, conviene vedere subito come si può articolare un file PostScript che non contiene
pagine, ma una sola immagine:
%!PS-Adobe-2.0 EPSF-1.2
%%Creator: nome_del_redattore_del_file
%%BoundingBox: 0 0 larghezza_in_punti altezza_in_punti
%%EndComments
%%BeginProlog
prologo
%%EndProlog
istruzioni_ps
showpage
%%Trailer
%%EOF
[
]
Si
può osservare che la direttiva speciale ‘%%BoundingBox’ va a sostituire
‘%%DocumentPaperSizes’, allo scopo di indicare l’area in cui vanno rappresentate le
istruzioni.
A ogni modo, la direttiva ‘%%BoundingBox’ può essere usata anche per un file PostScript diviso
in pagine, quando si vuole indicare un formato non standard, oppure se si vuole essere precisi.
225.1.1 Piano di lavoro e unità di misura
Il linguaggio PostScript è predisposto per fare riferimento a oggetti su un piano cartesiano ideale,
in cui l’unità di misura normale è il punto tipografico, corrispondente secondo questo linguaggio
a 1/72-esimo di pollice, pari a circa 0,35278 mm. In condizioni normali, la pagina è collocata
sul piano cartesiano ideale come si vede nella figura 225.1, dove lo zero per x e y corrispondono
esattamente con l’angolo inferiore sinistro; tuttavia, è consentita la definizione di pagine collocate
in posizioni differenti, se questo può servire in qualche modo.
Linguaggio PostScript: introduzione
2414
Figura 225.1. La pagina collocata su degli assi cartesiani ideali.
y
788
x,y = 0,0
x,y = 595.3,788
595.3
x
Gli oggetti grafici vengono disegnati sul piano cartesiano ideale; quello che risulta trovarsi
sull’area della pagina potrà essere stampato.
225.1.2 Posizione corrente
Il PostScript può essere visto come un linguaggio per disegnare (tracciare curve, riempire delle
aree e piazzare dei caratteri tipografici). Tutto questo avviene quasi sempre indicando delle coordinate, dove spesso la posizione di partenza ha importanza. Le coordinate iniziali si modificano
con l’istruzione ‘moveto’:
x y moveto
In pratica, si indicano due numeri, seguiti dalla parola chiave ‘moveto’. Il significato è molto
semplice: il primo numero esprime la coordinata orizzontale (asse X), il secondo la coordinata
verticale (asse Y). I valori si esprimono in punti tipografici.
225.1.3 Istruzioni speciali più importanti
Le istruzioni più importanti che iniziano con due segni di percentuale sono elencate brevemente
nella tabella 225.1. Tuttavia, è il caso di aggiungere qualche piccola indicazione a proposito di
alcune di queste.
Nessuna delle istruzioni che iniziano con due segni di percentuale è indispensabile; tuttavia
alcune sono importanti. L’inserimento corretto di queste istruzioni rende il file PostScript più
facile da gestire con gli strumenti comuni.
Linguaggio PostScript: introduzione
2415
Tabella 225.1. Alcune istruzioni che iniziano con due segni di percentuale.
Istruzione
%%Creator: nome
%%DocumentPaperSizes: formato
%%BoundingBox: x 1 y 1 x 2 y 2
%%Title: titolo
%%CreationDate: data
%%Pages: n
%%PageOrder: Ascend Descend
%%EndComments
%%BeginProlog
%%EndProlog
%%BeginSetup
%%EndSetup
%%Page: x n
%%Trailer
%%EOF
|
Descrizione
Il nome del programma che ha composto il file.
Formato della carta.
Collocazione e dimensione della carta: da x 1 y 1 a x 2 y 2.
Titolo del documento.
Data e ora di creazione del documento.
Quantità di pagine contenuta.
Ordine di apparizione delle pagine: ascendente o discendente.
Fine dell’intestazione con le informazioni generali.
Inizia un’area di definizione delle funzioni.
Termina l’area di definizione delle funzioni.
Inizia un’area per l’inserimento di istruzioni di stampa.
Termina l’area delle di istruzioni di stampa.
Inizia la pagina n -esima, rappresentata come x .
Conclude la serie delle pagine.
Conclude definitivamente il file.
L’istruzione ‘%%DocumentPaperSizes’ serve intuitivamente per elencare le dimensioni possibili delle pagine. In generale si indica una sola parola chiave che esprime sinteticamente la
dimensione della pagina, come si vede nella tabella 225.2. Probabilmente non conviene andare
al di fuori di pochi standard; eventualmente è preferibile indicare le coordinate esatte attraverso
l’istruzione ‘%%BoundingBox’.
Tabella 225.2. Formati di stampa comuni, indicabili come argomento dell’istruzione
‘%%DocumentPaperSizes’. Le dimensioni non sono necessariamente quelle reali, ma
quelle conosciute dal linguaggio PostScript.
formato
letter
legal
a3
a4
a5
b4
b5
larghezza
punti
612
612
842
595
421
709
501
altezza
punti
792
1008
1190
842
595
1002
709
larghezza
pollici
8,50
8,50
11,6944
8,26389
5,84722
9,84722
6,95833
altezza
pollici
11,00
14,00
16,5278
11,6944
8,26389
13,9167
9,84722
larghezza
cm
21,59
21,59
29,7
21
14,85
25,0119
17,6742
altezza
cm
27,94
35,56
42
29,7
21
35,3483
25,0119
‘%%BoundingBox’ consente di indicare la posizione dell’angolo inferiore sinistro e di quello su-
periore destro della pagina. Di solito, le prime due coordinate che esprimono proprio la posizione
dell’angolo inferiore sinistro, sono azzerate, a indicare che si parte dallo zero degli assi cartesiani
ideali della superficie.
225.1.4 Aspetto delle istruzioni normali
Le istruzioni PostScript sembrano non avere inizio e fine, perché si possono collocare su una o
più righe indifferentemente, senza alcun segno di separazione. Per esempio, si può scrivere
newpath
100
100
100
431
350
431
350
100
closepath
moveto
lineto
lineto
lineto
oppure, indifferentemente
Linguaggio PostScript: introduzione
2416
newpath 100 100 moveto 100 431 lineto 350 431 lineto 350 100 lineto closepath
e in tanti altri modi intermedi. È evidente che se si vuole scrivere del codice intelligibile occorre
uno stile (come in tutti i linguaggi di programmazione).
la cosa che può apparire strana inizialmente è il fatto che i comandi che prevedono l’uso di
argomenti, ricevono questi dati prima del nome del comando stesso. Per esempio, è già stata
mostrata l’istruzione ‘moveto’, che riceve l’indicazione delle coordinate prima del suo nome.
225.2 Linee e aree
La cosa più semplice che si può fare per cominciare a comprendere il linguaggio è quella di
disegnare delle linee. In generale, il disegno avviene partendo dalle coordinate correnti, per cui
questa indicazione non appare in modo esplicito, ma se necessario si definisce con uno spostamento attraverso l’istruzione ‘moveto’. Per le linee rette si possono usano le istruzioni ‘lineto’
e ‘rlineto’, dove la prima rappresenta un movimento con coordinate di destinazione assolute,
mentre la seconda fa riferimento a coordinate di destinazione relative a quelle di partenza. Si osservino gli esempi seguenti, con cui si disegna lo stesso rettangolo largo 20 punti e alto 10 punti,
a partire dalla coordinata x ,y=0,0:
0
0
20
20
0
0
10
10
0
0
0
0
20
0
-20
0
10
0
-10
0
moveto
lineto
lineto
lineto
lineto
moveto
rlineto
rlineto
rlineto
rlineto
In pratica, l’istruzione ‘lineto’ vuole l’indicazione del punto finale espresso come coordinata
assoluta, mentre ‘rlineto’ vuole una coordinata relativa alla posizione corrente.
x,y=0,10=+0,+10
x,y=20,10=+20,+0
x,y=0,0
x,y=20,0=+0-10
Il disegno non viene tracciato se alla fine non si aggiunge un’istruzione ‘stroke’, che non richiede argomenti. Dopo un’istruzione ‘stroke’ viene perduto il riferimento alle coordinate correnti,
per cui, se necessario, si deve ricominciare con un’istruzione ‘moveto’. Si osservi l’esempio seguente, in cui lo stesso rettangolo viene disegnato un segmento alla volta, riposizionando sempre
le coordinate iniziali:
0
0
0
20
20
20
20
0
0
10
10
10
10
0
0
0
moveto
lineto
moveto
lineto
moveto
lineto
moveto
lineto
stroke
stroke
stroke
stroke
Naturalmente, se si preferisce questo modo di utilizzo dell’istruzione ‘stroke’, si può anche
cambiare un po’ lo stile di scrittura:
Linguaggio PostScript: introduzione
0
0
20
20
0
10
10
0
moveto
moveto
moveto
moveto
0
20
20
0
10
10
0
0
lineto
lineto
lineto
lineto
2417
stroke
stroke
stroke
stroke
Le linee, oltre alla collocazione, hanno due caratteristiche importanti: lo spessore e il colore.
Lo spessore predefinito dovrebbe essere di un punto, mentre il colore predefinito è il nero. Si
modifica lo spessore delle linee con l’istruzione ‘setlinewidth’ e la colorazione (grigia) con
l’istruzione ‘setgray’. Entrambi ricevono un solo argomento numerico, che nel primo caso
esprime lo spessore della linea e nel secondo rappresenta la luminosità, con un valore che va da
zero a uno (zero rappresenta il nero e uno rappresenta il bianco).
Le istruzioni che alterano le caratteristiche delle linee, hanno effetto solo nel momento in cui
appare l’istruzione ‘stroke’. In questo modo, si possono indicare le linee desiderate, quindi
si possono cambiare le loro caratteristiche e infine si possono tracciare.
L’esempio seguente disegna lo stesso rettangolo già presentato, specificando un tratto di due
punti tipografici di colore grigio (esattamente a metà tra il bianco e il nero). Si può osservare
che le istruzioni ‘setlinewidth’ e ‘setgray’ sono state collocate subito prima dell’istruzione
‘stroke’:
0
0
20
20
0
0
10
10
0
0
moveto
lineto
lineto
lineto
lineto
2 setlinewidth
0 setgray
stroke
Si possono tracciare delle linee per disegnare un poligono. L’esempio già visto rappresenta proprio un rettangolo, ma non è stato dichiarato esplicitamente il fatto che le linee devono congiungersi. Per farlo occorre dichiarare un percorso, con l’istruzione ‘newpath’, che si conclude con
‘closepath’. Si osservi la variante seguente al disegno del rettangolo:
newpath
0
0
0
10
20
10
20
0
closepath
moveto
lineto
lineto
lineto
2 setlinewidth
0 setgray
stroke
In pratica, si tracciano le prime tre linee, mentre l’ultima viene indicata implicitamente con la
richiesta di chiudere il percorso con l’istruzione ‘closepath’.
Il fatto di avere realizzato un poligono, consente di definire il colore di riempimento. In condizioni normali, quando non è stato fissato alcunché, il poligono è trasparente, mentre se si fissa
un riempimento diventa opaco e il colore ricopre anche il bordo tracciato con le linee.1 Il colore di riempimento si definisce con l’istruzione ‘fill’ e il colore usato è quello già fissato con
l’istruzione ‘setgray’.
newpath
0
1
0 moveto
Il bordo ha lo stesso colore fissato con l’istruzione ‘setgray’, per cui tutto diventa dello stesso colore.
Linguaggio PostScript: introduzione
2418
0
10 lineto
20
10 lineto
20
0 lineto
closepath
%
2
setlinewidth
0.5 setgray
fill
stroke
L’esempio mostra l’utilizzo dell’istruzione ‘fill’ per colorare il rettangolo di grigio. Dal momento che lo spessore delle linee non serve più, l’istruzione relativa è stata commentata. Volendo
mettere un bordo a questo rettangolo, occorre ridisegnarne sopra un altro trasparente, con il tratto
desiderato:
newpath
0
0
0
10
20
10
20
0
closepath
moveto
lineto
lineto
lineto
0.5 setgray
fill
stroke
newpath
0
0
0
10
20
10
20
0
closepath
2
0
moveto
lineto
lineto
lineto
setlinewidth
setgray
stroke
Per completare l’argomento sulle linee e sui poligoni, conviene mostrare un esempio completo,
che poi viene mostrato nella figura 225.3. Si osservi che l’area in cui viene disegnato è lo stretto
indispensabile per contenerlo: si estende da -1,-1 a 21,11, per dare lo spazio allo spessore della
riga che è di due punti.
%!PS-Adobe-2.0 EPSF-1.2
%%Creator: Daniele Giacomini
%%BoundingBox: -1 -1 21 11
%%EndComments
% Disegna un rettangolo
newpath
0
0
0
10
20
10
20
0
closepath
moveto
lineto
lineto
lineto
0.5 setgray
fill
stroke
newpath
0
0
0
10
20
10
20
0
closepath
moveto
lineto
lineto
lineto
Linguaggio PostScript: introduzione
2
0
2419
setlinewidth
setgray
stroke
showpage
%%Trailer
%%EOF
Figura 225.3. Il rettangolo riempito e bordato. Il contorno è molto largo, ma è
proporzionato rispetto al rettangolo che è alto solo 10 punti.
225.2.1 Archi e curve
Si può disegnare un arco o un cerchio completo con l’istruzione ‘arc’. In questo caso, non c’è bisogno di fare riferimento a una posizione corrente; anzi, è meglio eliminare tale informazione con
un’istruzione ‘stroke’ preventiva. L’istruzione ‘arc’ richiede l’indicazione delle coordinate del
centro del cerchio, la lunghezza del raggio, l’angolo di partenza e l’angolo di destinazione in direzione antioraria. L’esempio seguente disegna un arco con centro nella posizione x ,y=100,150,
con raggio di 50 punti, da 0 a 90 gradi:
100 150 50 0 90 arc
In pratica, si tratta di quanto si vede nella figura 225.4.
Figura 225.4. Arco di cerchio disegnato da 0 a 90 gradi.
Se prima di disegnare il cerchio o l’arco di cerchio si tracciano altre linee, è conveniente
chiudere i disegni precedenti con l’istruzione ‘stroke’, per evitare di avere delle coordinate
correnti attive nel momento in cui si usa l’istruzione ‘arc’. Diversamente, si otterrebbe una
linea che collega le coordinate iniziali con il punto di partenza dell’arco disegnato.
Per disegnare un cerchio completo, basta indicare l’intervallo di angoli da 0 a 360 gradi. Se si
vuole riempire il cerchio, non è necessario utilizzare le istruzioni ‘newpath’ e ‘closepath’,
perché si ottiene sempre un riempimento, anche quando il cerchio non è completo.
Il disegno di una curva è invece più complicato: si usa l’istruzione ‘curveto’, ma oltre alle coordinate di destinazione, bisogna indicare la tangente del punto di inizio e del punto di destinazione.
Prima di dare altre spiegazioni, conviene partire da un esempio visivo, come si vede nella figura
225.5. La curva da prendere in considerazione è rappresentata con un tratto più scuro. Si possono
vedere due linee oblique, che partono rispettivamente dal punto di inizio e dal punto di arrivo
della curva: si tratta delle tangenti che stabiliscono la curvatura di partenza e di arrivo della linea
disegnata. L’istruzione necessaria a disegnare questa curva è la seguente:
Linguaggio PostScript: introduzione
2420
0
200
50
100
moveto
0
0
200
50
curveto
Figura 225.5. Esempio di una curva in cui sono evidenti le tangenti.
100
50
0,0
200
In pratica:
• le coordinate di partenza sono x ,y=0,50;
• la prima tangente è la linea che va da x ,y=0,50 (le coordinate di partenza) a x ,y=200,100;
• la seconda tangente è la linea che va da x ,y=200,50 (le coordinate di arrivo) a x ,y=0,0;
• le coordinate di arrivo sono x ,y=200,50.
Naturalmente, la lunghezza delle linee indicate come tangenti rendono più o meno importante
la curvatura relativa. Si osservi, nella figura 225.6, come si trasforma il disegno se si accorcia la
linea tangente di arrivo come nell’esempio seguente:
0
200
50
100
moveto
100
25
200
50
curveto
Figura 225.6. Esempio di una curva in cui sono evidenti le tangenti.
100
50
25
0,0
100
200
Il modello sintattico per l’utilizzo dell’istruzione ‘curveto’ è quindi il seguente:
x_tangente_inizio y_tangente_inizio x_tangente_fine y_tangente_fine x_fine_curva y_fine_curva
curveto
Linguaggio PostScript: introduzione
2421
225.3 Salvare e recuperare le impostazioni grafiche
Le impostazioni grafiche, come quelle che si possono fissare con le istruzioni ‘setlinewidth’
e ‘setgray’, possono essere salvate e recuperate da una pila apposita. Si utilizza l’istruzione
‘gsave’ per salvare l’impostazione corrente e ‘grestore’ per recuperare le ultime impostazioni
salvate. Si osservi l’esempio seguente:
1 setlinewidth
gsave
2 setlinewidth
gsave
4 setlinewidth
50 120 moveto
200 120 lineto
stroke
grestore
50 125 moveto
200 125 lineto
stroke
grestore
50 130 moveto
200 130 lineto
stroke
Vengono accumulate tre spessori differenti per le linee, quindi si procede disegnando tre linee,
dopo ognuna delle quali viene recuperata l’ultima impostazione grafica. In pratica, la linea da
50,120 a 200,120 viene disegnata con un tratto di quattro punti; la linea da 50,125 a 200,125
viene disegnata con un tratto di tre punti; la linea da 50,130 a 200,130 viene disegnata con un
tratto di un punto di spessore.
Quando si disegna qualcosa, può essere opportuno racchiudere le modifiche alle caratteristiche
entro una coppia ‘gsave’-‘grestore’, onde evitare di coinvolgere le impostazioni precedenti,
che potrebbero riguardare il resto del file:
gsave
4 setlinewidth
50 120 moveto
200 120 lineto
stroke
grestore
Nell’esempio che appare sopra, si inizia salvando le impostazioni e impostando uno spessore
di quattro punti. Viene quindi indicata la linea e fissata con l’istruzione ‘stroke’. Al termine
si recuperano le impostazioni grafiche. Nello stesso modo, si potevano salvare e modificare le
impostazioni grafiche subito prima dell’istruzione ‘stroke’:
50 120 moveto
200 120 lineto
gsave
4 setlinewidth
stroke
grestore
Attraverso la tecnica del salvataggio e del recupero delle caratteristiche grafiche, è possibile
disegnare un poligono bordato senza dover ripetere due volte il tratto del contorno. In pratica, il
comando di riempimento viene dato entro un ambiente protetto da ‘gsave’ e ‘grestore’, come
si vede nell’esempio seguente:
%!PS-Adobe-2.0 EPSF-1.2
%%Creator: Daniele Giacomini
%%BoundingBox: -1 -1 21 11
%%EndComments
Linguaggio PostScript: introduzione
2422
% Disegna un rettangolo
newpath
0
0
0
10
20
10
20
0
closepath
moveto
lineto
lineto
lineto
gsave
0.5 setgray
fill
grestore
2
setlinewidth
0
setgray
stroke
showpage
%%Trailer
%%EOF
Il risultato è identico a quanto già visto nella figura 225.3.
225.4 Spostamento del piano cartesiano e modifica della
scala
È possibile spostare la posizione della superficie prima di dare altre istruzioni di scrittura di
qualunque tipo. Si tratta in particolare delle istruzioni ‘translate’ e di ‘rotate’. La prima
di queste due sposta le coordinate 0,0 in una posizione nuova, prendendo come riferimento le
coordinate precedenti; la seconda ruota gli assi attorno alle coordinate 0,0. Per esempio, con le
istruzioni
50 100 translate
50 50 moveto
100 50 lineto
stroke
si ottiene una linea orizzontale dalla posizione 100,150 alla posizione 150,150. Infatti, l’istruzione ‘translate’ sposta le coordinate 0,0 verso 50,100, secondo la collocazione precedente.
La figura 225.7 mostra la collocazione iniziale e lo spostamento; la linea disegnata è quella che
appare con tratto più scuro.
Figura 225.7. Esempio riferito a uno spostamento degli assi.
150
100
0,0
50
0,0
50
50
100
100
150
Linguaggio PostScript: introduzione
2423
L’istruzione ‘rotate’ fa ruotare il piano cartesiano sul centro delle coordinate 0,0. La figura
225.8 mostra cosa accade se si sposta lo zero nella posizione 0,0 e poi si ruota di 30 gradi, con le
istruzioni seguenti:
50
30
50
100
stroke
50 translate
rotate
50
50
moveto
lineto
Figura 225.8. Esempio riferito a uno spostamento e a una rotazione degli assi.
0
10
50
50
50
0,0
0,0
50
Lo spostamento e la rotazione del piano sono informazioni che possono essere salvate e recuperate con le istruzioni ‘gsave’ e ‘grestore’. Pertanto, prima di uno spostamento o di una rotazione,
conviene salvare la situazione, per recuperarla quando questi cambiamenti non servono più.
gsave
50
30
50 translate
rotate
50
50
100
50
stroke
grestore
moveto
lineto
Oltre allo spostamento e alla rotazione del piano, si può modificare la scala, con l’istruzione
‘scale’. Gli argomenti dell’istruzione sono due valori, che esprimono il rapporto nei confronti
dell’asse X e nei confronti dell’asse Y. Dopo la modifica della scala, le coordinate 0,0 rimangono
centrate sulla stessa posizione iniziale. Per esempio,
1 0.5 scale
serve a fare in modo che la scala dell’asse Y risulti schiacciata alla metà del valore precedente,
mentre l’asse X non viene modificato. Anche le alterazioni della scala possono essere recuperate
da un’istruzione ‘grestore’.
Linguaggio PostScript: introduzione
2424
225.5 Ripetizione
Un gruppo di istruzioni, racchiuso tra parentesi graffe, può essere ripetuto più volte con
l’istruzione ‘repeat’:
n {istruzioni } repeat
Evidentemente, perché ciò abbia un senso, è necessario che le istruzioni da ripetere creino ogni
volta un cambiamento, come una rotazione o uno spostamento di assi. Per esempio,
36 {10 rotate 10 10 moveto 30 30 lineto} repeat
stroke
Disegna una stellina attorno alle coordinate 0,0, con un diametro di 80 punti. In questo caso, la
rotazione riporta alla fine gli assi nella posizione di partenza, ma in generale conviene salvare e
ripristinare la situazione:
gsave
36 {10 rotate 10 10 moveto 30 30 lineto} repeat
stroke
grestore
Figura 225.9. Esempio di un disegno ottenuto con la rotazione.
225.6 Testo
Per poter scrivere sulla superficie del foglio, è necessario selezionare il tipo di carattere e la
dimensione prima di tutto. Questo si ottiene con alcune istruzioni, che in pratica conviene usare
assieme:
/carattere findfont dimensione scalefont setfont
Per esempio, per usare il carattere Helvetica alto 12 punti, si usa l’istruzione seguente:
/Helvetica findfont 12 scalefont setfont
La scrittura vera e propria avviene con l’istruzione ‘show’, con la quale si colloca il testo a partire
dalle coordinate correnti, per cui si fa precedere normalmente da un’istruzione ‘moveto’:
(testo) show
Come si vede dal modello sintattico, il testo deve essere scritto tra parentesi tonde e collocato
prima della parola chiave ‘show’.
Dovendo usare le parentesi tonde per delimitare il testo da visualizzare, deve esserci un modo per
poter togliere a queste il valore sintattico normale, quando c’è la necessità di rappresentarle nel
testo. In pratica si usano le sequenze ‘\(’ e ‘\)’ per rappresentarle; inoltre, dal momento che la
barra obliqua inversa ha un significato speciale, per rappresentare questa si usa la sequenza ‘\\’.
Linguaggio PostScript: introduzione
2425
La tabella 225.3 riepiloga le sequenze speciali più importanti per il testo delimitato tra parentesi
tonde.
Tabella 225.3. Alcune sequenze speciali per la scrittura di testo delimitato da parentesi
tonde, con l’istruzione ‘show’.
Sequenza
\\
\(
\)
\nnn
Descrizione
Barra obliqua inversa.
Parentesi tonda aperta.
Parentesi tonda chiusa.
Simbolo corrispondente al numero, in ottale, secondo la codifica attuale.
Se si seleziona un carattere non disponibile, viene utilizzato il Courier. La tabella 225.4 elenca
i nomi standard dei tipi di carattere fondamentali che si possono utilizzare con il linguaggio
PostScript.
Tabella 225.4. Nomi dei tipi di carattere comuni che possono essere utilizzati con il
linguaggio PostScript.
Nome
Times, Times-Roman
Times-Italic
Times-Bold
Times-BoldItalic
Helvetica
Helvetica-Oblique
Helvetica-Bold
Helvetica-BoldOblique
Courier
Courier-Oblique
Courier-Bold
Courier-BoldOblique
Symbol
Descrizione
Times normale.
Times corsivo.
Times neretto.
Times neretto inclinato.
Helvetica normale.
Helvetica inclinato.
Helvetica neretto.
Helvetica neretto inclinato.
Courier normale.
Courier inclinato.
Courier neretto.
Courier neretto inclinato.
Symbol.
Un’istruzione simile a ‘show’, si occupa di visualizzare il testo, controllandone lo spostamento
in corrispondenza di un simbolo particolare:
x y n (testo) widthshow
L’istruzione ‘widthshow’ serve a fissare uno spostamento orizzontale (x ) e uno spostamento
verticale (y), subito dopo il simbolo corrispondente al numero n . In pratica, se alla fine di ogni
spazio si vuole aggiungere uno spazio orizzontale di due punti, si usa la forma seguente:
2 0 32 (testo) widthshow
Questa è anche la situazione tipica, in cui si vuole allargare lo spazio tra le parole, per adattare la
riga scritta alla larghezza disponibile. Naturalmente, lo spazio normale può anche essere ridotto,
se lo si desidera, utilizzando valori orizzontali negativi, come nell’esempio seguente:
-1 0 32 (testo) widthshow
Se si attribuisce un valore anche al secondo argomento numerico, si ottiene uno spostamento
verticale, come nell’esempio seguente, in cui ogni parola viene alzata di due punti rispetto alla
precedente:
0 2 32 (testo) widthshow
Linguaggio PostScript: introduzione
2426
225.7 Salvataggio e recupero delle impostazioni della
pagina nel complesso
Quando si scrive un documento composto da diverse pagine, diventa utile la possibilità di recuperare le impostazioni precedenti, prima di passare alla pagina successiva. È già stata presentata
la coppia di istruzioni ‘gsave’ e ‘grestore’, specifica per le impostazioni grafiche. Per tutto,
si può usare invece la coppia ‘save’ e ‘restore’. Di solito si inizia una pagina con ‘save’ e si
conclude con ‘restore’, in modo da garantire il recupero di tutto, senza dimenticare qualcosa.
%!PS-Adobe-2.0
%%Creator: nome_del_redattore_del_file
%%DocumentPaperSizes: formato
%%EndComments
%%BeginProlog
prologo
%%EndProlog
%%Page: numero_mostrato pagina_reale
save
istruzioni_ps
showpage
restore
%%Page: numero_mostrato pagina_reale
save
istruzioni_ps
showpage
restore ...
%%Trailer
%%EOF
[
]
[
]
Le istruzioni ‘save’ e ‘restore’ dovrebbero essere sempre annidate correttamente, nel senso
che ogni istruzione ‘restore’ va a recuperare l’ultima istruzione ‘save’ che non sia già stata
presa in considerazione da un altro ‘restore’. Se viene eseguito un ‘restore’ che non risulta
abbinato a un’istruzione ‘save’, si genera un errore irreversibile.
Per ovviare all’inconveniente di dover seguire attentamente l’uso delle istruzioni ‘save’ e
‘restore’, si può attribuire un «nome» a un’istruzione ‘save’, richiamando lo stesso nome
nel momento del ‘restore’:
/nome save def
...
...
...
nome restore
La cosa non è molto intuitiva, ma funziona così: il nome che viene dichiarato nel momento
dell’uso dell’istruzione ‘save’, viene posto davanti all’istruzione ‘restore’. Se nello spazio tra
queste due istruzioni apparivano altre istruzioni ‘save’, queste sono tutte annullate. Segue un
esempio:
/Mia_Configurazione_Predefinita save def
...
...
...
Mia_Configurazione_Predefinita restore
Linguaggio PostScript: introduzione
2427
Tabella 225.5. Tabella riassuntiva delle istruzioni più semplici del linguaggio PostScript.
Istruzione
x y moveto
x y rmoveto
x y lineto
x y rlineto
x y m n o arc
x y m n o arcn
x y x y x y curveto
x y translate
n rotate
n {istruzioni } repeat
n setlinewidth
n setgray
fill
newpath
closepath
stroke
gsave
grestore
save
restore
/nome save def
nome restore
/nome findfont dim scalefont setfont
(testo) show
x y n (testo) widthshow
x 0 32 (testo) widthshow
Descrizione
Cambia le coordinate correnti senza disegnare.
Cambia le coordinate correnti in modo relativo.
Traccia una linea fino alle coordinate assolute indicate.
Traccia una linea fino alle coordinate relative indicate.
Arco con centro in x ,y, raggio m , da n a o gradi, in senso
antiorario.
Arco con centro in x ,y, raggio m , da n a o gradi, in senso
orario.
Curva indicando le coordinate di arrivo delle tangenti e infine
della curva.
Fa sì che x ,y corrispondano alle nuove coordinate 0,0.
Ruota di n il fondo, con centro sulle coordinate 0,0.
Ripete n volte le istruzioni tra parentesi graffe.
Spessore delle linee.
Colorazione grigia: 0=nero; 1=bianco.
Riempie i poligoni e le aree racchiuse entro le curve.
Inizia a disegnare un oggetto nuovo.
Unisce l’ultimo punto disegnato con il punto di partenza.
Fissa le linee tracciate.
Accumula le impostazioni grafiche.
Recupera le impostazioni.
Accumula tutte le impostazioni della pagina.
Recupera le impostazioni della pagina.
Accumula tutte le impostazioni dichiarando un nome.
Recupera le impostazioni riferite a quel nome.
Seleziona il carattere e la dimensione indicata.
Scrive il testo indicato usando il carattere già stabilito.
Scrive il testo indicato con uno spostamento x ,y alla fine del
simbolo n .
Scrive il testo indicato con l’aggiunta di uno spazio di x tra le
parole.
225.8 Riferimenti
• Cappella Archive
<http://www.cappella.demon.co.uk/index.html>
• David Byram-Wigfield, Practical PostScript
<http://www.cappella.demon.co.uk/bookpdfs/pracpost.pdf>
• David Byram-Wigfield, Making an electronic book
<http://www.cappella.demon.co.uk/tinypdfs/06ebook.pdf>
• Paul Bourke, PostScript Tutorial
<http://astronomy.swin.edu.au/pbourke/dataformats/postscript/>
• First Guide to PostScript
<http://www.cs.indiana.edu/docproject/programming/postscript/postscript.html>
• Portable Document Format Reference Manual, 1999
<http://partners.adobe.com/asn/developer/acrosdk/docs/pdfspec.pdf>
Appunti di informatica libera 2003.01.01 --- Copyright © 2000-2003 Daniele Giacomini -- daniele @ swlibero.org
Capitolo
226
PostScript: espressioni e funzioni
Il linguaggio PostScript è nato per essere interpretato in modo veloce da stampanti realizzate appositamente. In questo senso, la sua logica segue vagamente quella di un linguaggio
assemblatore.
226.1 Lo stack
Per poter scrivere codice PostScript un po’ più complesso, diventa necessario l’utilizzo di istruzioni che realizzano delle espressioni, fino ad arrivare alla costruzione di funzioni (procedure)
che possono essere richiamate successivamente. Purtroppo, le espressioni realizzate con questo linguaggio, diventano un po’ complicate da leggere. Infatti, queste funzioni ricevono i loro
argomenti prelevandoli da uno stack (pila) ed emettono risultati inserendoli nello stesso stack.
dato ... funzione
Osservando il modello, le informazioni che non sono riconducibili a nomi di funzione, vengono inserite in questo stack, che poi la prima funzione inizia a leggere. Si osservi l’istruzione
seguente:
1 2 3 4 5 6 7 8 9 moveto lineto
I valori da uno a nove, vengono inseriti così come sono nello stack, poi ogni funzione preleva
dallo stack la quantità di argomenti che la riguarda. In questo caso, ‘moveto’ preleva gli ultimi
due valori a essere stati inseriti, precisamente la coppia otto e nove, per cui sposterà le coordinate
correnti in 8,9; successivamente è il turno di ‘lineto’, che preleva altri due valori, precisamente
il sei e il sette, tracciando una linea fino al punto 6,7. Pertanto, tutto è come se fosse stato scritto
nel modo seguente:
8 9 moveto 6 7 lineto
Tuttavia, rimangono ancora altri valori nello stack, per altre funzioni successive, ammesso che
vogliano usarli, perché se si inseriscono altri valori, questi vengono poi estratti per primi.
Dato questo meccanismo, diventano importanti alcune funzioni che consentono di intervenire su
questo stack: ‘clear’ svuota completamente lo stack; ‘pop’ preleva ed elimina l’ultimo valore
inserito.1
Sono un po’ più difficili da comprendere le funzioni ‘exch’ e ‘roll’. La prima scambia l’ordine
degli ultimi due valori inseriti nello stack; la seconda esegue uno scorrimento, verso sinistra o
verso destra di una certa quantità di questi valori:
n_elementi_da_scorrere scorrimento roll
Per esempio, se nello stack ci fossero i valori 1, 2, 3, 4, 5, 6 e 7, in questo ordine, per cui il primo
a essere prelevato sarebbe il numero 7, l’istruzione ‘3 2 roll’ trasformerebbe questa sequenza
in 1, 2, 3, 4, 6, 7 e 5; al contrario, l’istruzione ‘3 -2 roll’ trasformerebbe questa sequenza in
1, 2, 3, 4, 7, 5 e 6. In pratica, il primo valore indica quanti elementi prendere in considerazione,
a partire dall’ultimo, mentre il secondo indica quante volte scorrere e in quale direzione.
Figura 226.1. Esempio di funzionamento dell’istruzione ‘roll’, con uno scorrimento
verso destra.
stack iniziale:
3 2 roll
stack finale:
1 2 3 4 5 6 7
7 5 6
6 7 5
1 2 3 4 6 7 5
1
(primo scorrimento verso destra)
(secondo scorrimento verso destra)
A fianco di ‘pop’ si potrebbe immaginare la presenza di una funzione con il nome push, ma in questo caso non serve,
perché l’azione di inserimento nello stack avviene in modo implicito.
2428
PostScript: espressioni e funzioni
2429
Figura 226.2. Esempio di funzionamento dell’istruzione ‘roll’, con uno scorrimento
verso sinistra.
stack iniziale:
1 2 3 4 5 6 7
3 -2 roll
6 7 5
7 5 6
1 2 3 4 7 5 6
stack finale:
(primo scorrimento verso sinistra)
(secondo scorrimento verso sinistra)
Quando una funzione restituisce un valore, lo fa inserendolo implicitamente nello stack. In questo
modo, l’assegnamento a una variabile, così come si è abituati nei linguaggi di programmazione
comuni, non c’è. Al massimo si definisce una funzione che restituisce un valore, inserendolo
nello stack.
A questo punto si può cominciare a comprendere che i dati inseriti nello stack, quando ciò non
avviene per mezzo di una funzione che restituisce qualcosa, devono avere una rappresentazione
formale. Può trattarsi di: valori numerici, che si scrivono come sono, utilizzando il punto per
separare la parte decimale; stringhe, che sono delimitate da parentesi tonde e possono contenere delle sequenze di escape; espressioni, che sono delimitate tra parentesi graffe (si ricordi
il caso della funzione ‘repeat’). I valori logici, Vero e Falso, non hanno una rappresentazione
particolare e si indicano espressamente solo attraverso le funzioni ‘true’ e ‘false’.
Tabella 226.1. Rappresentazione dei dati e gestione dello stack.
Istruzione
intero .decimale
(stringa )
{espressione }
clear
oggetto pop
oggetto_1 oggetto_2 exch
m n roll
oggetto dup
[
]
Descrizione
Inserisce il valore numerico nello stack.
Inserisce la stringa nello stack.
Inserisce le istruzioni nello stack.
Svuota lo stack.
Preleva dallo stack l’ultimo valore inserito.
Scambia gli ultimi due valori nello stack.
Fa scorrere gli ultimi m elementi dello stack di n posizioni.
Preleva l’ultimo valore e ne inserisce due copie nello stack.
226.2 Funzioni comuni
Alcune funzioni operano su valori numerici, restituendo un risultato che, secondo la logica del
linguaggio PostScript, viene inserito nello stack. Per esempio, la funzione ‘add’ riceve due valori
restituendo la somma di questi:
10 20 add 40 moveto
In questo caso, vengono sommati i valori 10 e 20, inserendo nello stack il valore 30. Così, si
ottiene lo spostamento nelle coordinate 30,40, attraverso la funzione ‘moveto’.
I valori logici, come accennato, si indicano attraverso le funzioni ‘true’ e ‘false’, che si limitano rispettivamente a inserire nello stack il valore corrispondente. Possono generare risultati
logici anche alcune funzioni di confronto e i valori logici possono essere rielaborati attraverso
funzioni booleane. Infine, in base a un valore logico è possibile eseguire o meno un gruppo di
espressioni. Si osservino gli esempi seguenti.
•
10 20 lt
La funzione ‘lt’ confronta due valori e restituisce Vero se il primo (secondo la lettura
umana) è minore. In questo caso, viene restituito Vero.
•
10 20 lt 45 34 gt and
PostScript: espressioni e funzioni
2430
La funzione ‘and’ restituisce Vero se riceve due valori Vero simultaneamente. In questo
caso, la funzione ‘lt’ inserisce il valore Vero nello stack e anche la funzione ‘gt’ inserisce
un altro valore Vero, dal momento che il confrontando i valori 45 e 34 si vede che il primo
è maggiore del secondo.
•
10 20 lt {45 50 moveto} if
La funzione ‘if’ preleva un valore logico e un gruppo di istruzioni. Se il valore logico è Vero
viene eseguito il raggruppamento di istruzioni. In questo caso, dato che la funzione ‘lt’
inserisce il valore Vero nello stack, così può essere eseguito lo spostamento nelle coordinate
45,50.
•
10 20 lt {45 50 moveto} {50 45} moveto ifelse
La funzione ‘ifelse’ preleva un valore logico e due gruppi di istruzioni. Se il valore logico
è Vero viene eseguito il primo gruppo di istruzioni, altrimenti viene eseguito il secondo.
In questo caso, dato che la funzione ‘lt’ inserisce il valore Vero nello stack, così viene
eseguito lo spostamento nelle coordinate 45,50.
Queste funzioni vengono descritte brevemente nella tabella 226.2.
Tabella 226.2. Espressioni matematiche, logiche e condizionali.
Istruzione
n neg
m n add
m n sub
m n mul
m n div
m n mod
n round
n abs
n sin
n cos
m n min
m n max
true
false
m n gt
m n ge
m n lt
m n le
m n eq
m n ne
bool {istruzioni } if
bool {istr_1} {istr_2} ifelse
Descrizione
Inverte il segno del valore.
Somma i due valori.
Sottrae n da m .
Moltiplica i valori.
Divide m per n .
Il resto della divisione intera di m per n .
Arrotonda n .
Calcola il valore assoluto di n .
Calcola il seno di n .
Calcola il coseno di n .
Restituisce il minimo tra due valori.
Restituisce il massimo tra due valori.
Vero.
Falso.
Vero se m è maggiore di n .
Vero se m è maggiore o uguale a n .
Vero se m è minore di n .
Vero se m è minore o uguale a n .
Vero se i valori sono uguali.
Vero se i valori sono diversi.
Esegue le istruzioni se il valore logico è Vero.
Esegue il primo o il secondo gruppo di istruzioni in base al
valore logico.
226.3 Operazioni sulle stringhe
A causa della struttura del linguaggio, la gestione delle stringhe non è affatto intuitiva: bisogna
tradurre tutto nell’ottica dello stack. Tanto per cominciare, la cosa più semplice che si può fare
con una stringa è misurarne la lunghezza con l’aiuto della funzione ‘stringwidth’. Per la precisione, si tratta di determinare la posizione finale di una stringa collocata a partire dalle coordinate
0,0:
stringa stringwidth
PostScript: espressioni e funzioni
2431
Se si osserva la figura 226.3, si può vedere la stringa composta dalla parola «Ciao», scritta con
il carattere Helvetica, avente un corpo di 12 punti. Come si vede, la sua lunghezza è di 24,672
punti.
Figura 226.3. Lunghezza di una stringa.
0,0
Ciao
24.672
Quando c’è la necessità di convertire un valore in una stringa, si pone il problema dell’allocazione
di memoria per la stringa stessa. Per esempio, la funzione ‘cvs’ converte un valore in stringa, ma
per farlo deve avere già una stringa da prelevare dallo stack:
valore stringa cvs
Volendo convertire il valore 23,45 in stringa, bisogna preparare prima una stringa di almeno
cinque caratteri:
23.45 (
) cvs
Per allocare una stringa, composta da caratteri <NUL>, ovvero 0008, si può usare la funzione
‘string’, che richiede l’indicazione della quantità di caratteri. Pertanto, la stessa cosa avrebbe
potuto essere scritta nel modo seguente:
23.45 5 string cvs
Naturalmente, la funzione ‘cvs’ si può usare per visualizzare la stringa generata, per esempio nel
modo seguente:
10 10 moveto
23.45
5 string cvs
show
Si osservi che con ‘cvs’, anche se si alloca una stringa più grande del necessario, questa viene
ridotta alla dimensione richiesta dalla conversione.
Tabella 226.3. Espressioni relative a stringhe.
Istruzione
n string
stringa stringwidth
valore stringa cvs
Descrizione
Alloca una string di n caratteri <NUL>.
Inserisce le coordinate finali della stringa nello stack.
Restituisce una stringa corrispondente al valore.
2432
PostScript: espressioni e funzioni
226.4 Funzioni
Una funzione si definisce attraverso la sintassi seguente:
/nome {istruzioni } def
In pratica, si vuole fare in modo che usando il nome indicato, si faccia riferimento
automaticamente al gruppo di istruzioni contenuto tra parentesi graffe.2
Come per qualunque altra funzione normale, anche le funzioni definite in questo modo ricevono gli argomenti della chiamate dallo stack. Per esempio, la funzione ‘quadrilatero’ che si
potrebbe dichiarare nel modo seguente,
/quadrilatero { newpath moveto lineto lineto lineto closepath stroke } def
va usata mettendo davanti, ordinatamente gli argomenti per le varie funzioni utilizzate. Per esempio, volendo disegnare un quadrato con gli angoli nelle coordinate 0,0, 0,10, 10,10 e 10,0, si
dovrà usare la funzione ‘quadrilatero’ nel modo seguente:
10 0 10 10 0 10 0 0 rettangolo
È importante osservare che la prima coppia di coordinate è quella presa in considerazione
dall’ultima funzione ‘lineto’ contenuta nel raggruppamento di ‘quadrilatero’.
Così come si definisce una funzione, si può attribuire a un nome un valore costante. In questi casi
eccezionali, è consentito l’eliminazione delle parentesi graffe:
/nome costante def
Con la definizione di costanti, si può stabilire una volta per tutte il valore di qualcosa, come
nell’esempio seguente:
/Margine_Sinistro 80 def
/Margine_Destro 80 def
/Margine_Superiore 100 def
/Margine_Inferiore 100 def
226.4.1 Variabili
Nel linguaggio PostScript non è prevista la gestione di variabili: tutto viene elaborato attraverso
lo stack. Tuttavia, esiste un trucco per ottenere qualcosa che assomigli a delle variabili; si tratta di
sfruttare opportunamente la definizione di funzioni. È già stato visto l’assegnamento di un valore
costante a un nome:
/nome costante def
oppure:
/nome { costante } def
Se si vuole attribuire a una funzione un valore diverso, occorre un trucco, che si può
schematizzare come segue:
/nome_1 { /nome_2 exch def } def
Si tratta di una funzione che ne dichiara un’altra, ma si osservi con attenzione: la parola chiave
‘exch’ non è racchiusa tra parentesi graffe e non può esserlo, se si vuole che il meccanismo
funzioni.
Per assegnare un valore alla funzione nome_2 , si utilizza una chiamata alla funzione nome_1 :
2
Eccezionalmente, se si tratta di definire una costante o se si vuole ridefinire il nome di un’altra funzione, non sono
necessarie le parentesi graffe.
PostScript: espressioni e funzioni
2433
n nome_1
Per leggere il valore, si fa riferimento alla funzione nome_2 , come nell’esempio seguente in cui
si utilizza questo dato come coordinata Y per uno spostamento:
n nome_1
m nome_2 moveto
226.5 Dizionari
La dichiarazione delle funzioni può essere inserita in un dizionario, da richiamare quando serve
e da sostituire eventualmente con altre di un altro dizionario, quando la situazione lo richiede. In
pratica, la definizione di dizionari di funzioni consente di fare riferimento a gruppi di funzioni
solo nell’ambito di un certo contesto, ripristinando un utilizzo differente delle stesse subito dopo.
/dizionario n dict def
dizionario begin
dichiarazione_di_funzione
...
...
end
Il modello sintattico mostra in che modo procedere alla dichiarazione di un dizionario. Si può
osservare che prima della parola chiave ‘dict’ occorre indicare un numero, allo scopo di definire
una quantità di memoria da allocare per il dizionario stesso. Per abilitare l’uso delle funzioni
dichiarate nel dizionario, si deve dichiarare espressamente:
dizionario begin
istruzione
...
...
end
Eventualmente, la dichiarazione di utilizzo di un dizionario si può annidare; quando si raggiunge
la parola chiave ‘end’, termina il campo di azione dell’ultimo dizionario ancora aperto.
In generale, potrebbe essere conveniente inserire la dichiarazione dei dizionari nell’ambito delle
istruzioni speciali ‘%%BeginProlog’ e ‘%%EndProlog’. L’esempio seguente mostra un estratto
di un file PostScript ipotetico, in cui si dichiara un dizionario (molto breve) e lo si utilizza immediatamente nell’ambito della pagina (i puntini di sospensione indicano una parte mancante del
file che non viene mostrata).
%!PS-Adobe-2.0
%%DocumentPaperSizes: a4
%%EndComments
%%BeginProlog
/Mio_Dizionario 50 dict def
Mio_Dizionario begin
/quadrilatero
{
newpath moveto lineto lineto lineto closepath stroke
} def
/Margine_Sinistro 80 def
/Margine_Destro 80 def
/Margine_Superiore 100 def
/Margine_Inferiore 100 def
end
% Fine della dichiarazione del dizionario «Mio_Dizionario»
%%EndProlog
Mio_Dizionario begin
%%Page: 1 1
...
...
...
PostScript: espressioni e funzioni
2434
showpage
%%Page: 2 2
...
...
...
showpage
end
% Fine del campo di azione del dizionario «Mio_Dizionario»
%%Trailer
%%EOF
226.6 Riferimenti
• Cappella Archive
<http://www.cappella.demon.co.uk/index.html>
• David Byram-Wigfield, Practical PostScript
<http://www.cappella.demon.co.uk/bookpdfs/pracpost.pdf>
• Paul Bourke, PostScript Tutorial
<http://astronomy.swin.edu.au/pbourke/dataformats/postscript/>
• David Byram-Wigfield, Making an electronic book
<http://www.cappella.demon.co.uk/tinypdfs/06ebook.pdf>
• First Guide to PostScript
<http://www.cs.indiana.edu/docproject/programming/postscript/postscript.html>
Appunti di informatica libera 2003.01.01 --- Copyright © 2000-2003 Daniele Giacomini -- daniele @ swlibero.org
Capitolo
227
PostScript: caratteri da stampa
Il linguaggio PostScript, nelle sue prime versioni, prevede che il file contenente le istruzioni sia
di tipo ASCII, dove è ammissibile usare gli 8 bit per esteso. Tuttavia, l’insieme di caratteri a
disposizione non è il solito ISO 8859-1, ma qualcosa di diverso che può essere visto nella tabella
227.1.
Tabella 227.1. Insieme di caratteri normale del linguaggio PostScript.
*
*
*
\037
\000
\040
\100
\140
! " # $ % & ’ ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ?
@ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _
‘ a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~
\200
\240
\300
\340
\077
\137
\177
\237
¡ ¢ £ ⁄ ¥ ƒ § ¤ ' “ « ‹ › fi fl
– † ‡ ·
¶ • ‚ „ ” » … ‰
` ´ ˆ ˜ ¯ ˘ ˙ ¨
˚ ¸
˝ ˛ ˇ —
Æ
ª
Ł Ø Œ º
æ
ı
ł ø œ ß
¿
\277
\337
\377
Per fare riferimento a un simbolo in forma numerica, basta indicare il numero ottale corrispondente, di tre cifre, preceduto dalla barra obliqua inversa. Per facilitare la lettura, la tabella mostra
questo modo di fare riferimento ai caratteri, all’inizio e alla fine di ogni riga.
Per poter usare la codifica corrispondente allo standard ISO 8859-1, è necessario dare delle istruzioni particolari. Volendo sbirciare nel codice PostScript generato da vari sistemi di composizione, si potrà osservare che ognuno utilizza un proprio modo, più o meno sofisticato. Probabilmente, la tecnica più semplice è quella che si può leggere nei sorgenti di Ghostscript, dove vengono
dichiarate due funzioni apposite nel modo seguente:
/font-to-iso-latin-1
{
dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall
/Encoding ISOLatin1Encoding def currentdict end
dup /FontName get 80 string cvs (-ISOLatin1) concatstrings cvn
exch definefont
} def
/find-latin-font
{
findfont font-to-iso-latin-1
} def
In questo modo, quando si va a dichiarare l’uso di un certo tipo di carattere da stampa, invece
dell’istruzione
/carattere findfont dimensione scalefont setfont
si userà piuttosto la forma seguente:
/carattere find-latin-font dimensione scalefont setfont
2435
PostScript: caratteri da stampa
2436
227.1 Aspetto dei caratteri da stampa comuni
Il linguaggio PostScript mette a disposizione pochi tipi di carattere da stampa; tuttavia, è disponibile l’interprete Ghostscript, su moltissime piattaforme, che mette a disposizione un numero
discreto di questi tipi. La tabella 227.13 elenca brevemente i nomi di questi tipi di carattere,
mentre in altre tabelle successive viene mostrato l’aspetto di alcuni di questi, ordinando i simboli
secondo l’insieme ISO 8859-1.
Tabella 227.2. Carattere da stampa AvantGarde.
*
*
*
\037
\000
\040
\100
\140
\200
\240
\300
\340
! " # $ % & ’ ( ) * + , − . / 0 1 2
@ A B C D E F G H I J K L M N O P Q R
‘ a b c d e f g h i j k l mn o p q r
ı ` ´
¡ ¢ £ ¤ ¥ ¦ § ¨ © ª « ¬ - ® ¯ ° ± ²
À Á Â Ã Ä Å Æ Ç È É Ê Ë Ì Í Î Ï Ð Ñ Ò
à á â ã ä å æ ç è é ê ë ì
3
S
s
ˆ
³
Ó
4
T
t
˜
´
Ô
5
U
u
¯
µ
Õ
6
V
v
˘
¶
Ö
7
W
w
˙
·
×
8
X
x
¨
¸
Ø
ø
9 :
Y Z
y z
˚
¹ º
Ù Ú
ú
;
[
{
¸
»
Û
< = >
\ ] ^
| } ~
˝ ˛
¼ ½ ¾
Ü Ý Þ
8
X
x
¨
¸
Ø
ø
9 :
Y Z
y z
˚
¹ º
Ù Ú
ú
;
[
{
¸
»
Û
8
X
x
¨
¸
Ø
ø
9 : ; <
Y Z [ \
y z { |
˚ ¸
¹ º » ¼
Ù Ú Û Ü
ú
?
_
\077
\137
\177
ˇ
¿
ß
\237
\277
\337
\377
Tabella 227.3. Carattere da stampa Bookman.
*
*
*
\037
\000
\040
\100
\140
\200
\240
\300
\340
! " # $ % & ’ ( ) * + , − . / 0 1 2
@ A B C D E F G H I J K L M N O P Q R
‘ a b c d e f g h i j k l mn o p q r
ı ` ´
¡ ¢ £ ¤ ¥ ¦ § ¨ © ª « ¬ - ® ¯ ° ± ²
À Á Â Ã Ä Å Æ Ç È É Ê Ë Ì Í Î Ï Ð Ñ Ò
à á â ã ä å æ ç è é ê ë ì
3
S
s
ˆ
³
Ó
4
T
t
˜
´
Ô
5
U
u
¯
µ
Õ
6
V
v
˘
¶
Ö
7
W
w
˙
·
×
< = >
\ ] ^
| } ~
˝ ˛
¼ ½ ¾
Ü Ý Þ
?
_
\077
\137
\177
ˇ
¿
ß
\237
\277
\337
\377
Tabella 227.4. Carattere da stampa Courier.
*
*
*
\037
\000
\040
\100
\140
\200
\240
\300
\340
! " # $ % & ’ ( ) * + , − . / 0
@ A B C D E F G H I J K L M N O P
‘ a b c d e f g h i j k l m n o p
ı
¡ ¢ £ ¤ ¥ ¦ § ¨ © ª « ¬ - ® ¯ °
À Á Â Ã Ä Å Æ Ç È É Ê Ë Ì Í Î Ï Ð
à á â ã ä å æ ç è é ê ë ì
1
Q
q
`
±
Ñ
2
R
r
´
²
Ò
3
S
s
ˆ
³
Ó
4
T
t
˜
´
Ô
5
U
u
¯
µ
Õ
6
V
v
˘
¶
Ö
7
W
w
˙
·
×
=
]
}
˝
½
Ý
>
^
~
˛
¾
Þ
?
_
\077
\137
\177
ˇ
¿
ß
\237
\277
\337
\377
Tabella 227.5. Carattere da stampa Helvetica.
*
*
*
\037
\000
\040
\100
\140
\200
\240
\300
\340
! " # $ % & ’ ( )
@A B C D E F G H I
‘ a b c d e f g h i
* + , − . / 0 1 2
J K L M N O P Q R
j k l m n o p q r
ı ` ´
¡ ¢ £ ¤ ¥ ¦ § ¨ © ª « ¬ - ® ¯ ° ± ²
À Á Â Ã Ä Å ÆÇ È É Ê Ë Ì Í Î Ï Ð Ñ Ò
à á â ã ä å æ ç è é ê ë ì
3
S
s
ˆ
³
Ó
4
T
t
˜
´
Ô
5
U
u
¯
µ
Õ
6
V
v
˘
¶
Ö
7
W
w
˙
·
×
8
X
x
¨
¸
Ø
ø
9 :
Y Z
y z
˚
¹ º
Ù Ú
ú
;
[
{
¸
»
Û
< = >
\ ] ^
| } ~
˝ ˛
¼ ½ ¾
Ü Ý Þ
?
_
\077
\137
\177
ˇ
¿
ß
\237
\277
\337
\377
PostScript: caratteri da stampa
2437
Tabella 227.6. Carattere da stampa NewCenturySchlbk.
*
*
*
\037
\000
\040
\100
\140
\200
\240
\300
\340
! " # $ % & ’ ( ) * + , − . / 0 1 2
@ A B C D E F G H I J K L MN O P Q R
‘ a b c d e f g h i j k l m n o p q r
ı ` ´
¡ ¢ £ ¤ ¥ ¦ § ¨ © ª « ¬ - ® ¯ ° ± ²
À Á Â Ã Ä Å Æ Ç È É Ê Ë Ì Í Î Ï Ð Ñ Ò
à á â ã ä å æ ç è é ê ë ì
3
S
s
ˆ
³
Ó
4
T
t
˜
´
Ô
5
U
u
¯
µ
Õ
6
V
v
˘
¶
Ö
7
W
w
˙
·
×
8
X
x
¨
¸
Ø
ø
9 :
Y Z
y z
˚
¹ º
Ù Ú
ú
;
[
{
¸
»
Û
< = >
\ ] ^
| } ~
˝ ˛
¼ ½ ¾
Ü Ý Þ
8
X
x
¨
¸
Ø
ø
9 :
Y Z
y z
˚
¹ º
Ù Ú
ú
;
[
{
¸
»
Û
8
X
x
¨
¸
Ø
ø
9 :
Y Z
y z
˚
¹ º
Ù Ú
ú
;
[
{
¸
»
Û
8
X
x
¨
¸
Ø
ø
9 : ; <
Y Z [ \
y z { |
˚ ¸
¹ º » ¼
Ù Ú Û Ü
ú
?
_
\077
\137
\177
ˇ
¿
ß
\237
\277
\337
\377
Tabella 227.7. Carattere da stampa Palatino.
*
*
*
\037
\000
\040
\100
\140
\200
\240
\300
\340
! " # $ % & ’ ( ) * + , − . / 0 1 2
@ A B C D E F G H I J K L MN O P Q R
‘ a b c d e f g h i j k l m n o p q r
ı ` ´
¡ ¢ £ ¤ ¥ ¦ § ¨ © ª « ¬ - ® ¯ ° ± ²
À Á Â Ã Ä Å Æ Ç È É Ê Ë Ì Í Î Ï Ð Ñ Ò
à á â ã ä å æ ç è é ê ë ì
3
S
s
ˆ
³
Ó
4
T
t
˜
´
Ô
5
U
u
¯
µ
Õ
6
V
v
˘
¶
Ö
7
W
w
˙
·
×
< = >
\ ] ^
| } ~
˝ ˛
¼ ½ ¾
Ü Ý Þ
?
_
\077
\137
\177
ˇ
¿
ß
\237
\277
\337
\377
Tabella 227.8. Carattere da stampa Times.
*
*
*
\037
\000
\040
\100
\140
\200
\240
\300
\340
! " # $ % & ’ ( )
@ A B C D E F G H I
‘ a b c d e f g h i
* + , − . / 0 1 2
J K L M N O P Q R
j k l m n o p q r
ı ` ´
¡ ¢ £ ¤ ¥ ¦ § ¨ © ª « ¬ - ® ¯ ° ± ²
À Á Â Ã Ä Å Æ Ç È É Ê Ë Ì Í Î Ï Ð Ñ Ò
à á â ã ä å æ ç è é ê ë ì
3
S
s
ˆ
³
Ó
4
T
t
˜
´
Ô
5
U
u
¯
µ
Õ
6
V
v
˘
¶
Ö
7
W
w
˙
·
×
< = >
\ ] ^
| } ~
˝ ˛
¼ ½ ¾
Ü Ý Þ
?
_
\077
\137
\177
ˇ
¿
ß
\237
\277
\337
\377
Tabella 227.9. Carattere da stampa Utopia.
*
*
*
\037
\000
\040
\100
\140
\200
\240
\300
\340
! " # $ % & ’ ( ) * + , − . / 0
@ A B C D E F G H I J K L M N O P
‘ a b c d e f g h i j k l m n o p
ı
¡ ¢ £ ¤ ¥ ¦ § ¨ © ª « ¬ - ® ¯ °
À Á Â Ã Ä Å Æ Ç È É Ê Ë Ì Í Î Ï Ð
à á â ã ä å æ ç è é ê ë ì
1
Q
q
`
±
Ñ
2
R
r
´
²
Ò
3
S
s
ˆ
³
Ó
4
T
t
˜
´
Ô
5
U
u
¯
µ
Õ
6
V
v
˘
¶
Ö
7
W
w
˙
·
×
=
]
}
˝
½
Ý
>
^
~
˛
¾
Þ
?
_
\077
\137
\177
ˇ
¿
ß
\237
\277
\337
\377
PostScript: caratteri da stampa
2438
Tabella 227.10. Carattere da stampa ZapfChancery.
*
*
*
\037
\000
\040
\100
\140
\200
\240
\300
\340
! " # $ % & ’ ( ) * + , − . / 0 1 2
@ A B C D E F G H I J K L M N O P Q R
‘ a b c d e f g h i j k l m n o p q r
ı ` ´
¡ ¢ £ ¤ ¥ ¦ § ¨ © ª « ¬ - ® ¯ ° ± ²
À Á Â Ã Ä Å Æ Ç È É Ê Ë Ì Í Î Ï Ð Ñ Ò
à á â ã ä å æ ç è é ê ë ì
3
S
s
ˆ
³
Ó
4
T
t
˜
´
Ô
5
U
u
¯
µ
Õ
6
V
v
˘
¶
Ö
7
W
w
˙
·
×
8
X
x
¨
¸
Ø
ø
9 :
Y Z
y z
˚
¹ º
Ù Ú
ú
;
[
{
¸
»
Û
< = >
\ ] ^
| } ~
˝ ˛
¼ ½ ¾
Ü Ý Þ
?
_
\077
\137
\177
ˇ
¿
ß
\237
\277
\337
\377
Tabella 227.11. Carattere da stampa ZapfDingbats (solo con l’insieme di caratteri
normale).
*
*
*
\037
\000
\040
\100
\140
✁✂✃✄☎ ✆ ✇ ✈ ✉ ☛☞✌ ✍ ✎ ✏ ✐ ✑✒✓ ✔ ✕ ✖ ✗ ✘ ✙ ✚ ✛ ✜ ✝ ✞ ✟
✠ ✡ ✢ ✣ ✤ ✥ ✦ ✧ ★ ✩ ✪ ✫ ✬ ✭ ✮ ✯ ✰ ✱ ✲ ✳ ✴ ✵ ✶ ✷ ✸ ✹ ✺ ✻ ✼ ✽ ✾ ✿
❀ ❁ ❂ ❃ ❄ ❅ ❆ ❇ ❈ ❉ ❊ ❋ ● ❍ ■ ❏ ❐ ❑ ❒ ▲ ▼ ◆ ❖ ◗ ❘ ❙ ❚ ❛ ❜ ❝ ❞
\200
\240
\300
\340
\077
\137
\177
\237
❡ ❢ ❣ ❤ ❥ ❦ ❧ ♣ ♦ ♥ ♠ ① ② ③ ④ ⑤ ⑥ ⑦ ⑧ ⑨ ⑩ ❶ ❷ ❸ ❹ ❺ ❻ ❼ ❽ ❾ ❿
➀ ➁ ➂ ➃ ➄ ➅ ➆ ➇ ➈ ➉ ➊ ➋ ➌ ➍ ➎ ➏ ➐ ➑ ➒ ➓ ➔ → ↔↕ ➘ ➙ ➚ ➛ ➜ ➝ ➞ ➟
➠ ➡ ➢ ➣ ➤ ➥ ➦ ➧ ➨ ➩ ➪ ➫ ➬ ➭ ➮ ➯
➱ ➲ ➳➴ ➵ ➶ ➷ ➸➹ ➺ ➻ ➼ ➽➾
\277
\337
\377
Tabella 227.12. Carattere da stampa Symbol (solo con l’insieme di caratteri normale).
*
*
*
\037
\000
\040
\100
\140
! ∀ # ∃ % & ∋ ( )
≅ Α Β Χ ∆ Ε Φ Γ Η Ι
 α β χ δ ε φ γ η ι
∗ + , − . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ?
ϑ Κ Λ Μ Ν Ο Π Θ Ρ Σ Τ Υ ς Ω Ξ Ψ Ζ [ ∴ ] ⊥ _
ϕ κ λ µ ν ο π θ ρ σ τ υ ϖ ω ξ ψ ζ { | } ∼
\200
\240
\300
\340
\077
\137
\177
\237
ϒ ′ ≤ ⁄ ∞ ƒ ♣ ♦ ♥ ♠ ↔←↑ →↓ ° ± ″ ≥ × ∝ ∂ • ÷ ≠ ≡ ≈ … ↵
ℵ ℑ ℜ ℘⊗ ⊕ ∅ ∩ ∪ ⊃ ⊇ ⊄ ⊂ ⊆ ∈ ∉ ∠ ∇    ∏ √ ⋅ ¬ ∧ ∨ ⇔⇐⇑ ⇒⇓
◊ 〈    ∑          
〉 ∫ ⌠  ⌡         
Tabella 227.13. Nomi dei tipi di carattere da stampa che solitamente sono disponibili
con Ghostscript.
Nome
AvantGarde-Book
AvantGarde-BookOblique
AvantGarde-Demi
AvantGarde-DemiOblique
Bookman-Demi
Bookman-DemiItalic
Bookman-Light
Bookman-LightItalic
Courier
Courier-Bold
Courier-BoldOblique
Courier-Oblique
Helvetica
Helvetica-Bold
Helvetica-BoldOblique
Helvetica-Narrow
Helvetica-Narrow-Bold
Descrizione
AvantGarde normale.
AvantGarde inclinato.
AvantGarde neretto.
AvantGarde neretto obliquo.
Bookman neretto.
Bookman neretto corsivo.
Bookman normale.
Bookman corsivo.
Courier normale.
Courier neretto.
Courier neretto inclinato.
Courier inclinato.
Helvetica normale.
Helvetica neretto.
Helvetica neretto inclinato.
Helvetica stretto.
Helvetica stretto neretto.
\277
\337
\377
PostScript: caratteri da stampa
Nome
Helvetica-Narrow-BoldOblique
Helvetica-Narrow-Oblique
Helvetica-Oblique
NewCenturySchlbk-BoldItalic
NewCenturySchlbk-Bold
NewCenturySchlbk-Italic
NewCenturySchlbk-Roman
Palatino-Bold
Palatino-BoldItalic
Palatino-Italic
Palatino-Roman
Times-Bold
Times-BoldItalic
Times-Italic
Times-Roman
ZapfChancery-MediumItalic
ZapfDingbats
Symbol
2439
Descrizione
Helvetica stretto neretto inclinato.
Helvetica stretto inclinato.
Helvetica inclinato.
NewCenturySchlbk neretto corsivo.
NewCenturySchlbk neretto.
NewCenturySchlbk corsivo.
NewCenturySchlbk normale.
Palatino neretto.
Palatino neretto corsivo.
Palatino corsivo.
Palatino normale.
Times neretto.
Times neretto inclinato.
Times corsivo.
Times normale.
ZapfChancery-MediumItalic medio corsivo.
ZapfDingbats (solo con l’insieme di caratteri normale).
Symbol (solo con l’insieme di caratteri normale).
227.2 Distorsione e spostamento dei caratteri da stampa
Fino a questo punto è stato visto come selezionare un carattere da stampa con l’istruzione
/carattere findfont dimensione scalefont setfont
oppure con quella seguente, nel caso sia disponibile la funzione relativa:
/carattere find-latin-font dimensione scalefont setfont
In alternativa, è possibile sostituire l’indicazione della dimensione con qualcosa di più articolato,
secondo uno dei due schemi seguenti:
/carattere findfont [dim_x rot_x rot_y dim_y sp_x sp_y ] makefont setfont
/carattere find-latin-font [dim_x rot_x rot_y dim_y sp_x sp_y ] makefont setfont
Tra parentesi quadre appaiono una serie di valori, che se non utilizzati vanno lasciati azzerati. Per
comprenderne il significato, conviene partire dalla situazione normale. Supponendo di volere dichiarare un carattere da stampa di tipo Helvetica, normale, di 12 punti, si può usare la definizione
solita
/Helvetica findfont 12 scalefont setfont
oppure, in modo più complesso, quella seguente:
/Helvetica findfont [12 0 0 12 0 0] makefont setfont
In pratica, dim_x e dim_y servono per definire la dimensione orizzontale e verticale del carattere.
In condizioni normali, la dimensione è la stessa; diversamente, con una dimensione orizzontale
più grande di quella verticale si ottiene un carattere più largo, mentre con una dimensione verticale maggiore di quella orizzontale, si ottiene un carattere alto (o sottile). Si osservi l’esempio
seguente, di un carattere Helvetica allargato e successivamente alzato. Il risultato, in rapporto, si
può vedere nella figura 227.1.
/Helvetica findfont [30 0 0 12 0 0] makefont setfont
/Helvetica findfont [12 0 0 30 0 0] makefont setfont
PostScript: caratteri da stampa
2440
Figura 227.1. Distorsione orizzontale e verticale del carattere da stampa.
Helvetica allargato
Helvetica alzato (stretto)
I valori corrispondenti a rot_x e rot_y permettono di inclinare l’asse X o l’asse Y del testo. In
pratica, modificando rot_x si cambia l’andamento orizzontale del testo secondo l’angolo indicato. Per esempio un angolo di 10 gradi farà sì che la riga scritta sia inclinata verso l’alto (ovvero
di 10 gradi in senso antiorario), mentre un angolo di -10 gradi genererà una riga inclinata verso
il basso. La figura 227.2 mostra il risultato che si può ottenere con le due distorsioni seguenti:
/Helvetica findfont [12 10 0 12 0 0] makefont setfont
/Helvetica findfont [12 -10 0 12 0 0] makefont setfont
Figura 227.2. Distorsione dell’inclinazione orizzontale.
te
ra
n
ce
s
a
n
de
tu
rit
c
S
S
cr
itt
u
ra
di
sc
en
de
nt
e
Intervenendo invece nel valore rot_y, si cambia l’inclinazione del carattere, senza cambiare l’andamento della riga. In pratica, valori positivi dell’angolazione generano un’inclinazione in avanti,
simile a un corsivo, mentre valori negativi generano un’inclinazione all’indietro. La figura 227.3
mostra il risultato che si può ottenere con le due distorsioni seguenti:
/Helvetica findfont [12 0 10 12 0 0] makefont setfont
/Helvetica findfont [12 0 -10 12 0 0] makefont setfont
PostScript: caratteri da stampa
2441
Figura 227.3. Distorsione dell’inclinazione verticale.
Inclinato in avanti
Inclinato all’indietro
I valori corrispondenti a sp_x e sp_y rappresentano uno spostamento orizzontale e verticale, in
punti, senza applicare delle distorsioni vere e proprie.
L’andamento del testo, che normalmente si svolge da sinistra a destra, può essere invertito, assegnando un valore negativo per il primo valore, ovvero per dim_x . La figura 227.4 mostra la
comparazione tra un testo scritto in modo normale e un altro che invece si sviluppa verso sinistra,
con un comando simile a quello seguente:
/Helvetica findfont [-12 0 0 12 0 0] makefont setfont
Figura 227.4. Scrittura normale e scrittura da destra a sinistra.
Andamento normale
otitrevni otnemadnA
Così come si può invertire l’andamento del testo in orizzontale, si può invertire in modo verticale,
ottenendo una sorta di riflessione. La figure 227.5 mette a confronto un testo scritto in modo
normale e un altro modificato con l’istruzione seguente:
/Helvetica findfont [12 0 0 -12 0 0] makefont setfont
Figura 227.5. Scrittura ruotata sull’asse orizzontale.
Scrittura
normale
Scrittura riflessa
227.3 Riferimenti
• Cappella Archive
<http://www.cappella.demon.co.uk/index.html>
• David Byram-Wigfield, Practical PostScript
<http://www.cappella.demon.co.uk/bookpdfs/pracpost.pdf>
• Paul Bourke, PostScript Tutorial
<http://astronomy.swin.edu.au/pbourke/dataformats/postscript/>
PostScript: caratteri da stampa
2442
• David Byram-Wigfield, Making an electronic book
<http://www.cappella.demon.co.uk/tinypdfs/06ebook.pdf>
• First Guide to PostScript
<http://www.cs.indiana.edu/docproject/programming/postscript/postscript.html>
Appunti di informatica libera 2003.01.01 --- Copyright © 2000-2003 Daniele Giacomini -- daniele @ swlibero.org
Capitolo
228
Esempi di funzioni PostScript
In questo capitolo si raccolgono alcuni esempi di funzioni PostScript che possono essere utili a
vario titolo. Trattandosi di un linguaggio specifico per la stampa, non vengono proposti esempi
di programmazione standard.
228.1 Unità di misura
L’unità di misura utilizzata è sempre il punto tipografico, che in questo ambito corrisponde a
1/72-esimo di pollice, ovvero a 0,3527777 mm (per converso, un millimetro è pari a 2,834646
punti). Volendo usare unità di misura più comuni, si possono realizzare alcune funzioni molto
semplici che si limitano a moltiplicare il valore per una costante, in modo da ottenere come
risultato l’equivalente in punti:
/cm
/mm
/pt
/in
{
{
{
{
28.346456 mul } def
2.8346456 mul } def
1 mul } def
72 mul } def
%
%
%
%
<n>
<n>
<n>
<n>
cm
mm
pt
in
%
%
%
%
converte centimetri in punti
converte millimetri in punti
non converte alcunché
converte pollici in punti
In questo modo, al posto di inserire un valore puro e semplice, basta aggiungere subito dopo la
sigla dell’unità di misura, che in realtà è una funzione. Per esempio:
3 cm 18 cm moveto
Evidentemente, la funzione ‘pt’ è inutile, ma può servire per mantenere coerenza con il resto,
nel momento in cui si utilizzi sistematicamente questo meccanismo per indicare le coordinate o
le distanze.
228.2 Funzioni diagnostiche
Pur non trattandosi di un linguaggio di programmazione normale, quando si cerca di realizzare
qualcosa di particolare, può essere comoda la possibilità di mostrare un valore da qualche parte,
per verificare il contenuto di una data informazione.
/diag_display_number % <n> <x> <y> diag_display_number
{
gsave
/Helvetica findfont 10 scalefont setfont
moveto
100 string cvs show
grestore
} def
La funzione appena mostrata, serve per ottenere la conversione di un numero in stringa, che poi
viene visualizzato nelle coordinate previste. Andrebbe usata nel modo seguente, dove x ,y sono
le coordinate a partire dalle quali mostrare il valore:
n x y diag_display_number
Dal momento che questa funzione preleva il valore dallo stack, potrebbe essere conveniente la
duplicazione di tale valore prima di utilizzarlo:
n dup x y diag_display_number
Volendo completare il problema con una funzione equivalente per la visualizzazione delle
stringhe, basta la variante seguente:
/diag_display_string % <stringa> <x> <y> diag_display_string
{
2443
Esempi di funzioni PostScript
2444
gsave
/Helvetica findfont 10 scalefont setfont
moveto
show
grestore
} def
228.3 Gestione di stringhe
Quando si disegnano delle figure o dei grafici, può essere comodo disporre di qualche funzione
che faciliti la collocazione di didascalie o di annotazioni di qualunque tipo. Qui viene proposto
un sistema molto semplice, con cui è possibile piazzare delle stringhe allineate correttamente a
sinistra, a destra o al centro, date le coordinate di riferimento. Si parte con la definizione di alcune
«variabili», che servono per fissare i punti di riferimento delle stringhe:
/set_line_t
/set_line_l
/set_line_r
/set_line_c
/set_line_h
{
{
{
{
{
/line_t
/line_l
/line_r
/line_c
/line_h
exch
exch
exch
exch
exch
def
def
def
def
def
}
}
}
}
}
def
def
def
def
def
La funzione ‘line_t’ verrà usata per conoscere la posizione verticale (Y) della stringa da collocare; la funzione ‘line_l’ servirà per fornire la posizione iniziale (X) di una stringa da allineare
a sinistra; ‘line_r’ fornirà la posizione finale (X) di una stringa da allineare a destra; ‘line_c’
fornirà la posizione centrale (X) di una stringa da centrare; infine, ‘line_h’ servirà per conoscere
la distanza tra le righe.
Per usare le funzioni che verranno presentate, dovranno essere impostati inizialmente i valori
per le variabili appena descritte. Per esempio, sapendo che si vuole scrivere un testo allineato
a sinistra a partire dalla coordinata 100,50, con una distanza tra le righe di 14 punti, basterà
impostare i valori nel modo seguente:
50 set_line_t
100 set_line_l
14 set_line_h
Dal momento che non si devono centrare le righe e nemmeno allineare a destra, le altre variabili
non servono, altrimenti occorrerebbe impostare ‘line_c’ o ‘line_r’, al posto di ‘line_l’.
/show_line_left % <stringa> show_line_left
{
% Si posiziona all’inizio della riga.
line_l line_t moveto
% Mostra la riga.
show
% Sottrae alla posizione Y l’altezza della riga.
line_t line_h sub set_line_t
} def
Si osservi la funzione ‘show_line_left’: si usano i valori restituiti dalle funzioni ‘line_l’ e
‘line_t’ per impostare le coordinate iniziali, quindi si visualizza la stringa. Subito dopo si provvede a ridurre il valore della variabile corrispondente alla funzione ‘line_t’ del valore restituito
da ‘line_h’ (la distanza tra le righe), in modo da poter continuare con la visualizzazione di altre
stringhe, con lo stesso allineamento sinistro, subito sotto quella appena inserita.
/show_line_right % <stringa> show_line_right
{
% Calcola la lunghezza della riga.
dup % fa una copia della stringa
stringwidth % restituisce le coordinate finali X e Y
Esempi di funzioni PostScript
2445
pop % elimina la coordinata Y
% Sottrae dalla posizione destra la lunghezza della riga,
% cambiando poi il segno.
line_r sub neg
% Si posiziona correttamente.
line_t moveto
% Mostra la riga e va all’inizio di una riga nuova.
show
% Sottrae alla posizione Y l’altezza della riga.
line_t line_h sub set_line_t
} def
La funzione ‘show_line_right’ è molto simile, con la differenza che occorre fare qualche
calcolo per individuare la posizione orizzontale di inizio, sapendo la posizione finale ottenuta
dalla funzione ‘line_r’. Per questo, viene fatta una copia della stringa, che quindi viene misurata
con la funzione ‘setlinewidth’. Da questa misurazione si espelle l’informazione verticale, che
risulta inutile, sottraendo poi a questa il valore restituito da ‘line_r’. Quello che si ottiene è la
distanza dalla posizione destra finale, con segno invertito, pertanto si inverte nuovamente con la
funzione ‘neg’. Disponendo della coordinata X, si aggiunge la coordinata Y, data da ‘line_t’,
spostando la posizione corrente, per poi mostrare la stringa e infine preparare nuovamente la
posizione verticale per una nuova riga.
/show_line_center
{
% Calcola la lunghezza della riga.
dup % fa una copia della stringa
stringwidth % restituisce le coordinate finali X e Y
pop % elimina la coordinata Y
2 div % divide la lunghezza a metà
% Sottrae dal centro la metà della riga, cambiando poi il segno.
line_c sub neg
% Si posiziona correttamente.
line_t moveto
% Mostra la riga e va all’inizio di una riga nuova.
show
% Sottrae alla posizione Y l’altezza della riga.
line_t line_h sub set_line_t
} def
La funzione ‘show_line_center’ centra la stringa in riferimento alla posizione ‘line_c’. I
calcoli sono simili a quelli per l’allineamento a destra, con la differenza che la distanza dal centro
è pari alla metà della lunghezza della stringa. Il resto è equivalente.
L’esempio seguente mostra come scrivere qualcosa con queste funzioni; la figura 228.1 mostra il
risultato che si ottiene osservando il riquadro che va da 0,0 a 150,100:
/Times-Roman findfont 10 scalefont setfont
90
10
140
75
14
set_line_t
set_line_l
set_line_r
set_line_c
set_line_h
(Stringa a sinistra) show_line_left
(Stringa centrata) show_line_center
(Stringa a destra) show_line_right
Esempi di funzioni PostScript
2446
(Ciao) show_line_center
() show_line_center
(:-\)) show_line_center
showpage
Figura 228.1. Esempio nell’uso delle funzioni sulle stringhe.
Stringa a sinistra
Stringa centrata
Stringa a destra
Ciao
:-)
Naturalmente, si possono predisporre anche delle abbreviazioni a queste funzioni:
/L { show_line_left } def
/R { show_line_right } def
/C { show_line_center } def
In questo modo, l’indicazione delle stringhe può essere ridotto alla forma seguente:
(Stringa a sinistra) L
(Stringa centrata) C
(Stringa a destra) R
(Ciao) C
() C
(:-\)) C
228.4 Riferimenti
• Cappella Archive
<http://www.cappella.demon.co.uk/index.html>
• David Byram-Wigfield, Practical PostScript
<http://www.cappella.demon.co.uk/bookpdfs/pracpost.pdf>
• David Byram-Wigfield, The TinyDict Typesetter
<http://www.cappella.demon.co.uk/tinyfiles/tinydict.html>
• David Byram-Wigfield, Tinydict
<http://www.cappella.demon.co.uk/tinyfiles/tinydict.ps>
• David Byram-Wigfield, Making an electronic book
<http://www.cappella.demon.co.uk/tinypdfs/06ebook.pdf>
• First Guide to PostScript
<http://www.cs.indiana.edu/docproject/programming/postscript/postscript.html>
Esempi di funzioni PostScript
Appunti di informatica libera 2003.01.01 --- Copyright © 2000-2003 Daniele Giacomini -- daniele @ swlibero.org
2447
2448
Esempi di funzioni PostScript
Parte xliv
TeX
229 teTeX: la distribuzione Unix di TeX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2453
229.1 Collocazione . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2453
229.2 Configurazione . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2454
229.3 Funzionamento fondamentale di TeX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2457
229.4 Interazione con TeX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2460
229.5 Riferimenti . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2463
230 TeX: introduzione . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2464
230.1 Elementi essenziali del linguaggio TeX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2464
230.2 Variabili e tipi di dati . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2468
230.3 Dichiarazione di macroistruzioni . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2475
230.4 Riferimenti ad altre parole o simboli di controllo . . . . . . . . . . . . . . . . . . . . . . . . . 2478
230.5 Testo normale e ambienti matematici . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2479
230.6 Modalità orizzontale e modalità verticale . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2479
230.7 Strutture di controllo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2480
230.8 Verifica del significato di un’istruzione elementare . . . . . . . . . . . . . . . . . . . . . . . 2481
230.9 Riferimenti . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2482
231 TeX: caratteri . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2483
231.1 Caratteri speciali . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2483
231.2 Accenti . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2484
231.3 Apici, trattini e legati automatici . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2485
231.4 Istruzioni alternative per generare simboli particolari . . . . . . . . . . . . . . . . . . . . . 2486
231.5 Caratteri da stampa standard . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2487
231.6 Sottolineatura . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2490
232 TeX: la pagina . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2492
232.1 La parte centrale della pagina . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2492
232.2 Intestazione e fondo pagina . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2495
232.3 Numerazione delle pagine . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2496
232.4 Note a piè di pagina . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2496
232.5 Oggetti fluttuanti . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2497
233 TeX: paragrafi, righe, spazi, scatole e linee . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2498
233.1 Caratteristiche normali di un paragrafo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2498
233.2 Spaziatura orizzontale automatica e separazione automatica dei paragrafi in righe
2500
2449
233.3 Rientri particolari . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2501
233.4 Paragrafi etichettati . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2503
233.5 Attuazione dei comandi riferiti ai paragrafi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2504
233.6 Tolleranza estetica . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2505
233.7 Sillabazione . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2506
233.8 Spaziature verticali . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2507
233.9 Righe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2510
233.10 Spazi orizzontali . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2512
233.11 Spazio rigido . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2514
233.12 Scatole . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2514
233.13 Linee guida . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2518
233.14 Linee . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2519
233.15 Scatole più complesse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2520
234 TeX: tabelle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2522
234.1 Tabulazione . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2522
234.2 Tabelle più complesse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2527
235 TeX: ambienti matematici . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2532
235.1 Due situazioni differenti . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2532
235.2 Spazi orizzontali . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2533
235.3 Caratteri e simboli . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2533
235.4 Dimensione del testo matematico . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2539
235.5 Punteggiatura . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2540
235.6 Frazioni e simili . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2540
235.7 Apici e pedici . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2541
235.8 Radici . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2542
235.9 Sottolineature e sopralineature . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2542
235.10 Funzioni . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2543
235.11 Delimitatori . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2544
235.12 Matrici e sistemi di equazioni . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2545
235.13 Dichiarazione di teoremi e corollari . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2547
235.14 Equazioni in evidenza . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2548
236 LaTeX: introduzione . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2550
236.1 Comandi e modelli sintattici . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2550
236.2 Esempio iniziale . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2551
236.3 Struttura essenziale di un documento LaTeX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2554
236.4 Composizione per approssimazione successiva . . . . . . . . . . . . . . . . . . . . . . . . . . . 2556
236.5 Personalizzazione . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2557
236.6 Localizzazione . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2559
236.7 Variabili e tipi di dati . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2562
2450
236.8 Riferimenti . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2566
237 LaTeX: struttura . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2568
237.1 Dichiarazione dello stile generale . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2568
237.2 Preambolo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2569
237.3 Inizio e fine del documento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2569
237.4 Suddivisione del documento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2570
237.5 Ambienti . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2573
238 LaTeX: la pagina . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2575
238.1 Dimensioni della pagina . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2575
238.2 Flusso verticale del testo, colonne e salti pagina . . . . . . . . . . . . . . . . . . . . . . . . . . 2576
238.3 Stile della pagina . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2580
238.4 Numerazione delle pagine . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2581
238.5 Note a piè di pagina . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2581
238.6 Sillabazione . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2582
239 LaTeX: caratteri . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2583
239.1 Caratteri che hanno un significato speciale . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2583
239.2 Corpi uniformi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2584
239.3 Caratteri da stampa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2585
239.4 Definizione dettagliata del carattere da stampa . . . . . . . . . . . . . . . . . . . . . . . . . . . 2587
239.5 Linee e cornicette attorno al testo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2588
239.6 Spostamento verticale del testo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2589
240 LaTeX: blocchi di testo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2590
240.1 Caratteristiche normali di un paragrafo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2590
240.2 Allineamento del testo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2591
240.3 Elenchi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2592
240.4 Citazioni . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2597
240.5 Versi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2598
240.6 Testo letterale . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2599
240.7 Ambienti fluttuanti . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2600
241 LaTeX: spazi e scatole . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2603
241.1 Spazi orizzontali . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2603
241.2 Spazi verticali . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2604
241.3 Elasticità controllabile . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2606
241.4 Interlinea . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2606
241.5 Scatole . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2607
241.6 Testo da salvare e da recuperare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2610
241.7 Linee . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2611
2451
242 LaTeX: riferimenti . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2613
242.1 Indice generale, indice delle tabelle e delle figure . . . . . . . . . . . . . . . . . . . . . . . . 2613
242.2 Riferimenti liberi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2616
242.3 Indice analitico . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2617
242.4 Bibliografie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2621
243 LaTeX: tabelle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2624
243.1 Tabella fatta di tabulazioni . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2624
243.2 Tabella fatta di colonne e righe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2628
243.3 Tabella a cavallo di più pagine . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2633
244 LaTeX: figure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2635
244.1 Disegnare con LaTeX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2635
244.2 Importazione di file EPS esterni . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2639
245 LaTeX: ambienti matematici . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2641
245.1 Definizione della modalità matematica . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2641
245.2 Spazi orizzontali e punteggiatura . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2642
245.3 Caratteri e simboli . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2643
245.4 Delimitatori . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2649
245.5 Modifica delle caratteristiche del carattere . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2650
245.6 Espressioni varie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2650
245.7 Matrici e sistemi di equazioni . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2652
245.8 Teoremi, corollari e dichiarazioni simili . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2654
246 LaTeX: file esterni . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2658
246.1 Importazione . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2658
246.2 Importazione letterale . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2658
246.3 Creazione di file . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2658
2452
Capitolo
229
teTeX: la distribuzione Unix di TeX
TeX è un linguaggio di programmazione per l’editoria elettronica. Come nei linguaggi di programmazione comuni è possibile realizzare procedure o funzioni, con TeX è possibile costruire
delle macro. Nel tempo sono stati realizzati diversi pacchetti standard di macro per TeX; per
esempio LaTeX e AmS-TeX.
Semplificando le cose, una distribuzione TeX è un insieme composto da un compilatore TeX (ma
forse è più appropriato il termine «compositore»), una serie di file contenenti le informazioni
necessarie a produrre i caratteri da stampa e alcuni pacchetti di macro (di solito si tratta almeno
di LaTeX).
La distribuzione più importante nei sistemi Unix di TeX è teTeX,
questo capitolo.
1
a cui si fa riferimento in
Purtroppo, una distribuzione TeX è qualcosa di estremamente complesso, dove si raccolgono apporti di autori differenti che a volte hanno scelto licenze particolari. In questo senso, la scelta
di una distribuzione TeX rispetto a un’altra può significare che questa possa essere complessivamente libera o meno. Tuttavia, dal punto di vista dell’utente, è come la differenza che c’è
tra un compilatore libero di un certo linguaggio e un altro compilatore non libero per lo stesso
linguaggio di programmazione.
In generale, l’utilizzatore di una distribuzione TeX «libera» non subisce alcun inconveniente dalle
particolarità che possono avere le licenze di questo o quel componente. Il problema, semmai, si
incontra nel momento in cui si voglia partecipare al suo sviluppo, a causa dell’incompatibilità
che ci può essere tra licenze differenti. A questo proposito, si può osservare che molti file sono
espressamente di dominio pubblico, per non creare difficoltà di alcun genere all’utilizzo in questa
o quella distribuzione.
Questo capitolo si colloca prima di quelli che mostrano l’uso del linguaggio TeX e alcuni concetti
potrebbero sembrare oscuri. Tuttavia, è importante comprendere inizialmente, almeno a grandi
linee, la struttura e il funzionamento di una distribuzione TeX.
229.1 Collocazione
È importante chiarire che non esiste un modo standard di installare una distribuzione TeX e le differenze esistono anche nell’ambito della stessa distribuzione teTeX, dato che ogni distribuzione
GNU/Linux tende a collocarla dove ritiene più opportuno.
Il blocco principale di teTeX dovrebbe trovarsi in una gerarchia che può inserirsi al di sotto
di ‘/usr/lib/’ o ‘/usr/share/’. A titolo di esempio, viene mostrato un elenco di alcune di
queste possibilità.
‘/usr/lib/teTeX/texmf/’
‘/usr/lib/texmf/texmf/’
‘/usr/share/teTeX/texmf/’
‘/usr/share/texmf/’
Negli esempi che si mostreranno, quando si farà riferimento a questa directory, si indicheranno
solo percorsi relativi a iniziare da ‘texmf/’. La sigla «texmf» sta per TeX and more, oppure per
TeX and friends.
1
teTeX GNU GPL
2453
2454
teTeX: la distribuzione Unix di TeX
229.2 Configurazione
Di fronte alla complicazione di una distribuzione teTeX, potrebbe sembrare assurda l’idea di
metterci le mani, pensando addirittura di modificare le impostazioni generali di teTeX. Tuttavia, quando si maneggiano documenti eccezionalmente voluminosi, potrebbe essere necessario
modificare anche ciò che non è stato pensato per esserlo.
229.2.1 Modifiche manuali
Alla fine della composizione di un documento TeX, si può leggere nel file delle registrazioni
generato un rapporto delle risorse utilizzate durante l’elaborazione. Si osservi l’esempio.
Here is how much of TeX’s memory you used:
2418 strings out of 25906
45132 string characters out of 446921
109255 words of memory out of 263001
5196 multiletter control sequences out of 10000+0
106774 words of font info for 69 fonts, out of 200000 for 1000
15 hyphenation exceptions out of 1000
33i,12n,21p,2494b,1259s stack positions out of 300i,100n,500p,30000b,4000s
Output written on texput.dvi (1844 pages, 7563800 bytes).
Questo è proprio il caso di un documento enorme (1844 pagine), ma prima di tale informazione appaiono una serie di valori, dove alternativamente si vede quanto di una data risorsa è stato
usato e quanto era invece disponibile. Se per qualche ragione si esaurisce una di queste risorse, l’elaborazione si interrompe con una segnalazione di errore che indica quale limite è stato
superato.
Se succede, si può provare a mettere mano al file di configurazione di teTeX che dovrebbe essere
‘texmf/web2c/texmf.cnf’. La prima volta, non è tanto facile capire il senso delle direttive
che questo contiene, ma con un po’ di tentativi si dovrebbe riuscire a risolvere il problema.
Prima di tutto si può osservare che, seguendo lo stile generale di TeX, i commenti sono introdotti dal simbolo di percentuale (‘%’). Nella prima parte del file sono annotati i percorsi dei vari
componenti della distribuzione.
% Part 1: Search paths and directories.
% The main tree, which must be mentioned in $TEXMF, below:
TEXMFMAIN = /usr/share/texmf
% A place for local additions to a "standard" texmf tree.
%
TEXMFLOCAL = /usr/share/texmf.local
For example:
% A place where texconfig stores modifications (instead of the TEXMFMAIN
% tree). texconfig relies on the name, so don’t change it.
%
TEXMF_CNF = $TEXMF.cnf
% User texmf trees can be catered for like this...
%
HOMETEXMF = $HOME/texmf
La lettura di questa parte può rivelare delle informazioni importanti riguardo la propria distribuzione teTeX. Più avanti inizia una parte più delicata: quella che definisce le dimensioni degli
array utilizzati da TeX, che di conseguenza rappresentano i limiti a cui si accennava all’inizio di
questa sezione.
teTeX: la distribuzione Unix di TeX
2455
% Part 3: Array and other sizes for TeX (and Metafont and MetaPost).
...
% Max number of characters in all strings, including all error messages,
% help texts, font names, control sequences. These values apply to TeX and MP.
pool_size.context = 500000
pool_size.cont-en = 500000
pool_size.cont-nl = 500000
pool_size.cont-de = 500000
%pool_size = 125000
pool_size = 500000
In questa parte, il valore più importante è quello di ‘pool_size’, perché può creare problemi
soprattutto a pdfTeX. Nell’esempio si vede che è stato quadruplicato.
Alcune modifiche non possono essere prese in considerazione senza un’elaborazione successiva
del file. In generale, al termine delle modifiche è bene dare il comando seguente:
# texconfig init
A parte il caso particolare dell’utilizzo appena mostrato, ‘texconfig’ è un programma
interattivo, che viene descritto nella prossima sezione.
229.2.2 # texconfig
‘texconfig’ è un programma, in forma di script predisposto per configurare gli elementi essen-
ziali della distribuzione teTeX. Si avvia semplicemente, senza bisogno di argomenti. La figura
229.1 mostra il menù principale di ‘texconfig’.
# texconfig
Figura 229.1. Il menù principale di ‘texconfig’.
.---------------------------- teTeX setup utility -----------------------------.
|
|
| Hint: all output of external commands (e.g. tex) is logged into
|
| a file. You can look at this file using LOG. If cursor keys make
|
| trouble, you may have more luck with +/- and TAB.
|
|
|
|
|
| .--------------------------------------------------------------------------. |
| |
EXIT
exit
| |
| |
PREF
personal preferences
| |
| |
CONF
show configuration
| |
| |
REHASH rebuild ls-R database
| |
| |
HYPHEN hyphenation table (tex/latex)
| |
| |
MODE
default mode (xdvi/dvips/mf)
| |
| |
XDVI
xdvi configuration
| |
| |
DVIPS
dvips configuration
| |
| |
FONT
directories for font creation
| |
| |
DOC
rebuild html documentation
| |
| |
FAQ
frequently asked questions + answers
| |
| |
LOG
view logfile
| |
|------------------------------------------------------------------------------|
|
< OK >
<Cancel>
|
‘------------------------------------------------------------------------------‘
La funzione indicata con la sigla PREF serve solo a modificare il comportamento di ‘texconfig’,
permettendo in particolare di selezionare un programma per la modifica del testo alternativo a
quello predefinito.
La funzione CONF permette di mostrare la configurazione, consistente nella definizione delle
directory contenenti i vari componenti della distribuzione teTeX.
teTeX: la distribuzione Unix di TeX
2456
La funzione REHASH permette di ricostruire il file ‘texmf/ls-R’, utilizzato per agevolare la ricerca dei componenti installati ad alcuni programmi della distribuzione. In generale, si ricostruisce
questo file quando si aggiunte o si toglie qualche file (per esempio i file dei tipi di carattere).
La funzione HYPHEN è molto importante, perché permette di stabilire le lingue per cui attivare la
suddivisione in sillabe del testo. Selezionando questa funzione si ottiene l’avvio del programma
per la modifica di file di testo (presumibilmente VI) con il file ‘texmf/tex/generic/config/
language.dat’. Questo file può essere modificato, quindi, dopo averlo salvato, vengono avviate
automaticamente le procedure necessarie ad attivare in pratica le scelte fatte.
Di solito, si tratta di commentare le righe che fanno riferimento a linguaggi che non si vogliono
gestire e di togliere il commento dalla direttiva di attivazione della sillabazione per la lingua
italiana.
% File
: language.dat
% Purpose : specify which hypenation patterns to load
%
while running iniTeX
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% CAUTION: the first language will be the default if no style-file
%
(e.g. german.sty) is used.
% Since version 3.0 of TeX, hyphenation patterns for multiple languages are
% possible. Unless you know what you are doing, please let the american
% english patterns be the first ones. The babel system allows you to
% easily change the active language for your texts. For more information,
% have a look to the documentation in texmf/doc/generic/babel.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% The hyphenation pattern files are in the directory:
%
texmf/tex/generic/hyphen
% The US-english patterns should be loaded *always* and as *first* ones.
american ushyph1.tex %
% Let us define USenglish as an alias for american:
=USenglish %
% UK english, TWO LINES!
%british ukhyph.tex %
%=UKenglish %
% english should always be defined. Either an alias for american or british.
=english %
% French, TWO lines!
french
frhyph.tex frhyphex.tex %
=patois %
german
ghyph31.tex %
% The following
%bahasa
%catalan
%croatian
%czech
%danish
%dutch
%finnish
%galician
italian
%magyar
%norsk
languages are disabled by default. Uncomment, what you need.
inhyph.tex %
cahyph.tex %
hrhyph.tex %
czhyph2e.tex %
dkhyphen.tex %
nehyph2.tex %
fihyph.tex %
gahyph.tex %
ithyph.tex %
huhyph.tex %
nohyph.tex %
teTeX: la distribuzione Unix di TeX
%polish
%portuges
%romanian
%russian
%serbocroatian
%slovene
%spanish
%swedish
%turkish
2457
plhyph.tex %
pthyph.tex %
rohyphen.tex %
ruhyph.tex %
shhyphl.tex %
sihyph22.tex %
sphyph.tex %
sehyph.tex %
trhyph.tex %
% A "language" without hyphenation:
nohyphenation zerohyph.tex %
Al termine dell’elaborazione si potrà verificare nel file ‘texmf/web2c/latex.log’ la presenza
delle righe che dimostrano l’abilitazione della sillabazione per le lingue selezionate nel file di
configurazione. In questo caso particolare, la lingua italiana corrisponde al linguaggio numero
tre.
...
\l@american=\language0
...
\l@USenglish =\language0
\l@english =\language0
\l@french=\language1
...
\l@patois =\language1
\l@german=\language2
...
\l@italian=\language3
...
\l@nohyphenation=\language4
La funzione MODE permette di predisporre alcuni programmi per la risoluzione della propria
stampante. Ciò si ottiene semplicemente selezionando il nome di una stampante che dovrebbe
corrispondere, o essere molto simile alla propria.
La funzione XDVI permette di configurare Xdvi (capitolo 91), il programma di visualizzazione
dei file DVI, in modo da stabilire il formato del foglio che si utilizza. Basta scorrere un elenco e
confermare.
La funzione DVIPS permette di configurare Dvips (capitolo 91), il programma in grado di convertire file DVI in PostScript. Come per Xdvi, la cosa più importante da stabilire è il formato della
carta, ma può anche essere indicata la stampante, o il comando di stampa da utilizzare quando
Dvips viene usato per inviare direttamente un file alla stampa.
L’ultima funzione importante è FONT che permette di regolare i permessi di accesso alle directory
che contengono i tipi di carattere e anche di configurare altre caratteristiche di questi file.
229.3 Funzionamento fondamentale di TeX
TeX utilizza un sorgente che si distingue perché di solito il suo nome finisce con l’estensione ‘.tex’; durante il processo di composizione genera un rapporto sull’elaborazione in un file
con l’estensione ‘.log’ e produce un file finale in formato DVI, con estensione ‘.dvi’. Successivamente, i file DVI vengono convertiti normalmente in PostScript attraverso il programma
Dvips.
Eventualmente, è disponibile anche pdfTeX, con cui, invece di una composizione in formato
DVI, si ottiene un file PDF senza passaggi intermedi.
teTeX: la distribuzione Unix di TeX
2458
Se si suppone che il file ‘primo.tex’ contenga il testo seguente
Ciao a tutti.
Questo \‘e il mio primo documento scritto con il linguaggio \TeX.
\bye
per ottenere la composizione in formato DVI è sufficiente il comando
$ tex primo.tex[ Invio ]
This is TeX, Version 3.14159 (Web2C 7.3.1)
(primo.tex [1] )
Output written on primo.dvi (1 page, 328 bytes).
Transcript written on primo.log.
mentre per ottenere la composizione in formato PDF è sufficiente il comando
$ pdftex primo.tex[ Invio ]
This is pdfTeX, Version 3.14159-13d (Web2C 7.3.1)
(primo.tex[/usr/share/texmf/pdftex/config/pdftex.cfg]
Babel <v3.6x> and hyphenation patterns for american, italian, nohyphenation,
loaded.
[1[/usr/share/texmf/dvips/config/pdftex.map]] )<cmr10.pfb>
Output written on primo.pdf (1 page, 9807 bytes).
Transcript written on primo.log.
Nel primo caso si ottiene il file ‘primo.dvi’, mentre nel secondo si ha il file ‘primo.pdf’.
Eventualmente, per convertire il file DVI in PostScript, è sufficiente usare Dvips nel modo
seguente:
$ dvips -o primo.ps primo.dvi[ Invio ]
This is dvips(k) 5.86 Copyright 1999 Radical Eye Software (www.radicaleye.com)
’ TeX output 2001.08.30:0835’ -> primo.ps
<texc.pro>. [1]
Ecco quello che si ottiene:
Si può anche usare una versione estesa di TeX, e-TeX e pdfeTeX, corrispondenti agli eseguibili
‘etex’ e ‘pdfetex’, che in questo caso si comportano nello stesso modo:
$ etex primo.tex[ Invio ]
This is e-TeX, Version 3.14159-2.1 (Web2C 7.3.1)
entering extended mode
(primo.tex [1] )
Output written on primo.dvi (1 page, 328 bytes).
Transcript written on primo.log.
oppure
$ pdfetex primo.tex[ Invio ]
This is pdfeTeX, Version 3.14159-13d-2.1 (Web2C 7.3.1)
entering extended mode
(primo.tex[/usr/share/texmf/pdftex/config/pdftex.cfg] [1[/usr/share/texmf/dvips
/config/pdftex.map]] )<cmr10.pfb>
Output written on primo.pdf (1 page, 9807 bytes).
Transcript written on primo.log.
teTeX: la distribuzione Unix di TeX
2459
Gli eseguibili ‘tex’, ‘pdftex’ ‘etex’ e ‘pdfetex’ sono indipendenti, mentre attorno a loro si
presentano altrettante serie di collegamenti simbolici:
virtex
initex
latex
amstex
->
->
->
->
tex
tex
tex
tex
evirtex
einitex
elatex
-> etex
-> etex
-> etex
pdfevirtex -> pdfetex
pdfeinitex -> pdfetex
pdfelatex -> pdfetex
pdfvirtex
pdfinitex
pdflatex
-> pdftex
-> pdftex
-> pdftex
A seconda del nome usato per avviare uno stesso eseguibile, si può ottenere un comportamento
differente. Nel caso di ‘virtex’ che è un collegamento a ‘tex’, si fa riferimento implicitamente al formato ‘plain’, corrispondente alle dichiarazioni contenute nei file della directory
‘texmf/tex/plain/’, così come ‘pdfvirtex’ fa riferimento alla directory ‘texmf/pdftex/
plain/’, ecc. Purtroppo, le cose non sono così semplici in generale, perché le convenzioni
non sono perfettamente omogenee; tuttavia, vale la pena di tenere presente che i nomi del tipo
‘[pdf][e]virtex’ sono equivalenti ai nomi del tipo ‘[pdf][e]tex’.
I nomi del tipo ‘[pdf][e]initex’ fanno riferimento al linguaggio TeX senza la dichiarazione di alcuna macro e sono equivalenti all’uso degli eseguibili del tipo ‘[pdf][e]tex’
con l’aggiunta dell’opzione ‘--ini’. In pratica, per usare ‘[pdf][e]initex’, oppure
‘[pdf][e]tex --ini’, occorre modificare l’esempio già visto nel modo seguente:
\input plain
Ciao a tutti.
Questo \‘e il mio primo documento scritto con il linguaggio \TeX.
\bye
Questa spiegazione viene data solo per chiarire un po’ il funzionamento di TeX e il significato
di tutti i collegamenti simbolici che gli stanno intorno. L’uso dell’istruzione ‘\input plain’
nel sorgente non funziona sempre come ci si aspetterebbe leggendo queste indicazioni; in
pratica, una volta capito il senso della cosa, non va usata affatto.
In modo analogo a quanto visto fino a questo punto, quando si fa riferimento a un collegamento
del tipo ‘[pdf][e]latex’, è come usare un eseguibile del tipo ‘[pdf][e]initex’, oppure
‘[pdf][e]tex --ini’, iniziando il sorgente TeX con la riga seguente:
\input latex.ini
Resta il fatto che il comando ‘\input latex.ini’ non rappresenta necessariamente uno
standard e quello che conta è sapere solo che i collegamenti ‘[pdf][e]latex’ richiamano
in qualche modo il formato ‘latex’. In altri termini, i collegamenti ‘[pdf][e]latex’ fanno
riferimento implicitamente alle macro di LaTeX.
Per completare questa sezione, viene mostrato un esempio di un sorgente LaTeX, ovvero un
sorgente TeX fatto per le macro LaTeX. Si fa riferimento al nome ipotetico ‘secondo.tex’:
teTeX: la distribuzione Unix di TeX
2460
\documentclass{article}
\begin{document}
Ciao a tutti.
Questo \‘e il mio primo documento scritto con il linguaggio \LaTeX .
\end{document}
Per comporre correttamente questo file, occorre un comando del tipo:
$
[pdf][e]latex
secondo.tex
A seconda dei casi si otterrà il file ‘secondo.dvi’, oppure ‘secondo.pdf’.
229.4 Interazione con TeX
La composizione di un documento scritto con il linguaggio TeX può avvenire anche con qualche forma di interazione. Se si avvia uno degli eseguibili ‘[pdf][e]tex’ senza argomenti, si
ottiene un invito a inserire il nome del file, attraverso l’indicazione di due asterischi:
$ tex[ Invio ]
This is TeX, Version 3.14159 (Web2C 7.3.1)
**
Si può inserire così il percorso del file, omettendo eventualmente l’estensione se questa
corrisponde a ‘.tex’:
**terzo.tex[ Invio ]
(terzo.tex [1] )
Output written on terzo.dvi (1 page, 488 bytes).
Transcript written on terzo.log.
Supponendo di avere scritto un file, denominato ‘quarto.tex’, in cui non appare l’istruzione
‘\bye’ finale, come nel testo seguente, TeX si ferma in attesa di istruzioni, mostrando un invito
ridotto a un solo asterisco:
Ciao a tutti.
Questo \‘e il mio quarto documento scritto con il linguaggio \TeX,
dove non appare l’istruzione $\backslash$bye alla fine del file.
$ tex quarto.tex[ Invio ]
This is TeX, Version 3.14159 (Web2C 7.3.1)
(quarto.tex)
*
Naturalmente, se si è in grado di farlo, si può aggiungere anche altro testo:
*Saluti![ Invio ]
*\bye[ Invio ]
[1]
Output written on quarto.dvi (1 page, 448 bytes).
Transcript written on quarto.log.
!"#$ % && ' ( ) * + , -, . /
teTeX: la distribuzione Unix di TeX
2461
Di solito si evita di interagire con TeX, tuttavia si può essere costretti dal presentarsi di un errore
durante la compilazione del sorgente. Per la precisione, il livello di interazione di TeX può essere regolato attraverso delle istruzioni speciali, come descritto nella tabella 229.1. In condizioni
normali, il funzionamento avviene in modalità ‘errorstopmode’, corrispondente all’istruzione
‘\errorstopmode’, in cui TeX si ferma in attesa di indicazioni per qualunque errore si presenti.
Tabella 229.1. Istruzioni per il controllo della modalità di funzionamento interattiva.
Istruzione TeX
\errorstopmode
\scrollmode
\nonstopmode
\batchmode
Modalità di funzionamento
La composizione viene sospesa per qualunque errore.
La composizione viene sospesa solo per gli errori più importanti.
La composizione viene sospesa solo in presenza di errori gravissimi.
La composizione viene sospesa solo in presenza di errori gravissimi e non si
mostrano informazioni sullo schermo.
Per esempio, il file ‘quinto.tex’ che contiene il testo seguente, usa erroneamente l’istruzione
‘\tex’ al posto di ‘\TeX’:
Ciao a tutti.
Questo \‘e il mio quinto documento scritto con il linguaggio \tex, in
cui si provoca volutamente un errore.
\bye
$ tex quinto.tex[ Invio ]
This is TeX, Version 3.14159 (Web2C 7.3.1)
(quinto.tex
! Undefined control sequence.
l.3 ...to documento scritto con il linguaggio \tex
, in
?
Viene dichiarato sinteticamente il tipo di errore individuato, che in questo caso corrisponde a
! Undefined control sequence.
ovvero una sequenza di controllo indefinita. Nella riga successiva si indica il numero della riga
in cui appare l’errore (‘l.3’ sta per line 3) con il pezzo di testo che arriva fino all’errore, mentre
il pezzo successivo appare staccato, nella riga successiva.
l.3 ...to documento scritto con il linguaggio \tex
, in
In pratica, secondo TeX l’errore è riferito esattamente alla stringa ‘\tex’. Sotto appare un invito composto da un punto interrogativo, con il quale TeX attende un’azione dell’utente. Si può
rispondere con un altro punto interrogativo per avere l’elenco delle possibilità:
??[ Invio ]
Type <return> to proceed, S to scroll future error messages,
R to run without stopping, Q to run quietly,
I to insert something, E to edit your file,
1 or ... or 9 to ignore the next 1 to 9 tokens of input,
H for help, X to quit.
?
La tabella 229.2 descrive brevemente il significato e l’uso dei comandi disponibili, mostrando
anche la modalità corrispondente quando una scelta coincide con la richiesta di cambiamento di
questa.
teTeX: la distribuzione Unix di TeX
2462
Tabella 229.2. Interazione in presenza di un errore.
Istruzione TeX
corrispondente
Effetto
[ r ][ Invio ]
\scrollmode
\nonstopmode
[ q ][ Invio ]
\batchmode
Mostra la spiegazione del motivo dell’interruzione.
Richiede di inserire una correzione.
Avvia un programma per la modifica del file sorgente.
Arresta la composizione.
Non si ferma più in presenza di piccoli errori.
Non si ferma più per alcun errore.
Non si ferma più per alcun errore e non mostra alcuna
informazione.
Cerca di rimediare all’errore e continua la composizione.
Cerca di rimediare automaticamente ai prossimi n errori.
Tastiera
[ h ][ Invio ]
[ i ][ Invio ]
[ e ][ Invio ]
[ x ][ Invio ]
[ s ][ Invio ]
[ Invio ]
[ n ][ Invio ]
Nel caso dell’errore mostrato, si vuole provare a capire meglio di cosa si tratta, attraverso il
comando [ h ][ Invio ]:
?h[ Invio ]
The control sequence at the end of the top line
of your error message was never \def’ed. If you have
misspelled it (e.g., ‘\hobx’), type ‘I’ and the correct
spelling (e.g., ‘I\hbox’). Otherwise just continue,
and I’ll forget about whatever was undefined.
Dal momento che si può correggere facilmente l’errore, si richiede di poter inserire del testo
sostitutivo:
?i[ Invio ]
insert>\TeX[ Invio ]
[1] )
Output written on quinto.dvi (1 page, 376 bytes).
Transcript written on quinto.log.
Con il comando [ e ][ Invio ] si può avviare un programma per la modifica del file sorgente. Di
solito si tratta di VI, ma si può intervenire nella variabile di ambiente ‘TEXEDIT’ indicando il
nome di un altro programma, usando le metavariabili ‘%d’ e ‘%s’ per indicare rispettivamente la
riga contenente l’errore e il nome del file. Per esempio, rimanendo nel caso di VI, è possibile
usare la sintassi seguente per raggiungere la riga n -esima del file indicato:
vi -c n file
In questo modo, si dovrebbe assegnare alla variabile di ambiente ‘TEXEDIT’ la stringa ‘vi -c
%d %s’:
$ TEXEDIT="vi -c %d %s"[ Invio ]
$ export TEXEDIT[ Invio ]
teTeX: la distribuzione Unix di TeX
229.5 Riferimenti
• Documentazione interna della distribuzione teTeX: ‘texmf/doc/*’
• Documentazione interna Info: web2c.info e latex.info
Appunti di informatica libera 2003.01.01 --- Copyright © 2000-2003 Daniele Giacomini -- daniele @ swlibero.org
2463
Capitolo
230
TeX: introduzione
TeX è un linguaggio di programmazione per la composizione tipografica. La «compilazione» di
un sorgente TeX produce un file in formato finale (DVI o PDF) per la stampa.
L’importanza di questo linguaggio richiede anche la conoscenza della pronuncia corretta del suo
nome: «t-e-k». Infatti, il creatore di questo linguaggio, D.E. Knuth, voleva fare riferimento alle
lettere greche maiuscole «TEX», che così vanno pronunciate.
Dal momento che le istruzioni TeX utilizzano spesso le parentesi graffe, nei modelli sintattici
queste vanno intese letteralmente, come parte dell’istruzione rappresentata.
230.1 Elementi essenziali del linguaggio TeX
Un file sorgente TeX è un file di testo normale; per la precisione dovrebbe trattarsi di un file
ASCII standard a 7 bit, dove l’interruzione delle righe avviene secondo le regole del proprio
sistema operativo.
Nel linguaggio di TeX si distinguono righe bianche o vuote da righe contenenti istruzioni. Nell’ambito delle righe contenenti istruzioni, possono poi apparire dei commenti che si distinguono
per essere preceduti dal segno di percentuale (‘%’), terminati dalla fine della riga. Nell’esempio
seguente si può osservare che tutte le righe che contengono del testo sono in pratica delle istruzioni, più o meno articolate. Nella prima riga appare anche un commento, che non appare poi
nella composizione finale.
Ciao a tutti. % Ecco, un commento tanto per gradire.
Questo \‘e solo un piccolo esempio per vedere come funziona il
linguaggio di composizione \TeX.
\bye
Gli spazi, verticali e orizzontali, hanno un significato, ma generalmente non si sommano. Normalmente si usa una riga vuota o bianca per separare il testo in paragrafi, ma la presenza di più
righe bianche o vuote non cambia la distanza tra questi paragrafi nella composizione finale; nello
stesso modo, uno spazio orizzontale serve generalmente a separare le parole di una frase, ma la
presenza di più spazi orizzontali non cambia la distanza tra le parole.
Eventualmente si può dichiarare espressamente la separazione tra i paragrafi attraverso l’istruzione ‘\par’, tenendo presente che anche in questo caso, l’uso di più istruzioni del genere non
produce una separazione maggiore tra i paragrafi stessi
L’istruzione finale ‘\bye’ conclude il «programma» TeX e tutto ciò che appare dopo viene
ignorato.
230.1.1 Testo letterale, parole e simboli di controllo
Una riga di testo si traduce generalmente nel testo corrispondente nella composizione finale,
tenendo conto però che alcuni simboli hanno un significato speciale e si distinguono contesti
differenti. La tabella 230.1 elenca i caratteri che hanno significati particolari, con l’indicazione
del modo per ottenere il loro simbolo originale nella composizione.
2464
TeX: introduzione
2465
Tabella 230.1. Elenco dei caratteri che hanno significati particolari.
Carattere
speciale
\
{
}
%
&
~
$
^
_
#
<SP>
<
>
Utilizzo normale
Prefisso di una parola di controllo o di un simbolo di
controllo.
Apre un gruppo.
Chiude un gruppo.
Inizia un commento fino alla fine della riga.
Tabulazione orizzontale.
Spazio non interrompibile.
Inizia e conclude un contesto matematico.
Apice, in un contesto matematico.
Pedice, in un contesto matematico.
Definisce la collocazione di un parametro.
Uno o più spazi vengono ridotti a uno solo.
In condizioni normali, genera un punto esclamativo
rovesciato.
In condizioni normali, genera un punto interrogativo
rovesciato.
Trasformazione
per l’uso letterale
$\backslash$
$\{$
$\}$
\%
\&
\~{}
\$
\^{}
\_{}
\#
\<SP>
$<$
$>$
La barra obliqua inversa (‘\’) viene usata come prefisso per delle sequenze di controllo , nell’ambito delle quali si può distinguere tra parole di controllo e simboli di controllo . Una parola
di controllo è formata esclusivamente da lettere alfabetiche (dalla «a» alla «z», maiuscole e minuscole, escluse le lettere accentate); per esempio, ‘\TeX’ è una parola di controllo con cui si
ottiene la rappresentazione del nome TeX secondo lo standard stabilito dal suo autore originale.
Un simbolo di controllo è invece un solo carattere che non sia una lettera alfabetica; per esempio,
‘\‘’ è un simbolo di controllo con cui si ottiene l’aggiunta di un accento grave sopra il simbolo
successivo.
In base al fatto che le parole di controllo si distinguono perché composte esclusivamente da lettere
alfabetiche, si può porre il problema di delimitarle correttamente quando si trovano incorporate in
parole che compongono il testo normale. Nell’esempio già mostrato, la parola di controllo ‘\TeX’
si individua correttamente perché è seguita da un punto fermo, ovvero un simbolo che non è una
lettera alfabetica, ma volendo scrivere un gioco di parole, come «il mio primo TeXdocumento»,
sarebbe necessario usare uno strattagemma. Si osservi l’esempio seguente che si traduce in un
errore nella composizione del documento:
Ciao a tutti.
Questo \‘e il mio primo \TeXdocumento.
\bye
TeX cerca di interpretare la parola di controllo ‘\TeXdocumento’ e non dovrebbe riuscirci. Per
questa ragione, lo spazio che dovesse seguire una parola di controllo viene ignorato; così, diventa
più facile inserire queste parole di controllo in parole del testo che si vuole comporre. Ecco
l’esempio corretto:
Ciao a tutti.
Questo \‘e il mio primo \TeX documento.
\bye
Tuttavia, rimane da chiarire in che modo inserire veramente uno spazio dopo una parola di
controllo. Questo problema viene risolto con l’uso dei raggruppamenti.
TeX: introduzione
2466
230.1.2 Raggruppamenti
In diverse situazioni è utile raggruppare parte delle istruzioni (il testo) all’interno di parentesi
graffe (‘{...}’). L’effetto del raggruppamento non si nota nella composizione finale, ma permette
di circoscrivere l’effetto di istruzioni particolari.
È ammissibile anche l’uso di raggruppamenti vuoti, ‘{}’, che di solito vengono usati per separare
parole o simboli di controllo dal testo che segue. Per esempio, scrivendo ‘\TeX{}’ si riesce a
evitare che lo spazio successivo venga inghiottito.1 Nel seguito vengono mostrati diversi esempi
che si traducono nella stessa composizione finale.
• Raggruppamento vuoto alla fine della parola di controllo:
Il linguaggio di composizione \TeX{} sembra complesso a prima vista...
\bye
• Raggruppamento vuoto per separare gli spazi:
Il linguaggio di composizione \TeX {} sembra complesso a prima vista...
\bye
• Raggruppamento per individuare uno spazio:
Il linguaggio di composizione \TeX{ }sembra complesso a prima vista...
\bye
• Raggruppamento per individuare uno spazio dopo la fine della parola di controllo:
Il linguaggio di composizione \TeX { }sembra complesso a prima vista...
\bye
• Raggruppamento per isolare la parola di controllo:
Il linguaggio di composizione {\TeX} sembra complesso a prima vista...
\bye
• Raggruppamento per isolare lo spazio e la parola successiva:
Il linguaggio di composizione \TeX { sembra} complesso a prima vista...
\bye
Nella tabella 230.1 sono stati mostrati alcuni simboli di controllo che sono conclusi evidentemente da un raggruppamento vuoto: ‘\~{}’, ‘\^{}’ e ‘\_{}’. In questo caso, il raggruppamento
vuoto serve a impedire che la sequenza di controllo produca qualcosa di diverso da ciò che ci
si aspetta in quel contesto particolare. Per esempio, ‘\^o’ oppure anche ‘\^ o’ genera la lettera
accentata «ô».2
Oltre all’uso delle parentesi, è possibile usare in alternativa la coppia di parole di controllo
‘\bgroup’ e ‘\egroup’, in sostituzione di ‘{’ e ‘}’ rispettivamente.
230.1.3 Inclusione di file esterni
È possibile articolare un sorgente TeX in più file separati, che vengono inclusi con l’istruzione
‘\input’:
\input nome_file
1
Naturalmente si può usare anche il simbolo di controllo ‘\<SP>’ (barra obliqua inversa e spazio) per indicare
espressamente uno spazio in quel punto.
2
Verrà chiarito in seguito che le istruzioni ‘\~{}’ e ‘\^{}’ sono delle macroistruzioni che servono a generare un
accento, utilizzano un parametro, costituito dal carattere o dal gruppo successivo. Nel momento in cui si vogliono rappresentare questi simboli senza abbinarli ad altro, il loro parametro deve essere un gruppo vuoto o lo spazio inteso come
carattere (‘\<SP>’). Pertanto, in alternativa a ‘\~{}’ e ‘\^{}’ si poteva usare la forma ‘\~\<SP>’ e ‘\^\<SP>’.
TeX: introduzione
2467
L’inclusione avviene inserendo in quel punto le righe del file indicato. Se il file esterno contiene
l’istruzione ‘\bye’, la composizione termina senza continuare nel file di partenza.
2468
TeX: introduzione
230.2 Variabili e tipi di dati
TeX ha una gestione molto particolare dei dati. Nelle sezioni seguenti vengono descritti solo i
tipi di dati più comuni, ma questo dovrebbe bastare per far comprendere la logica di fondo.
Vale la regola per cui può essere usato solo ciò che è già stato dichiarato; inoltre, il campo di
azione di queste variabili può essere controllato attraverso i raggruppamenti con le parentesi
graffe.
In generale, per TeX una variabile ha l’aspetto di una parola di controllo a cui si assegna un valore
secondo la sintassi seguente:
\nome =valore
L’espansione di una variabile avviene inserendo la parola di controllo corrispondente nel punto
in cui il contesto lo richiede. Tuttavia, se lo scopo è quello di espandere la variabile in modo che
appaia nel testo normale, occorre usare un accorgimento, con cui si trasforma il suo contenuto in
una stringa. Di solito si usa per questo la parola di controllo ‘\the’:
\the\nome
230.2.1 Stringhe
Per TeX la stringa è ciò che può essere reso tipograficamente; così, un’espressione stringa è ciò
che alla fine si trasforma in una stringa nella composizione tipografica. Le variabili di tipo stringa
si dichiarano nel modo seguente:
\newtoks\nome
Si può assegnare una stringa alla variabile nel modo seguente:
\nome ={espressione_stringa }
L’espansione di una variabile stringa non può avvenire inserendo semplicemente la parola di
controllo ‘\nome ’ nel testo, perché occorre dichiarare espressamente questa intenzione con la
parola di controllo ‘\the’.
\newtoks\data
\data={9 settembre 2001}
Treviso, \the\data \par
Bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla
bla bla bla bla bla bla bla bla bla bla. \par
Ciao.
Nell’esempio precedente, si crea una variabile stringa corrispondente alla parola di controllo
‘\data’, a cui si assegna la stringa ‘9 settembre 2001’, per poi ottenerne successivamente
l’espansione nel testo.
TeX: introduzione
2469
230.2.2 Trasformazione delle stringhe
Le trasformazioni più comuni sulle stringhe sono il cambiamento in maiuscole o minuscole. Ciò
si ottiene facilmente con le macro ‘\uppercase’ e ‘\lowercase’:
\uppercase{espressione_stringa_da_trasformare_in_maiuscole }
\lowercase{espressione_stringa_da_trasformare_in_minuscole }
230.2.3 Contatori
La variabile numerica più semplice di TeX è il contatore. Ne esistono due tipi: uno deve essere
inizializzato subito, con un valore non negativo, l’altro no:
\countdef\nome_contatore =n
\newcount\nome_contatore
Il primo di questi due modelli riguarda il tipo di contatore che deve essere inizializzato in fase di
dichiarazione. Il valore di inizializzazione è rappresentato da n .
Per assegnare un valore a una variabile contatore, si usa la forma seguente:
\nome =valore
È importante sottolineare che l’inizializzazione di un contatore definito attraverso
‘\countdef’ potrebbe in pratica non tradursi nell’assegnamento corrispondente alla variabile,
pur essendo obbligatorio. Pertanto, conviene poi assegnare nuovamente il valore richiesto.
Si può assegnare un numero espresso usando cifre numeriche, con un segno anteriormente nel
caso sia necessario, senza separatore decimale, come nell’esempio seguente, in cui si assegna al
contatore ‘\conteggio’ il valore -345.
\conteggio=-345
230.2.4 Lunghezze
Un tipo specifico di variabile numerica è adibita a contenere delle lunghezze. Per TeX, la lunghezza è un’informazione numerica particolare, che si potrebbe ricondurre al concetto di variabile a
virgola mobile di altri linguaggi. Si dichiara una lunghezza nel modo seguente:
\newdimen\nome_lunghezza
Una lunghezza è un valore che si può rappresentare in forma costante solo specificando l’unità
di misura, che per TeX è una sigla composta da due lettere secondo lo schema che appare nella
tabella 230.2. Pertanto, un valore che esprime una lunghezza deve avere la forma seguente:
[+|-]numero [true]unità_di_misura
In particolare, il valore che precede l’unità di misura può contenere una virgola decimale, espressa attraverso il punto (‘.’).3 Per esempio, per esprimere una lunghezza di 10 cm, si deve scrivere
‘10cm’.4 Nell’esempio seguente si assegna alla variabile ‘\distanza’ una lunghezza positiva di
4,5 mm:
3
È consentito anche l’uso della virgola per separare la parte intera di un numero. Tuttavia, ci sono situazioni in cui
ciò non va bene, per cui è meglio usare sempre solo il punto.
4
TeX ammette che tra il numero e l’unità di misura ci sia dello spazio. Qui si preferisce attaccare l’unità di misura al
numero, per evitare confusione con il testo successivo.
TeX: introduzione
2470
\distanza=4.5mm
La parola chiave ‘true’ consente di indicare una lunghezza che non può essere ingrandita o ridotta attraverso l’istruzione ‘\magnification’, come verrà descritto nella sezione 232.1. Pertanto,
se nell’esempio precedente si vuole indicare una lunghezza positiva corrispondente esattamente
a 4,5 mm, in ogni situazione, si deve scrivere così:
\distanza=4.5truemm
oppure anche in modo più leggibile:
\distanza=4.5 true mm
La rappresentazione interna delle lunghezze è di un solo tipo; in pratica, TeX converte sempre i
valori nell’unità di misura più piccola che è in grado di gestire.5
Tabella 230.2. Unità di misura secondo TeX.
Sigla
mm
cm
in
Denominazione
millimetro
centimetro
pollice
Corrispondenza
bp
big point
pt
punto
dd
punto didôt
sp
scaled point
1/65535 punti ‘pt’
pc
pica
12 punti
em
M
variabile
ex
x
variabile
mu
math unit
18 quadratoni
2,54 cm
0,3527777 mm
1/72 pollici
0,3514598 mm
1/72,27 pollici
0,376065 mm
1/67,54 pollici
Annotazioni
Il punto tipografico usato dal
linguaggio PostScript.
Punto tipografico usato negli
Stati Uniti.
Punto tipografico europeo.
L’unità di misura più piccola
gestibile da TeX.
Quadratone, pari alla larghezza
della lettera «M» maiuscola.
Altezza della lettera «x» minuscola.
Si osservi che TeX non semplifica la tradizione tipografica, consentendo di utilizzare ben tre
tipi diversi di punto tipografico. Il punto a cui si è abituati comunemente con i programmi di
composizione, è quello corrispondente alla sigla ‘bp’, ma TeX utilizza in modo predefinito
l’unità ‘pt’, che comunque non si discosta di molto.
230.2.5 Lunghezze elastiche
In varie situazioni, TeX è in grado di gestire delle lunghezze elastiche. Le variabili che contengono informazioni del genere sono in grado di annotare tre indicazioni distinte: la distanza normale,
una tolleranza in più e una tolleranza in meno. Questo tipo di informazione si esprime secondo
la forma seguente:
lunghezza_richiesta
[plus
lunghezza_in_estensione
] [minus
lunghezza_in_contrazione
]
In pratica, è come dire che si fa riferimento a una certa lunghezza, a cui si può aggiungere quanto
appare dopo la parola chiave ‘plus’ e si può togliere quanto appare dopo ‘minus’. Come si può
intuire, quando non si indicano i valori che danno elasticità, si sottintende in corrispondenza un
valore zero.
5
L’unità di misura più piccola è definita scaled point, che è stata creata appositamente per TeX.
TeX: introduzione
2471
L’elasticità fissata attraverso le parole chiave ‘plus’ e ‘minus’ non è tassativa. Di solito, il
solo fatto che si consenta un’estensione, anche di un solo punto, fa sì che il salto sia allungabile
in modo indefinito, in caso di necessità.
Eventualmente, si dichiara una variabile del genere con la forma seguente:
\newskip\nome
L’assegnamento, come si può intendere, ha la forma seguente:
\nome =lunghezza_elastica
Ovvero:
\nome =lunghezza
[plus
lunghezza
] [minus
lunghezza
]
Le indicazioni sull’elasticità in estensione e in contrazione sono formate normalmente da lunghezze, come per esempio ‘plus 1pt’, ma si possono usare anche delle definizioni astratte,
rappresentate da tre parole chiave, precedute da un numero intero:
n fil
n fill
n filll
Generalmente, il numero n è sempre 1 e va inteso come moltiplicatore della parola successiva;
in pratica, ‘2fil’ rappresenta un’elasticità doppia di ‘1fil’.
La parola chiave ‘fil’ rappresenta un’elasticità di grado minimo, ‘fill’ un’elasticità di grado
medio e ‘filll’ un’elasticità molto grande.
230.2.6 Operazioni con i valori numerici
La realizzazione di espressioni numeriche con TeX diventa abbastanza complicata. Si utilizzano
fondamentalmente tre tipi di istruzione per modificare il valore di una variabile:
[by] valore
\multiply\nome [by] valore
\divide\nome [by] valore
\advance\nome
In pratica, nel primo caso si incrementa la variabile del valore indicato (se il valore in questione
è negativo, la variabile viene ridotta di conseguenza); nel secondo caso di assegna alla variabile
il prodotto tra quanto contenuto prima per il valore indicato; nel terzo caso si divide il contenuto
della variabile per il valore, assegnando alla stessa il risultato della divisione.
Come si può osservare, la parola chiave ‘by’ è facoltativa e si può usare per facilitare la lettura
umana dell’istruzione.
Il valore usato deve essere del tipo adatto alla variabile con cui si esegue l’operazione. Viene
mostrato un esempio complessivo che dovrebbe essere comprensibile a sufficienza:
TeX: introduzione
2472
\countdef\pagina=0
\pagina=1
\newcount\contatore
\contatore=-7
\newdimen\lunghezza
\lunghezza=100pt
\newskip\elastico
\elastico=10pt plus 2pt minus 1pt
pagina = \the\pagina \par
contatore = \the\contatore \par
lunghezza = \the\lunghezza \par
elastico = \the\elastico \par
\multiply\pagina by 2
\advance\contatore by 1
\advance\lunghezza by 10pt
\advance\elastico by 5pt plus 3pt minus 2pt
pagina = \the\pagina \par
contatore = \the\contatore \par
lunghezza = \the\lunghezza \par
elastico = \the\elastico \par
\divide\lunghezza by 2
\divide\elastico by 2
lunghezza = \the\lunghezza \par
elastico = \the\elastico \par
!
"
# # !# # # % # $ # Va tenuta in considerazione una scorciatoia importante per rappresentare il prodotto tra una
costante numerica e il valore di una lunghezza, che si usa di solito per gli assegnamenti:
n \nome
In questo caso, il numero n non deve esprimere una lunghezza, pertanto non può contenere
l’indicazione dell’unità di misura. Per esempio, se ‘\hsize’ contiene la lunghezza 15 cm, con
l’istruzione seguente si assegna alla variabile ‘\mezza’ la metà di questa lunghezza, ovvero
7,5 cm:
\mezza=0.5\hsize
Nell’esempio seguente si creano due variabili: una contiene una lunghezza e l’altra una lunghezza elastica. Dopo aver controllato il valore iniziale di queste, si riassegna loro la metà del
loro valore di partenza, controllando successivamente il risultato ottenuto. Si può osservare che
‘\elastico’ perde l’informazione sull’elasticità, diventando una lunghezza normale.
\newdimen\lunghezza
\lunghezza=100pt
\newskip\elastico
\elastico=10pt plus 2pt minus 1pt
lunghezza = \the\lunghezza \par
elastico = \the\elastico \par
\lunghezza=0.5\lunghezza
\elastico=0.5\elastico
TeX: introduzione
2473
lunghezza = \the\lunghezza \par
elastico = \the\elastico \par
230.2.7 Trasformazione in stringa di dati numerici
I dati numerici, quando devono essere convertiti in stringhe, possono essere rappresentati in forme differenti. La parola di controllo ‘\the’ consente di ottenere una trasformazione «normale»
di qualunque variabile in stringa:
\the\parola_di_controllo
Per esempio, se ‘\lunghezza’ è stata dichiarata come lunghezza contenente il valore 10 cm,
l’espansione di ‘\the\lunghezza’ può generare la stringa ‘284.45274pt’.
Un valore numerico può essere trasformato in numero intero, ammesso che ciò abbia senso, con
la parola di controllo ‘\number’:
\number\parola_di_controllo
In questo caso, se si tenta di trasformare una lunghezza in numero, si ottiene la dimensione in
punti scaled point; nel caso dell’esempio precedente, si otterrebbe la rappresentazione del valore
18646798, corrispondente ai 10 cm di prima espressi secondo l’unità di misura minima che
TeX è in grado di gestire. Per quanto riguarda le lunghezze elastiche, non è possibile usare la
trasformazione attraverso ‘\number’.
Quando il valore da trasformare è un intero positivo maggiore di zero, si può ottenere la
rappresentazione in numero romano, con lettere minuscole, attraverso la parola di controllo
‘\romannumeral’:
\romannumeral\parola_di_controllo
L’esempio seguente riepiloga l’uso delle forme di trasformazione dei dati numerici in stringa che
sono appena state descritte:
\newdimen\lunghezza
\newcount\contatore
\newcount\pagina
\lunghezza=1cm
\contatore=-7
\pagina=123
lunghezza = \the\lunghezza\ = \number\lunghezza scaled point \par
contatore = \the\contatore\ = \number\contatore \par
pagina = \the\pagina\ = \number\pagina = \romannumeral\pagina \par
!#" #" $% $ & ' ' TeX: introduzione
2474
230.2.8 Controllo del campo di azione delle variabili
Le parentesi graffe, oppure le parole di controllo ‘\bgroup’ e ‘\egroup’, servono a delimitare e
isolare una zona rispetto al testo che si trova al loro esterno. Una dichiarazione o un assegnamento
fatto all’interno di una zona delimitata da parentesi graffe ha effetto in quell’ambito e in tutte le
altre zone che possono essere annidate al suo interno, mentre all’esterno non esiste più. Si osservi
l’esempio seguente:
\newdimen\lunghezza
\newcount\contatore
\lunghezza=1cm
\contatore=7
{
\lunghezza=10cm
\contatore=14
{
\lunghezza=100cm
\contatore=21
lunghezza = \the\lunghezza{} contatore = \the\contatore \par
}
lunghezza = \the\lunghezza{} contatore = \the\contatore \par
}
lunghezza = \the\lunghezza{} contatore = \the\contatore
\bye
Si otterrà il testo che segue:
Perché un assegnamento abbia valore in modo globale, si usa la parola di controllo ‘\global’.
Si osservi l’esempio seguente:
\newdimen\lunghezza
\newcount\contatore
\lunghezza=1cm
\contatore=7
{
\lunghezza=10cm
\contatore=14
{
\global\lunghezza=100cm
\contatore=21
lunghezza = \the\lunghezza{} contatore = \the\contatore \par
}
lunghezza = \the\lunghezza{} contatore = \the\contatore \par
}
lunghezza = \the\lunghezza{} contatore = \the\contatore
\bye
In questo caso, la lunghezza appare essere sempre di 100 cm (2845,27559 punti normali), anche
quando si ritorna al di fuori dei raggruppamenti. In pratica, si otterrà il testo che segue:
TeX: introduzione
2475
230.2.9 Ordine nell’espansione delle sequenze di controllo
Esiste un problema con TeX, legato all’ordine in cui vengono espanse le parole di controllo.
L’esempio più comune è dato dalla difficoltà con cui si riesce a trasformare un numero romano
ottenuto da ‘\romannumeral’ in maiuscolo. Per esempio,
\newcount\pagina
\pagina=4
\uppercase{\romannumeral\pagina}
genera solo:
In pratica, ‘\uppercase’ si trova a intervenire su una stringa che ancora non c’è, per cui non succede nulla. Per risolvere il problema si usa la parola di controllo ‘\expandafter’ che anticipa
l’esecuzione di ciò che segue:
\newcount\pagina
\pagina=4
\uppercase\expandafter{\romannumeral\pagina}
Purtroppo il funzionamento di questa parola di controllo non è intuitivo e spesso si devono fare
vari tentativi prima di riuscire a fare ciò che si intende.
230.3 Dichiarazione di macroistruzioni
Si può dare un nome a un’espressione stringa attraverso la sintassi seguente:
\def\nome {espressione_stringa }
Si osservi che, al contrario di altre situazioni, qui TeX richiede che la parentesi graffa aperta
segua immediatamente il nome (o il simbolo dell’ultimo parametro, come verrà descritto nel
seguito), senza alcuna spaziatura intermedia.
Questo tipo di dichiarazione serve in generale per realizzare delle macroistruzioni; tuttavia, utilizzandola solo così, si fa in modo di ottenere l’espansione di ciò che è contenuto fra le parentesi
graffe nel momento in cui si inserisce nel testo l’istruzione ‘\nome ’. Si osservi l’esempio:
\def\eTeX{e-\TeX}
Bla bla bla bla \eTeX{} bla bla...
\bye
In questo caso si vuole dichiarare la parola di controllo ‘\eTeX’, con cui diventa facile uniformare
la scrittura di questo nome nel testo. Se ci fosse un ripensamento sulla forma da dare al nome,
basterebbe modificare la sua dichiarazione iniziale.
Una macro del genere può essere modificata solo riassegnandole un altro valore, nello stesso
modo usato per la sua dichiarazione iniziale.
È importante ricordare che in fase di composizione, le parole di controllo assorbono gli spazi
alla loro destra, per cui è necessario usare una tecnica per evitarlo, che di solito si riduce
all’inserimento di un gruppo vuoto alla fine della stessa.
TeX: introduzione
2476
Nel momento in cui si utilizza una parola di controllo corrispondente a una macro dichiarata in
questo modo, si ottiene l’espansione del suo contenuto. In altri termini, la parola di controllo
diventa una forma abbreviata per scrivere un testo più articolato, che può contenere a sua volta
altre sequenze di controllo, che vengono espanse solo all’ultimo momento. Si osservi l’esempio
seguente:
\def\resistenza{\valore{} ohm \tolleranza{} \%}
\def\valore{100}
\def\tolleranza{5}
25 resistenze \resistenza \par
\def\valore{300}
\def\tolleranza{1}
30 resistenze \resistenza \par
\bye
Si otterrà un testo simile a quello seguente, con cui si comprende il fatto che le parole di controllo
‘\valore’ e ‘\tolleranza’ vengono espanse per ultime:
L’espansione di una parola di controllo del genere avviene in modo letterale, salvo naturalmente
l’espansione successiva del suo contenuto, ma questo fatto significa che vengono riprodotte anche le interruzioni delle righe e gli spazi. Alle volte si preferisce strutturare il contenuto di una
dichiarazione del genere, per cui si utilizzano dei commenti per evitare di dare un significato agli
spazi che si inseriscono. Si osservi l’esempio precedente dopo una piccola modifica:
\def\resistenza{
\valore{} ohm \tolleranza{} \%}
\def\valore{100}
\def\tolleranza{5}
25 resistenze \resistenza \par
\def\valore{300}
\def\tolleranza{1}
30 resistenze \resistenza \par
\bye
In questo caso, ciò che si ottiene è diverso, perché la parola di controllo ‘\resistenza’ si
espande inserendo inizialmente una riga vuota, ovvero ciò che poi si traduce nell’inizio di un
paragrafo nuovo:
Per evitare questo tipo di inconveniente, si può mettere un commento all’inizio della riga vuota,
che così perde questa sua particolarità:
\def\resistenza{
%
\valore{} ohm \tolleranza{} \%}
Di solito, in queste situazioni si mette un commento anche dopo la parentesi graffa aperta:
TeX: introduzione
2477
\def\resistenza{%
%
\valore{} ohm \tolleranza{} \%}
Oltre a questo è da tenere in considerazione che nel momento dell’espansione, ciò che si ottiene
non risulta contenuto in una zona separata; in altri termini, ciò che viene dichiarato o modificato
all’interno di questa definizione, continua a valere anche al di fuori. Eventualmente, se si intende che l’espansione debba generare una zona isolata, vanno usate le parentesi graffe come già
mostrato. Per esempio:
\def\attenzione{{\bf ATTENZIONE!!!}}
In questo caso, l’istruzione ‘\bf’ inizia la scrittura in neretto; così, la parola di controllo
‘\attenzione’ permette di inserire la scritta che si vede, in neretto, senza interferire con il
testo successivo.
Gli esempi usati fino a questo punto sono riconducibili all’idea di una funzione che non prevede
parametri per la chiamata, ricevendo i dati attraverso variabili globali. Per dichiarare una macro
in grado di ricevere dei parametri si usa una dichiarazione come quella seguente:
[ [ ]]{espressione_stringa }
\def\nome #1 #2... #9
In una dichiarazione del genere si possono indicare un massimo di nove parametri, rappresentati
da ‘#1’, ‘#2’,... ‘#9’, che possono essere inseriti nella stringa contenuta tra le parentesi graffe.
Volendo modificare l’esempio già visto, le cose si potrebbero semplificare nel modo seguente:
\def\resistenza#1#2{#1 ohm #2 \%}
25 resistenze \resistenza{100}{5} \par
30 resistenze \resistenza{300}{1}
\bye
Nella dichiarazione, i simboli ‘#n ’ che si inseriscono all’interno del testo contenuto tra parentesi
graffe possono essere indicati anche più volte, ottenendo sempre l’espansione del parametro n esimo corrispondente.
È ormai evidente il modo in cui deve essere usata la parola di controllo che può essere chiamata
con dei parametri:
[
[...{parametro_n }]]
\nome {parametro_1 } {parametro_2 }
È importante sottolineare che, contrariamente a quanto si potrebbe immaginare, la stringa
utilizzata in un parametro di scambio non può essere separata in paragrafi.
Si osservi che molte macro predefinite di TeX isolano l’espressione stringa che restituiscono all’interno di un raggruppamento, in modo tale che ciò che si cambia al suo interno non si rifletta
nel testo successivo. Di solito questo fatto è un comportamento «logico», o intuitivo, ma non
si deve pensare che la definizione di una macro implichi automaticamente questa forma di isolamento. In pratica, il fatto di usare una parola di controllo del tipo ‘\nome {espressione }’, non
significa implicitamente che quanto inserito come parametro non debba anche influenzare il testo
successivo.
230.3.1 Chiamata di macroistruzioni che richiedono l’indicazione di
parametri
È stata mostrata la sintassi per la chiamata di una macro che richiede l’indicazione di uno o più
parametri:
TeX: introduzione
2478
[
[...{parametro_n }]]
\nome {parametro_1 } {parametro_2 }
Tuttavia, si tratta di una semplificazione. Infatti, i parametri possono anche non essere racchiusi
tra parentesi graffe, ma in tal caso, il primo parametro sarà il primo carattere che segue. Si osservi
l’esempio seguente, in cui si dichiara una macro con tre parametri e poi la si chiama senza
raggruppare i parametri:
\def\ciao#1#2#3{%
Primo parametro: #1\par
Secondo parametro: #2\par
Terzo parametro: #3\par
}
\ciao, come stai?
Nel capitolo 231 verrà mostrato l’uso di macro come ‘\‘’ che servono ad aggiungere un accento
alla lettera successiva. Queste si usano solitamente senza circoscrivere la lettera che segue entro
parentesi graffe.
230.4 Riferimenti ad altre parole o simboli di controllo
È possibile creare dei riferimenti a una parola o a un simbolo di controllo, usando la sintassi
seguente:
\let\nome_nuovo =\nome
In pratica, in questo modo si crea una parola di controllo alternativa a un’altra già esistente:
‘\nome_nuovo ’ può essere usato al posto di ‘\nome ’.6 Si osservi l’esempio:
\newdimen\altezza
\altezza=10cm
\let\grandezza=\altezza
\altezza=20cm
La scatola ha una grandezza di \the\grandezza.
\bye
Si ottiene in pratica il testo
dove 569,05511 punti corrispondono esattamente a 20 cm, ovvero l’ultimo valore assegnato alla
lunghezza ‘\altezza’, a cui punta anche ‘\grandezza’.
Tuttavia, se si fa un esperimento simile con una parola di controllo corrispondente a una macro
definita con l’istruzione ‘\def’, il riferimento che si genera con l’istruzione ‘\let’ è quello che
punta alla macro di quel momento, mentre una ridefinizione della parola di controllo di partenza
non si riflette nel riferimento:
\def\resistenza#1#2{#1 ohm #2 \%}
\let\prova=\resistenza
25 resistenze \resistenza{100}{5}
25 resistenze \prova{100}{5}
6
Si possono creare delle alternative anche a simboli di controllo, ma in generale ciò non è conveniente.
TeX: introduzione
2479
\def\resistenza#1#2{#2 ohm #1 \%}
30 resistenze \resistenza{300}{1}
30 resistenze \prova{300}{1}
\bye
Quello che si ottiene dalla composizione di questo esempio è il testo seguente:
230.5 Testo normale e ambienti matematici
Una caratteristica molto importante di TeX è la distinzione tra due modalità di funzionamento. In
pratica, si distingue un contesto «normale» da un contesto matematico. L’ambiente matematico si
introduce e si conclude con il simbolo ‘$’ e in tale situazione diventano disponibili delle istruzioni
che non si possono utilizzare al di fuori di questo ambito, mentre alcune istruzioni che erano
disponibili prima non lo sono più.
Per esempio, alcuni caratteri esistono solo nell’ambiente matematico; è già stato visto in che
modo vanno indicate le parentesi graffe quando si scrive in un ambito normale, attraverso le
istruzioni ‘$\{$’ e ‘$\}$’. In pratica, il dollaro iniziale e finale di queste istruzioni serve ad
aprire e a chiudere l’ambiente matematico.
230.6 Modalità orizzontale e modalità verticale
Nel suo lavoro di composizione, TeX distingue due situazioni, definite come modalità orizzontale
e modalità verticale. Per comprendere la differenza tra queste due situazioni, occorre pensare alla
struttura di ciò che si inserisce in una pagina.
Ogni oggetto che viene inserito in una pagina è una scatola, con le sue dimensioni. Queste scatole si inseriscono a loro volta all’interno di altre; per esempio, una lettera è una scatola che si
inserisce in una riga, ovvero un’altra scatola, che a sua volta si inserisce in un paragrafo, ovvero
ancora un’altra scatola, ecc.
In base al contesto, orizzontale o verticale, TeX si occupa di inserire spazi orizzontali o verticali:
tra le lettere di una parola, tra le parole, tra le righe, tra i paragrafi, ecc.
Quello che conta comprendere di tutto questo è che alcune istruzioni possono essere inserite solo
in modalità orizzontale, altre solo in modalità verticale. Volendo sperimentare se un certo contesto si trovi in modalità orizzontale o verticale, si può realizzare la macro seguente e collocarla
nel testo dove si ritiene opportuno; nella composizione finale si otterrà alternativamente la frase
«modalità orizzontale», oppure «modalità verticale»:
\def\verificamodo{%
\ifvmode
modalit\‘a verticale
\else
modalit\‘a orizzontale
\fi}
Nella sezione 230.7 viene spiegato l’uso dell’istruzione ‘\ifvmode’.
TeX: introduzione
2480
230.7 Strutture di controllo
Il linguaggio di TeX possiede una serie di strutture di controllo condizionali, in cui parte della
condizione è implicita nel nome dell’istruzione con cui la si introduce. Questo insieme di strutture
ha una sintassi comune riconducibile alla semplificazione seguente:
[
]
\ifnome_condizione
argomento
testo_e_altre_istruzioni_se_vero
\else
testo_e_altre_istruzioni_se_falso
\fi
Spesso, per completare la struttura anche quando una delle due ipotesi non deve generare alcun
risultato, si utilizza l’istruzione ‘\relax’, che rappresenta proprio l’operazione nulla.
Nelle sezioni seguenti vengono descritte solo le strutture condizionali più comuni.
230.7.1 \ifodd
È possibile verificare se un numero intero è dispari o pari con la struttura seguente:
\ifodd n
testo_e_altre_istruzioni_se_dispari
\else
testo_e_altre_istruzioni_se_pari
\fi
Di solito, al posto del numero n si inserisce l’istruzione ‘\pageno’ che restituisce il numero
della pagina corrente, permettendo così di verificare se la pagina è dispari o pari:
\ifodd \pageno
testo_e_altre_istruzioni_se_pagina_dispari
\else
testo_e_altre_istruzioni_se_pagina_pari
\fi
230.7.2 \ifmmode
È possibile verificare se ci si trova in modalità normale o in modalità matematica con la struttura
seguente:
\ifmmode
testo_e_altre_istruzioni_se_modalità_matematica
\else
testo_e_altre_istruzioni_se_modalità_normale
\fi
230.7.3 \ifnum
È possibile mettere a confronto due numeri con la struttura seguente:
||
\ifnum m = > <n
testo_e_altre_istruzioni_se_confronto_valido
\else
testo_e_altre_istruzioni_se_confronto_non_valido
\fi
In pratica, il confronto può avvenire solo con gli operatori ‘=’, ‘>’ e ‘<’, per indicare rispettivamente se i due valori sono uguali, se il primo è maggiore del secondo oppure se il primo è minore
del secondo.
TeX: introduzione
2481
230.7.4 \ifhmode e \ifvmode
È possibile verificare se la composizione si trova in modalità orizzontale o verticale con una delle
due strutture seguenti:
\ifhmode
testo_e_altre_istruzioni_se_modalità_orizzontale
\else
testo_e_altre_istruzioni_se_modalità_verticale
\fi
\ifvmode
testo_e_altre_istruzioni_se_modalità_verticale
\else
testo_e_altre_istruzioni_se_modalità_orizzontale
\fi
230.8 Verifica del significato di un’istruzione elementare
Per TeX, un’istruzione elementare può essere il singolo carattere di una parola, oppure una sequenza di controllo. Volendo comprendere il senso di qualcosa, si può verificare come intenda
TeX questa o quell’istruzione. Per questo, occorre avviare la composizione indicando un file
vuoto; per esempio, in un sistema Unix si potrebbe fare così:
$ tex /dev/null[ Invio ]
This is TeX, Version 3.14159 (Web2C 7.3.1)
(/dev/null)
*
A questo punto, dall’invito, si può usare l’istruzione ‘\show’ nel modo seguente:
\show istruzione_elementare
Per esempio, ci si può domandare se il carattere ‘@’ abbia un significato particolare:
*\show @[ Invio ]
> the character @.
<*> \show @
?
A questo punto, la composizione si ferma in attesa di altre indicazioni, mostrando un invito differente. Questo permette di comprendere anche che non conviene usare ‘\show’ in un file normale
del quale si vuole ottenere la composizione, perché in quel punto ci sarebbe una sospensione con
richiesta di intervento. A ogni modo, per proseguire basta premere [ Invio ], quindi si può chiedere
di conoscere qualcosa di diverso:
?[ Invio ]
*\show \TeX[ Invio ]
In questo caso si vuole conoscere in cosa consiste la macro ‘\TeX’ ed ecco il risultato che si
ottiene:
> \TeX=macro:
->T\kern -.1667em\lower .5ex\hbox {E}\kern -.125emX.
<*> \show \TeX
?
Pertanto, questo significa che ‘\TeX’ è definita come:
TeX: introduzione
2482
\def\TeX{T\kern -.1667em\lower .5ex\hbox {E}\kern -.125emX}
Per completare l’esempio, conviene vedere come appare una macro che prevede l’indicazione di
un parametro, come nel caso di ‘\‘’, che serve a mettere un accento grave su una lettera:
?[ Invio ]
*\show \‘[ Invio ]
> \‘=macro:
#1->{\accent 18 #1}.
<*> \show \‘
?
In pratica, la definizione originale è la seguente:
\def\‘#1{{\accent 18 #1}}
Per terminare l’uso interattivo basta inserire alla fine l’istruzione ‘\bye’:
?[ Invio ]
*\bye[ Invio ]
No pages of output.
Transcript written on null.log.
230.9 Riferimenti
• General documentation about (La)TeX
<http://tex.loria.fr/english/general.html>
• Michael Doob, A gentle introduction to TeX
<http://www.ctan.org/tex-archive/info/gentle/gentle.pdf>
• Daniel M. Zirin, TeX made easy, Using TeX with plain macro package, 1993, Zar Limited
<http://www.loria.fr/services/tex/general/all.dvi>
• D. R. Wilkins, Getting started with plain TeX, 1993
<http://www.loria.fr/services/tex/general/pllong.dvi>
• D. R. Wilkins, Summary of commonly-used features of plain TeX, 1993
<http://www.loria.fr/services/tex/general/plshort.dvi>
• TeX cookbook, 1989, MathPro Press
<http://www.loria.fr/services/tex/general/cookbook.dvi>
• Sorgenti della definizione del formato ‘tex’, contenuti nella directory ‘texmf/tex/
plain/base/’ di una distribuzione teTeX
• Sorgenti della definizione del formato ‘latex’, contenuti nel file ‘texmf/tex/latex/
base/latex.ltx’ di una distribuzione teTeX
• Claudio Beccari, LaTeX, Guida a un sistema di editoria elettronica, Hoepli, 1991, ISBN
88-203-1931-4
Appunti di informatica libera 2003.01.01 --- Copyright © 2000-2003 Daniele Giacomini -- daniele @ swlibero.org
Capitolo
231
TeX: caratteri
In condizioni normali, il testo scritto nel sorgente viene riprodotto nello stesso modo nella composizione finale, dopo essere stato reimpaginato opportunamente. Tuttavia, alcuni simboli hanno
significati speciali, per cui si devono usare simboli di controllo al loro posto, inoltre le lettere accentate e altri caratteri che non fanno parte dell’ASCII standard non possono essere usati
direttamente, per cui servono altri simboli o parole di controllo per generarli.
A fianco di questo problema, nasce poi l’esigenza di poter scrivere utilizzando stili, forme e corpi
differenti.
231.1 Caratteri speciali
Come è già stato descritto nella tabella 230.1, alcuni caratteri hanno un significato speciale e
non producono il simbolo corrispondente in fase di composizione. Per porre rimedio a questo
problema e alla mancanza di altri caratteri, si usano generalmente delle sequenze di controllo.
Tuttavia, dal momento che si distinguono due contesti di composizione differenti (quello normale
e quello matematico), certi caratteri o certe sequenze di controllo esistono solo nella modalità
matematica.
In generale, salvo altra indicazione, si fa sempre riferimento alla modalità di composizione normale, per cui un carattere o una sequenza di controllo che può apparire solo in modalità matematica, viene mostrata generalmente delimitandola tra due simboli ‘$’. Per esempio, quando si
afferma che le parentesi graffe si ottengono con le istruzioni ‘$\{$’ e ‘$\}$’, è chiaro che in
modalità matematica non serve più la delimitazione con i simboli ‘$’.
La tabella 231.1 riepiloga le sequenze di controllo per i caratteri speciali disponibili.1
Tabella 231.1. Elenco delle sequenze di controllo necessarie a ottenere i caratteri
speciali che non richiedono la sovrapposizione di accenti.
1
Leggendo la tabella, è il caso di osservare che in condizioni normali, la sequenza di controllo ‘\$’ genera il simbolo
del dollaro, mentre se il testo è in corsivo, si ottiene il simbolo della sterlina inglese.
2483
2484
"
'
&
)
-
+
2
6
8
<
A !B
.
31
5
9
= > ? 5 ;
A B
TeX: caratteri
!
$%!
$%$
#
$&
(
*)
,
/
4
7
:
@@@
*
01
5
; ; 231.2 Accenti
TeX ha la capacità di collocare un accento sopra ogni simbolo, anche se ciò che si ottiene può
non avere senso per qualunque lingua. Questa apposizione di accenti si ottiene con sequenze di
controllo che precedono la lettera da accentare. Quando si tratta di simboli di controllo, la lettera
successiva può essere unita alla sequenza, mentre quando si tratta di parole di controllo occorre
lasciare uno spazio di sicurezza. Per esempio, si scrive ‘\‘o’ per ottenere la lettera «ò», mentre
si scrive ‘\c c’ per ottenere la lettera ‘ç’.2 La tabella 231.2 riepiloga le sequenze di controllo
necessarie a ottenere tutti gli accenti disponibili, usando la lettera «o» come esempio.
Tabella 231.2. Elenco delle sequenze di controllo necessarie a ottenere le lettere
accentate.
#
2
$ %
!"
Si osservi che in questo caso non si può usare un raggruppamento vuoto al posto dello spazio, perché l’accento
risulterebbe spostato rispetto al centro della lettera.