[inizio] [indice generale] [precedente] [successivo] [indice analitico] [contributi]


71. File e filtri per la stampa

Il sistema che gestisce le code dei processi di stampa e la stampa remota, rappresenta solo una parte della soluzione del problema della stampa. È importante chiarire in che modo devono essere composti i file per la stampa, e come questi vanno gestiti dai filtri di stampa.

71.1 File per la stampa

Negli ambienti Unix si utilizzano normalmente due tipi fondamentali di file per la stampa:

Teoricamente, i file di testo sono stampabili con qualunque tipo di stampante, mentre i file PostScript richiedono una stampante PostScript. In pratica, quasi sempre non è possibile stampare un file di testo così com'è, e raramente si dispone di una stampante PostScript.

Negli ambienti Unix i file di testo (o file ASCII) seguono la convenzione dell'interruzione di riga attraverso il codice ASCII <LF>. Con il sistema operativo Dos è stato introdotto un codice differente, corrispondente a <CR><LF>. La maggior parte delle stampanti in circolazione è adatta a quest'ultimo tipo di interruzione di riga, per cui, il solo carattere <LF> produce un avanzamento alla riga successiva, senza il ritorno alla prima colonna. Quando si invia un file di testo in stile Unix a una stampante che richiede l'interruzione di riga in stile Dos, si ottiene il noto effetto scalettatura. Per esempio, supponendo di voler stampare un file contenente il testo

Uno
Due
Tre

si ottiene invece quello che segue:

Uno
   Due
      Tre

Per ovviare a tale inconveniente, prima di inviare un file di testo Unix a una stampante normale, occorre trasformare i codici di interruzione di riga in modo che comprendano sia <CR> che <LF>.

Il programma che tipicamente è in grado di eseguire questa conversione è `unix2dos'. Di questo ne esistono diverse edizioni, tutte incompatibili tra loro, accomunate solo dallo scopo. Qui si fa riferimento a un programma filtro, ovvero a uno `unix2dos' che riceve il file da convertire dallo standard input e che restituisce il risultato attraverso lo standard output (è importante sottolineare questo fatto perché esistono delle versioni che non si comportano così). I filtri di stampa sono descritti più avanti in questo capitolo, per il momento dovrebbe bastare sapere che si può utilizzare il programma `unix2dos' (o un altro programma simile) prima di inviare il file al programma `lpr', come si vede nell'esempio seguente:

cat esempio.txt | unix2dos | lpr

Come accennato, il programma `unix2dos' non è standard e a volte si può incontrare una versione che non funziona esattamente come negli esempi indicati qui. Eventualmente, se la propria distribuzione GNU/Linux dispone di questo programma di utilità, conviene consultare la sua documentazione: unix2dos(1).

In alternativa al programma `unix2dos' si può scrivere uno script Perl molto semplice e intuitivo, anche per chi non conosce tale linguaggio (che viene descritto a partire dal capitolo 165).

#!/usr/bin/perl
#======================================================================
# filtro-crlf.pl < <file-input> > <file-output>
#======================================================================

$riga = "";

while( $riga = <STDIN> ) {

    #------------------------------------------------------------------
    # Elimina il codice di interruzione di riga finale,
    # indipendentemente dal fatto che possa essere costituito da <LF>
    # o anche da <CR><LF>.
    #------------------------------------------------------------------
    chomp $riga;

    #------------------------------------------------------------------
    # Emette la riga con l'aggiunta di <CR> e <LF>.
    #------------------------------------------------------------------
    print "$riga\r\n";
};
#======================================================================

Il sistema PostScript ha introdotto una sorta di rivoluzione nel modo di stampare: attraverso un linguaggio standardizzato ha reso la stampa indipendente dal tipo particolare di stampante utilizzato. L'unico inconveniente delle stampanti PostScript era, ed è, il prezzo.

Fortunatamente, negli ambienti Unix è disponibile il programma Ghostscript in grado di trasformare un file PostScript in diversi formati, ognuno compatibile con un tipo diverso di stampante.

Nella maggior parte dei casi, quando cioè non si dispone di una stampante PostScript, si devono convertire i file PostScript in un formato accettabile dalla propria stampante. L'uso dei filtri di stampa permette di automatizzare questa operazione. Nel capitolo 72 viene descritto con maggiore dettaglio in che modo questi file PostScript possono essere gestiti.

71.2 Filtri di stampa

Attraverso il file `/etc/printcap', per ogni singolo record di descrizione di una coda, è possibile definire un gran numero di filtri di stampa, ognuno con uno scopo particolare. Di fatto, è preferibile limitarsi a utilizzarne uno solo, e precisamente quello del campo `if', o Input Filter. Il programma o lo script indicato nel campo `if' riceve alcuni argomenti:

<filtro-if> [<opzioni>]

In particolare:

A meno di non studiare in modo approfondito l'uso del sistema di stampa di cui si dispone, la maggior parte di questi argomenti sono inutilizzabili. È molto più facile costruire un file di configurazione aggiuntivo, da fare leggere al filtro ogni volta che viene avviato, piuttosto che pretendere di fare tutto attraverso l'interpretazione degli argomenti ottenuti automaticamente. In ogni caso, si può contare su due argomenti, eventualmente utilizzabili per produrre intestazioni, o per produrre un registro (un log): il nome dell'utente e il nome dell'elaboratore.

71.2.1 Filtro diagnostico

Gli argomenti forniti al filtro di stampa potrebbero essere diversi da quanto dichiarato dalla documentazione, e comunque vale la pena di verificare cosa succede costruendo la prima volta un filtro diagnostico simile allo script seguente:

#!/bin/bash
pwd > /tmp/test-stampa
echo $1 >> /tmp/test-stampa
echo $2 >> /tmp/test-stampa
echo $3 >> /tmp/test-stampa
echo $4 >> /tmp/test-stampa
echo $5 >> /tmp/test-stampa
echo $6 >> /tmp/test-stampa
echo $7 >> /tmp/test-stampa
echo $8 >> /tmp/test-stampa
echo $9 >> /tmp/test-stampa
echo ${10} >> /tmp/test-stampa
echo ${11} >> /tmp/test-stampa
echo ${12} >> /tmp/test-stampa
echo ${13} >> /tmp/test-stampa
echo ${14} >> /tmp/test-stampa
echo ${15} >> /tmp/test-stampa
echo ${16} >> /tmp/test-stampa
echo ${17} >> /tmp/test-stampa
echo ${18} >> /tmp/test-stampa
echo ${19} >> /tmp/test-stampa
echo ${20} >> /tmp/test-stampa

Come si può vedere, viene creato il file `/tmp/test-stampa' con l'indicazione della directory corrente (`pwd') e quindi l'elenco dei contenuti dei vari parametri, ovvero l'elenco degli argomenti ricevuti. La voce (il record) di `/etc/printcap' che utilizza questo filtro potrebbe essere composta nel modo seguente (`/var/spool/lpd/prova/filtro-prova' è il nome dello script visto sopra).

prova:\
	:sd=/var/spool/lpd/prova:\
	:mx#0:\
	:sh:\
	:lp=/dev/lp0:\
	:if=/var/spool/lpd/prova/filtro-prova:

Quando si stampa utilizzando la voce `prova' non si ottiene alcuna stampa: viene creato il file `/tmp/test-stampa'. *1*

tizio@dinkel.brot.dg$ lpr -Pprova lettera

Il comando precedente, avviato dall'utente `tizio' a partire dall'elaboratore `dinkel.brot.dg', dovrebbe generare il file `/tmp/test-stampa' con il contenuto seguente:

/var/spool/lpd/prova
-hdinkel.brot.dg
-l66
-ntizio
-w80
...

Al contrario, un sistema imperfetto potrebbe non corrispondere alle aspettative. Si osservi a questo proposito l'esito seguente che è stato ottenuto in passato sa un sistema di stampa BSD imperfetto:

/var/spool/lpd/prova
-w132
-l66
-i0
tizio
-h
dinkel.brot.dg

Qui si può notare che l'opzione `-n' non esiste, e al suo posto viene fornito il nome dell'utente senza il prefisso di alcuna opzione.

Una cosa utile da osservare è la directory corrente: corrisponde sempre alla directory della coda di stampa.

71.2.2 Filtri elementari

Quando si realizza un filtro di stampa personalizzato, raramente si vanno a cercare sottigliezze che sono comunque già disponibili all'interno di pacchetti di filtri già fatti da altri. Di solito ci si accontenta di trasformare lo standard input e di restituire uno standard output adatto alle proprie esigenze, ignorando completamente gli argomenti che il filtro riceve.

L'esempio tipico è il filtro che permette di stampare un file di testo in stile Unix su una stampante che richiede la conclusione della riga attraverso <CR><LF>. Come già accennato all'inizio del capitolo, basta utilizzare il programma `unix2dos' (purché ci sia e funzioni come filtro), oppure lo script che è stato mostrato.

Bisogna fare attenzione: il filtro di stampa riceve degli argomenti, anche se questi non servono. Se si tenta di utilizzare `unix2dos', o qualunque altro programma direttamente come filtro, si rischia di ottiene solo una segnalazione di errore in quanto potrebbe non essere in grado di comprendere gli argomenti ricevuti. Per risolvere il problema, occorre realizzare uno script, in modo da poter eliminare gli argomenti inutilizzati.

Segue l'esempio di una voce del file `/etc/printcap':

testo:\
	:sd=/var/spool/lpd/testo:\
	:mx#0:\
	:sh:\
	:lp=/dev/lp1:\
	:if=/var/spool/lpd/testo/filtro:

Segue l'esempio dello script utilizzato come filtro:

#!/bin/bash
/usr/bin/unix2dos

È necessario osservare un paio di particolari:

Infatti, non si può contare sulla conoscenza della directory corrente nel momento in cui questi vengono messi in esecuzione.

71.2.3 Filtri PostScript

Tutti i filtri di stampa in grado di convertire file PostScript in qualcosa di stampabile senza una stampante PostScript, si avvalgono del programma Ghostscript (`gs'). L'esempio seguente mostra uno script che riceve dallo standard input un file PostScript e restituisce attraverso lo standard output un file stampabile con una HP Laserjet o compatibile.

#!/bin/bash
/usr/bin/gs -q -dNOPAUSE -sPAPERSIZE=a4 -sDEVICE=laserjet -sOutputFile=- -

71.2.4 Problemi

In passato è capitato che una versione particolare del sistema di stampa BSD per GNU/Linux avesse un difetto che non le permetteva di utilizzare il flusso di dati proveniente dal filtro di stampa. Nel caso dovesse verificarsi nuovamente questa situazione, si può utilizzare un trucco: il filtro di stampa riceve i dati dallo standard input nel modo solito e li trasforma. Quindi, invece di emettere il risultato della sua elaborazione attraverso lo standard output, lo invia a un'altra coda di stampa.

In pratica, si può supporre che il file `/etc/printcap' sia composto come segue:

lp:\
	:sd=/var/spool/lpd/lp:\
	:mx#0:\
	:sh:\
	:lp=/dev/lp0:

testo:\
	:sd=/var/spool/lpd/testo:\
	:mx#0:\
	:sh:\
	:lp=/dev/lp0:\
	:if=/var/spool/lpd/testo/filtro:

Supponendo che la trasformazione del testo avvenga tramite il programma `unix2dos', il filtro `/var/spool/lpd/testo/filtro' potrebbe essere realizzato nel modo seguente:

#!/bin/bash
/usr/bin/unix2dos | lpr -Plp

71.2.5 Filtri sofisticati

Non è necessario complicarsi troppo la vita. Spesso la distribuzione GNU/Linux che si ha a disposizione è già predisposta in modo da facilitare la creazione di filtri di stampa. In particolare, Red Hat fornisce un pannello di controllo grafico intuitivo.

Anche quando non si è così «fortunati», esiste sempre un'alternativa migliore allo scriversi il proprio filtro (salvo casi particolari). Un esempio è ApsFilter che senza molta fatica genera da solo il file `/etc/printcap', le directory per le code di stampa e i filtri necessari; un altro è Magicfilter, più semplice, ma efficace.

Infine, è il caso di ricordare il pacchetto PSUtils che è composto da una serie di programmi di utilità in grado di rielaborare file PostScript, cosa utile per esempio quando su un solo foglio si vogliono stampare più pagine ridotte.

71.3 Magicfilter

Magicfilter è un sistema di filtri per la stampa organizzato in modo semplice ed efficace. Si tratta di un programma, precisamente l'eseguibile `magicfilter', in grado di individuare il tipo di file che gli viene fornito attraverso lo standard input e di conseguenza di elaborarlo nel modo migliore ai fini della stampa. Per ottenere questo risultato, è necessaria la preparazione di un file di configurazione, con il quale si indicano le impronte di riconoscimento dei file, ovvero il magic number, e le azioni da compiere a seconda del tipo di file individuato. Questo comportamento spiega la ragione del nome: un filtro di stampa abbinato all'individuazione del magic number.

L'idea più importante di Magicfilter sta nel fatto che i suoi file di configurazione, che si distinguono in base al tipo di stampante per i quali devono essere utilizzati, sono degli script per Magicfilter. Questo fatto semplifica tante cose, soprattutto nella configurazione del file `/etc/printcap'.

71.3.1 Configurazione di Magicfilter

Il file di configurazione tipico di Magicfilter inizia generalmente con la dichiarazione del suo interprete, essendo in pratica uno script dell'eseguibile `magicfilter':

#! /usr/sbin/magicfilter

In questo file, il simbolo `#' serve a indicare l'inizio di un commento, fino alla fine della riga; le righe bianche e quelle vuote vengono ignorate. Le altre righe, sono direttive, secondo la sintassi seguente:

<scostamento> <stringa-di-riconoscimento> <operazione-da-compiere>

In pratica, si tratta di campi separati da uno o più spazi: il primo è un numero che esprime lo scostamento in byte dall'inizio del file, per individuare il punto a partire dal quale si deve iniziare il confronto con la stringa indicata nel secondo campo (quello che sarebbe il magic number); il terzo campo è la descrizione delle azioni da compiere nel caso in cui il file corrisponda alla stringa di riconoscimento.

Il numero che indica lo scostamento è espresso normalmente in base decimale; può essere usata una notazione ottale, se la prima cifra è uno zero; si può utilizzare anche una notazione esadecimale che deve essere preceduta dal prefisso 0x... Il valore zero corrisponde all'inizio del file, qualunque altro valore (positivo) rappresenta un numero equivalente di byte da saltare prima di iniziare il confronto con la stringa di riconoscimento.

La stringa di riconoscimento è una stringa normale, che può contenere delle sequenze di escape secondo la convenzione del linguaggio C, oltre a due aggiunte: `\?' che rappresenta un carattere qualunque, e `\' seguita da uno spazio che rappresenta uno spazio letterale, allo scopo di non interrompere il campo. Eventualmente, questa stringa può anche essere racchiusa tra apici doppi, e in tal caso, non c'è bisogno di proteggere lo spazio con la barra obliqua inversa. *2*

L'ultima parte di queste direttive è più complessa da descrivere, in quanto si compone di una parola chiave iniziale, a cui possono seguire altre indicazioni che variano in base alla parola chiave stessa.

Questo file viene scandito dal suo interprete, `magicfilter', dall'inizio alla fine, e la scansione termina nel momento in cui una direttiva corrisponde al file, ovvero, quando i primi due campi sono tali da determinare la corrispondenza. In questo senso, le combinazioni più dettagliate devono avere la precedenza rispetto a quelle più generiche. Inoltre, esiste una variante alla sintassi di queste direttive, costituita dalla forma seguente:

default <operazione-da-compiere>

Questa direttiva va posta alla fine del file di configurazione, per indicare cosa fare con i file che non sono stati riconosciuti diversamente, e di solito viene usata proprio per gestire i file di testo.

Quando l'operazione da compiere prevede l'avvio di un programma o di uno script, vengono rese disponibili alcune variabili di ambiente, che possono essere indicate anche nell'ambito degli argomenti di questo comando. Le variabili disponibili effettivamente dipendono dalla quantità di informazioni a cui Magicfilter può accedere, e questo dipende a sua volta dalle caratteristiche del demone di stampa; tuttavia, sono disponibili sempre la variabile `LPUSER', che contiene il nome dell'utente proprietario del processo di stampa, e `LPHOST', con il nome dell'elaboratore da cui ha avuto origine la richiesta di stampa.

Alcune operazioni

cat [<prefisso> [<suffisso>]]

Questa definizione serve a ottenere la copia dei dati senza conversioni, aggiungendo eventualmente una stringa come prefisso, e una come suffisso, prima e dopo il file. Le stringhe in questione si possono realizzare nello stesso modo in cui si realizza la stringa di riconoscimento, con l'eccezione della sequenza `\?', che in questo contesto non ha significato.

ignore

reject <messaggio>

Queste due definizioni alternative, fanno in modo di non restituire dati in uscita; in particolare, `reject' tenta di inviare un messaggio all'utente a cui appartiene il processo di stampa, attraverso la posta elettronica.

filter <comando>

Il comando indicato viene eseguito e gli viene passato il flusso di dati che interessa il filtro, e ci si attende che restituisca i dati trasformati nel modo adatto per la stampa. Questo comando può accedere alle variabili di ambiente create da Magicfilter, e queste gli possono essere fornite anche tra le opzioni, usando la notazione `$<variabile>'.

pipe <comando>

Con la parola chiave `pipe' si ottiene una cosa simile a quella che si ha con `filter', con la differenza che il risultato emesso dal comando, viene rielaborato dal filtro, come passaggio ulteriore.

Questo meccanismo, se non viene usato nel modo corretto, potrebbe creare un ciclo infinito. Bisogna essere certi che prima o poi, i dati che vengono reimmessi nel filtro, trovino a un certo punto l'uscita corretta.

fpipe <comando> | ffilter <comando>

Si tratta dell'unione di `filter' e `pipe', con la differenza che il file che giunge dallo standard input viene prima salvato in un file temporaneo, il cui nome è disponibile attraverso la variabile di ambiente `FILE'. Questo permette di utilizzare un comando che accede a un file su disco, presumibilmente perché ha bisogno di accedervi in modo non sequenziale. L'elaborazione che si ottiene viene reimmessa nel filtro per un passaggio successivo.

Esempi

0	%!		filter	\
    /usr/bin/gs  -q -dSAFER -dNOPAUSE -r300 -sDEVICE=ljet4 -sOutputFile=- -

Questa direttiva serve a individuare i file PostScript, in quanto questi dovrebbero iniziare con la stringa `#!'. A questo tipo di file viene abbinata l'elaborazione da parte di `gs' (Ghostscript), con le opzioni opportune per ottenere un risultato adatto a una stampante di tipo HP Laserjet 4, emesso attraverso lo standard output.

0	\037\235	pipe	/bin/gzip  -cdq 

In questo caso, sembra trattarsi di un file compresso con `gzip', e per questo viene estratto e rinviato al filtro, in modo da rianalizzare il contenuto prima di inviarlo alla stampa.

0	MM\0\x2a	fpipe   /usr/bin/tiff2ps  $FILE
0	II\x2a\0	fpipe   /usr/bin/tiff2ps  $FILE 

Nel caso il file sembri un formato TIFF, viene utilizzato il programma `tiff2ps' che converte l'immagine in un file PostScript, che poi viene reimmesso nel filtro, in modo che questo file possa raggiungere la direttiva corretta per la sua utilizzazione finale. Si osservi l'uso della variabile di ambiente `FILE', per fornire al programma `tiff2ps' il nome del file temporaneo che viene generato in questo caso.

0	\177ELF		reject	Tentativo di stampare un binario ELF.

Sembra trattarsi di un binario ELF che ovviamente non può essere stampato.

default			cat

Questo è l'esempio più semplice di una direttiva finale che serve a definire cosa fare con i file di testo. In questo caso, i dati vengono lasciati tali e quali, mentre in un'altra situazione ci si potrebbe accertare di convertire il codice di interruzione di riga in modo che corrisponda alla sequenza <CR><LF>.

71.3.2 Funzionamento e utilizzazione pratica di Magicfilter

L'eseguibile `magicfilter' legge il file di configurazione che gli viene fornito come primo argomento nella riga di comando, e si comporta di conseguenza:

magicfilter <file-di-configurazione> [<opzioni>]

È necessario ricordare che `magicfilter' non viene avviato dall'utente, ma dal demone di stampa, per cui le opzioni sono quelle che passerà lo stesso demone, e `magicfilter' dovrà essere in grado di interpretarle. Dal momento che il demone di stampa non passa alcuna informazione sul file di configurazione, per fare in modo che questo sia indicato, si trasformano i file di configurazione in script, come è già stato mostrato, e si utilizzano tali script come se fossero i veri filtri di stampa. In effetti, in questo modo, si ottiene proprio di avviare `magicfilter' con il nome dello script come primo argomento, e le altre opzioni subito dopo, esattamente come si vede nello schema sintattico.

Magicfilter è stato realizzato allo scopo di essere utilizzato solo come filtro di ingresso (`if'), e a questo proposito, è in grado di interpretare solo le opzioni che vengono passate in questa situazione dal demone di stampa. A titolo informativo, la tabella 71.1 elenca le opzioni principali che l'eseguibile `magicfilter' è in grado di interpretare.

Opzione Descrizione
-c Lascia i dati inalterati.
-n<utente> Nominativo utente, disponibile attraverso la variabile `LPUSER'.
-h<host> Elaboratore di origine, disponibile attraverso la variabile `LPHOST'.
-i<rientro> Rientro, disponibile attraverso la variabile `LPINDENT'.

Tabella 71.1: Opzioni standard che vengono interpretate da Magicfilter, in quanto filtro di ingresso di un sistema di stampa.

Magicfilter si compone già di un buon numero di file di configurazione, ovvero di script, realizzati per altrettanti tipi di stampanti differenti. Di solito è sufficiente scegliere quello adatto, salvo la possibilità di provare tutti quelli simili in modo da poter scegliere il migliore in base al risultato preferito. Dal momento che, bene o male, si tratta di file di configurazione, questi script dovrebbero essere collocati nella directory `/etc/magicfilter/'. Quello che segue è l'esempio di un file `/etc/printcap' predisposto per gestire una stampate compatibile con il tipo HP Laserjet normale. Per la precisione, il file `/etc/magicfilter/laserjet-filter' è uno di questi script di configurazione.

lp|Stampante predefinita
        :lp=/dev/lp0:\
        :sd=/var/spool/lpd/lp:\
        :if=/etc/magicfilter/laserjet-filter:\
        :mx#0:\
        :sh:

In condizioni normali, una coda di stampa organizzata in questo modo va bene per qualunque file da stampare. Eventualmente, in caso di bisogno, si può modificare leggermente qualche direttiva del file di configurazione scelto, magari dopo averne fatta una copia.

71.4 Uniformità del sistema di stampa: da testo a PostScript

Un sistema di filtri di stampa ben organizzato deve passare per la generazione di un formato intermedio (prima di quello finale adatto alla stampante) per poter gestire l'impostazione della stampa in modo completamente trasparente. La figura 71.1 mostra questa idea.

+------------------+
| file da stampare |
+------------------+
         |
	 V
  +-------------+
  | conversione |
  +-------------+
         |
	 V
   +------------+     +-----------------------------+     +-----------+
   | PostScript |---->| conversione con Ghostscript |---->| stampante |
   +------------+     +-----------------------------+     +-----------+

Figura 71.1: Stampa attraverso un formato intermedio uniforme.

L'esistenza di Ghostscript, descritto meglio nel capitolo 72, giustifica la scelta del formato PostScript come standard per il formato intermedio di stampa. L'utilità di questo passaggio obbligato sta anche nel fatto che prima della conversione finale, il formato PostScript può essere rimaneggiato, per adattarlo a esigenze particolari, compresa la riduzione o l'ingrandimento. Tuttavia, in questa situazione, anche i file di testo vanno rielaborati in modo da generare prima un file PostScript. A questo scopo sono stati realizzati programmi come A2ps.

71.4.1 A2ps

A2ps è un programma per generare file PostScript a partire, prevalentemente, da file di testo. Gli obiettivi di chi sviluppa A2ps vanno oltre questo livello; tuttavia, questa è la sua funzionalità più importante.

A2ps è controllato da un file di configurazione generale, `/etc/a2ps.cfg', al quale può essere affiancato un file personale, `~/.a2ps/a2psrc', e anche uno locale, (nella directory corrente) `.a2psrc'. Pur senza approfondire la configurazione di A2ps, vale la pena di descrivere brevemente come si compongono questi file. Il simbolo `#' rappresenta l'inizio di un commento che termina alla fine della riga; le righe bianche e quelle vuote vengono ignorate; le altre righe sono direttive nella forma:

<tipo-dichiarazione>: <dichiarazione>

Il file di configurazione generale che di solito viene fornito assieme al programma (`/etc/a2ps.cfg') dovrebbe essere adatto alla maggior parte delle situazioni, e in generale non serve altro per utilizzare A2ps. In ogni caso, questo file è commentato molto bene, e la documentazione che fornisce A2ps è molto dettagliata (a2ps.info.

A2ps si utilizza in pratica attraverso l'eseguibile `a2ps', il cui scopo è quello di ricevere uno o più file in modo da poter generare una trasformazione adeguata in formato PostScript:

a2ps [<opzioni>] [<file>...]

I file possono essere indicati attraverso la riga di comando, e in mancanza di questa indicazione, viene usato lo standard input. Lo scopo di A2ps è quello di generare un file PostScript, e il modo in cui questo file viene restituito dipende dalla configurazione, oppure dalle opzioni della riga di comando. In generale, il risultato viene inviato alla stampa attraverso il comando `lpr', e questo lo si può vedere dalla direttiva

# First, the default printer (option -d, no argument)
DefaultPrinter: | lpr

che appare generalmente nel file di configurazione globale, con la quale si dichiara l'invio dello standard output verso tale comando di stampa. Di solito non c'è ragione di cambiare questo comportamento di A2ps, ma è importante sapere che non è sempre necessariamente così.

Il fatto che A2ps sia configurato in questo modo, lo rende simile a un comando di stampa alternativo a quello normale, per cui,

lpr pippo

viene sostituito direttamente dal comando

a2ps pippo

che in più si occupa di impaginare meglio il testo.

Ovviamente, tutto questo presuppone che la coda di stampa predefinita, ovvero quella che viene utilizzata quando si usa il comando `lpr' senza specificare altro, sia in grado di gestire file PostScript.

A2ps offre molte possibilità nel modo di impaginare il testo, e non si limita semplicemente a consentire la stampa ridotta di più pagine virtuali su una facciata singola. È molto importante anche la sua capacità di evidenziare il testo in funzione del suo contenuto, cosa che diventa molto utile per la lettura dei sorgenti di un programma. La tabella 71.2 riepiloga brevemente alcune opzioni più importanti che possono essere usate nella riga di comando dell'eseguibile `a2ps', opzioni che possono essere anche incluse nella configurazione attraverso direttive nella forma:

Options: <opzione-della-riga-di-comando>

Per esempio, per selezionare il formato di carta A4 si può utilizzare l'opzione `--medium=A4' nella riga di comando, oppure la direttiva

Options: --medium=A4

nel file di configurazione.

Opzione Alternativa Descrizione
-M <carta> --medium=<carta> Dimensione della carta.
-r --landscape Orientamento orizzontale.
-R --portrait Orientamento verticale.
-n n pagine virtuali per ogni pagina reale.
-j --borders={yes|no} Bordi attorno alle pagine virtuali.
-A --compact={yes|no} Unione di più file in un solo foglio.
-f n --font-size=n n punti per la dimensione dei caratteri.
-l n --chars-per-line=n n caratteri per riga.
-L n --lines-per-page=n n righe per pagina virtuale.
-m --catman Pagina di manuale; come `-L66'.
-T n --tabsize=n Dimensione degli stop di tabulazione.
-B --no-header Nessuna intestazione.
-a n --tabsize=n Dimensione degli stop di tabulazione.
-o <file> --output=<file> Crea un file e non invia alla stampa.
-P <coda> --printer=<coda> Coda di stampa a cui inviare il risultato.
-d Invia il risultato alla coda di stampa predefinita.
-E<tipo> --pretty-print=<tipo> Definizione dello stile di evidenziamento del testo.
-X <codifica> --encoding=<codifica> Definizione della codifica in cui è scritto il testo.

Tabella 71.2: Alcune opzioni di A2ps.

La tabella 71.3 riporta invece l'elenco di alcuni nomi di stili di evidenziamento della stampa, in funzione del contenuto del file di testo che si intende stampare. Questi nomi si usano con l'opzione `-E'.

Tipo Descrizione
sh Script di una shell Bourne.
html Sorgente HTML.
mail Messaggio di posta elettronica.
udiff File di differenze in formato unificato.
make File-make.
ada Sorgente in linguaggio ADA.
c Sorgente in linguaggio C.
cpp Sorgente in linguaggio C++.
gnuc Sorgente in linguaggio GNU C.
clisp Sorgente in linguaggio Common Lisp.
eiffel Sorgente in linguaggio Eiffel.
elisp Sorgente in linguaggio Emacs Lisp.
fortran Sorgente in linguaggio Fortran.
java Sorgente in linguaggio Java.
pascal Sorgente in linguaggio Pascal.
python Sorgente in linguaggio Python.
scheme Sorgente in linguaggio Scheme.
sql92 Sorgente in linguaggio SQL 92.

Tabella 71.3: Alcuni nomi che definiscono uno stile nel modo di evidenziare il testo.

La tabella 71.4 riporta l'elenco delle sigle che si possono utilizzare con l'opzione `-X' per definire la codifica con cui è scritto il testo da convertire.

Nome Descrizione
ASCII ASCII normale.
IBM-CP437 IBM CP437.
IBM-CP850 IBM CP850.
ISO-8859-1 ISO 8859-1 (Latin 1).
ISO-8859-2 ISO 8859-2 (Latin 2).
ISO-8859-10 ISO 8859-10.
ISO-8859-15 ISO 8859-15 (Latin 9).
ISO-8859-3 ISO 8859-3.
ISO-8859-4 ISO 8859-4.
ISO-8859-5 ISO 8859-5.
ISO-8859-7 ISO 8859-7.
ISO-8859-9 ISO 8859-9.
MS-CP1250 Microsoft CP1250.

Tabella 71.4: Alcuni nomi che identificano la codifica del testo.

Prima di passare all'elenco di esempi comuni, vale la pena di proporre il comando che potrebbe essere usato in un filtro di stampa per gestire i file di testo, senza lasciare che questi vengano inviati direttamente alla stampante:

a2ps -1 -M A4 -f 11 --borders=no -B -o -

In questo modo si specifica che: si vuole ottenere una pagina virtuale per foglio; il formato della carta è A4; il testo deve utilizzare un carattere da 11 punti (è la dimensione ottimale per stampare 80 colonne); non si vogliono bordi attorno alla pagina virtuale; non si vuole alcuna intestazione; il risultato in PostScript deve essere emesso attraverso lo standard output.

Volendo intervenire nella configurazione di Magicfilter, si potrebbe sostituire la solita direttiva

default			cat

con:

default   pipe   /usr/bin/a2ps -1 -M A4 -f 11 --borders=no -B -o - 2> /dev/null
Esempi

Gli esempi che vengono mostrati fanno riferimento alla configurazione tipica di A2ps.

a2ps pippo

Mette in stampa il file `pippo', dopo averlo convertito in PostScript. In condizioni normali, si ottiene la stampa di due pagine virtuali per foglio reale, con un orientamento orizzontale.

a2ps -2 pippo

Probabilmente, si tratta della stessa cosa dell'esempio precedente, con l'indicazione esplicita della richiesta di stampare due pagine virtuali per foglio.

a2ps -2 -P laser pippo

Come nell'esempio precedente, indicando espressamente la scelta della coda di stampa denominata `laser'.

a2ps -2 -o pippo.ps pippo

Come nell'esempio precedente, ma senza stampare: viene generato il file `pippo.ps'.

a2ps -2 -R pippo

Invia alla stampa il solito file, dopo averlo convertito in PostScript, in modo tale da ottenere due pagine virtuali, ma con un orientamento verticale. In questo modo, il testo è più piccolo, e ogni pagina virtuale contiene un numero molto elevato di righe.

man 1 a2ps | a2ps -2 -m

Stampa la pagina di manuale a2ps(1), impaginandola nel modo migliore per questo tipo di informazioni.

a2ps -2 -Esh /etc/profile

Stampa il file `/etc/profile', utilizzando un sistema di evidenziamento ottimale per gli script di shell Bourne o derivate.

71.4.2 Mpage

Mpage è un programma per generare file PostScript a partire da file di testo o da altri file PostScript. In generale, Mpage è utile per la prima di queste funzionalità, dal momento che la raccolta PSUtils è molto più adatta per la rielaborazione di file PostScript.

Sotto questo punto di vista, Mpage svolge un compito simile a quello di A2ps, in generale anche meno preciso; tuttavia Mpage offre una semplicità che alle volte manca all'altro. Per cominciare, Mpage non prevede alcuna configurazione, e tutte le indicazioni gli devono essere fornite attraverso la riga di comando; è previsto che il testo in ingresso utilizzi la codifica ISO 8859-1; inoltre, il risultato dell'elaborazione di Mpage è diretto verso lo standard output, e non alla coda di stampa predefinita.

mpage [<opzioni>] [<file>...]

L'eseguibile `mpage' è tutto ciò che compone questo programma, e come si vede, i file da elaborare possono essere indicati sulla riga di comando, altrimenti viene utilizzato lo standard input. La tabella 71.5 elenca alcune delle opzioni disponibili.

Opzione Descrizione
-1 Genera una pagina virtuale per foglio.
-2 Genera due pagine virtuali per foglio.
-4 Genera quattro pagine virtuali per foglio.
-8 Genera otto pagine virtuali per foglio.
-b<carta> Definisce il formato della carta.
-c Abilita il concatenamento di più file sullo stesso foglio.
-l Orientamento orizzontale.
-Ln Richiede n righe per pagina virtuale.
-mn[l][r][t][b] Richiede n punti di margine nel foglio.
-Mn[l][r][t][b] Richiede n punti di margine nella pagina virtuale.
-o Toglie i bordi attorno alle pagine virtuali.
-P<coda> Invia il risultato alla coda di stampa indicata.
-sn Specifica la lunghezza di uno stop di tabulazione.
-Wn Richiede n caratteri per riga.

Tabella 71.5: Alcune opzioni di Mpage.

Nella tabella, la sintassi delle opzioni `-m' e `-M' è stata indicata in modo approssimativo. Si riferiscono a dei margini per il foglio, oppure per la pagina virtuale: le lettere «l», «r», «t», e «b», si riferiscono rispettivamente al margine sinistro, destro, superiore e inferiore. Se si indica un gruppo di lettere, si intende che il margine indicato si deve riferire alle posizioni corrispondenti; se non si indicano lettere, il margine vale per tutti i lati del foglio. Per esempio, `-m20' indica un margine di 20 punti per tutti i lati, mentre `-m20lr' assieme a `-m10tb' richiede un margine di 20 punti per i margini sinistro e destro, mentre richiede solo 10 punti per i margini superiore e inferiore.

Prima di passare all'elenco di esempi comuni, vale la pena di proporre il comando che potrebbe essere usato in un filtro di stampa per gestire i file di testo, senza lasciare che questi vengano inviati direttamente alla stampante:

mpage -1 -bA4 -m72 -L 66 -W 80 -o 2> /dev/null

In questo modo si specifica che: si vuole ottenere una pagina virtuale per foglio; il formato della carta è A4; devono essere lasciati 72 punti per i margini del foglio (sono tutti uguali); il testo deve essere organizzato in modo tale che si possano stampare 80 colonne per 66 righe (il formato tradizionale per i file di testo, e anche per la composizione delle pagine di manuale); non si vogliono bordi attorno alla pagina virtuale. *3*

Volendo intervenire nella configurazione di Magicfilter, si potrebbe sostituire la solita direttiva

default			cat

con:

default	  pipe  /usr/bin/mpage -1 -bA4 -m72 -L 66 -W 80 -o 2> /dev/null
Esempi

mpage -bA4 -2 pippo | lpr

Invia alla stampa il file `pippo' dopo averlo trasformato in PostScript in modo tale che il testo si legga in due pagine virtuali contenute nel foglio fisico finale (il formato finale della carta è stato specificato esplicitamente in A4).

mpage -bA4 -2 pippo > pippo.ps

Come nell'esempio precedente, ma invece di inviare il file alla stampa, viene generato il file `pippo.ps'.

mpage -bA4 -2 -o pippo > pippo.ps

Come nell'esempio precedente, togliendo i bordi attorno alle pagine virtuali.

man 1 mpage | mpage -bA4 -2 -o -W80 -L66 | lpr

Invia alla stampa il risultato della ricomposizione della pagina di manuale mpage(1), dopo averla organizzata in due pagine virtuali per foglio, avendo stabilito la dimensione del testo nelle pagine virtuali di 80 colonne per 66 righe.

71.5 Controllo dell'impostazioni della carta

Nel momento in cui la stampa è gestita attraverso un sistema di filtri, come è stato mostrato in questo capitolo, i programmi non hanno la possibilità di definire il formato della carta. Infatti, non hanno alcun modo di colloquiare con il sistema di stampa sottostante; al massimo possono scegliere la coda di stampa.

In questo senso, se si dispone di una stampante con la quale possono essere utilizzati diversi formati di carta, occorrerà definire altrettante code di stampa differenti: ognuna predisposta per un formato diverso. In questo modo, il programma che ha bisogno di un certo formato, invierà la richiesta di stampa utilizzando la coda adatta per questo.

Nel capitolo 73 viene affrontato anche il problema dell'allineamento delle stampanti, dal momento che alle volte queste introducono dei margini che sfasano la stampa, cosa che crea problemi specialmente nel momento della rilegatura di un testo.

---------------------------

Appunti Linux 2000.04.12 --- Copyright © 1997-2000 Daniele Giacomini --  daniele @ pluto.linux.it


1.) Se si fanno modifiche al file `/etc/printcap' bisogna ricordare di inviare un segnale di aggancio al demone `lpd' per fare in modo che venga riletto questo file: `kill -s SIGHUP <pid-di-lpd>'.

2.) Una direttiva di questo file di configurazione può essere continuata sulla riga successiva, ponendo alla fine della riga da continuare il simbolo `\'.

3.) Rispetto allo stesso esempio mostrato con A2ps, il risultato con Mpage può essere considerato migliore, dal momento che si riesce a stabilire il numero di righe e di colonne da utilizzare, fissando anche i bordi (minimi) che si vogliono ottenere. Nel caso di A2ps era stato necessario stabilire la dimensione del carattere, per ottenere la larghezza corretta, ma non è stato possibile limitare il numero delle righe per foglio.


[inizio] [indice generale] [precedente] [successivo] [indice analitico] [contributi]