MokaByte 98 - Lug/Ago 2005
 
MokaByte 98 - Lug/Ago 2005 Prima pagina Cerca Home Page

 

 

 

MokaCMS - Open Source per il Web Content Management
IV parte: da XML ad PDF utilizzando XSLT e FO (I puntata)

Portable Document Format (PDF) è un formato diffuso per lo scambio di documenti nel web che consente di avere lo stesso preciso layout su tutte le piattaforme. In questo articolo si vedrà come il processore XSL è in grado di creare un file in formato pdf, partendo da documenti scritti con gli oggetti di formattazione, ovvero con Formatting Objects.

Formatting Objects
XSLFO è un vocabolario xml usato per specificare un'impaginazione e stili di testo per creare un layout di pagina. XSLFO può essere usato in congiunzione con XSLT per convertire un documento XML in un layout di pagina pronto per la stampa o per la visualizzazione.
XSLFO definisce un set di elementi in XML che descrivono come la pagina è impostata. I contenuti della pagina sono riempiti da blocchi. Ci possono essere blocchi statici che appaiono sempre nella pagina (come intestazione e piè di pagina) e il blocco principale che è racchiuso nel corpo della pagina.
Con la formattazione di oggetti è possibile definire in modo dettagliato come questi saranno visualizzati.
È possibile scegliere quale tipo di carattere usare, se utilizzare un stile sottolineato piuttosto che un grassetto e cosi via. È possibile posizionare interi blocchi di testo o immagini ovunque all'interno del documento.
Gli oggetti di formattazione XSL hanno un loro namespace "http://www.w3.org/1999/XSL/Format", proprio come le altre applicazioni XML. Il prefisso utilizzato per indicare che è un elemento di formattazione è fo.
Partiamo da un semplice esempio.

 

Benvenuti a Fop!
Si vuole creare un blocco contente il testo "Benvenuti". Un blocco è un'area rettangolare nel documento in uscita, quello che poi sarà in questo caso un documento pdf.
Prima di poter creare il blocco, bisogna definire i margini della pagina, dire al processore se questa pagina possiede un'intestazione e/o un piè di pagina ecc. Per xsl-fo la pagina è composta da cinque aree che sono: region-start, region-body, region-end, region-before e region-after. La loro rappresentazione è illustrata in figura 1.


Figura 1 - Rappresentazione delle aree di una pagina.

Tutte le aree tranne la region-body sono opzionali: possono non esserci all'interno del documento.
Si supponga che la pagina debba avere il margine superiore pari a 2,5 cm, il margine inferiore, destro e sinistro pari a 2 cm; ciò significa che il corpo della pagina, cioè la region-body, è posizionata a 2,5 cm dal bordo del foglio superiore e 2 cm dagli altri bordi, come mostrato in figura 2.


Figura 2
- Margini della pagina

Per definire un set di pagine si utilizza l'elemento fo:layout-master-set. I margini di una pagina, invece, sono impostati tramite fo:simple-page-master, figlio diretto dell'elemento precedentemente citato.
All'interno di un fo:layout-master-set ci possono essere più di un fo:simple-page-master. Questo significa che si possono creare più tipologie di pagine all'interno dello stesso documento.

<fo:root>
<fo:layout-master-set>
<fo:simple-page-master master-name="mokaBytePage"
page-height="29.7cm" page-width="21cm"
margin-top="2.5cm" margin-bottom="2.0cm"
margin-left="2.0cm" margin-right="2.0cm">

</fo:simple-page-master>
</fo:layout-master-set>


</fo:root>

Nel fo:simple-page-master sono specificati gli attributi che definiscono i margini della pagina, i quali sono:

  • page-height e page-width, che definiscono rispettivamente l'altezza e la larghezza dei foglio.
  • margin-top e margin-bottom, che definiscono la distanza tra il bordo superiore del foglio e il corpo della pagina per il primo, e la distanza tra il bordo inferiore e il corpo della pagina per il secondo.
  • margin-left e margin-right che definiscono rispettivamente la distanza tra il bordo destro del foglio e il corpo della pagina e la distanza tra il bordo sinistro e il corpo della pagina.
  • master-name è il nome che identifica questo elemento fo:simple-page-master.

Per comprendere meglio si guardi la figura di seguito riportata.



Figura 3
- Margini della pagina (2).

Fino ad ora sono stati discussi i margini della pagina. Ora è necessario dichiarare quali aree devono esserci in questo tipo di pagina. Per semplicità ne dichiareremo solo una, la quale è region-body.
Se nella dichiarazione vi sono presenti una o più aree, è obbligatorio che queste vengano poi definite all'interno del documento. Questo perché il processore non è in grado di ignorare una dichiarazione di un'area nel momento in cui non la trova per elaborarla.

<fo:root>
<fo:layout-master-set>
<fo:simple-page-master master-name="mokaBytePage"
page-height="29.7cm" page-width="21cm"
margin-top="2.5cm" margin-bottom="2.0cm"
margin-left="2.0cm" margin-right="2.0cm">

<fo:region-body margin-top="2.5cm" margin-bottom="2.0cm" margin-left="2.0cm" margin-right="2.0cm"/>

</fo:simple-page-master>
</fo:layout-master-set>


</fo:root>

Nella dichiarazione della region-body sono presenti attributi gia visti nell'elemento fo:simple-page-master.
Questi elementi danno la possibilità di separare ulteriormente il corpo della pagina dalle altre aree oppure di far coincidere confini della region-body con i confini delle altre aree.
Si è ora pronti per scrivere il codice necessario alla costruzione del blocco che visualizzerà il testo "Benvenuti".
Per farlo dobbiamo definire l'area region-body dove all'interno verra inserito l'elemento fo:block

<fo:page-sequence master-reference="page" initial-page-number="auto">
<fo:flow flow-name='xsl-region-body'>
<fo:block>Benvenuti</fo:block>
</fo:flow>
</fo:page-sequence>

L'elemento fo:block è un'area rettangolare di dimensione variabile in altezza, mentre in larghezza occupa tutto lo spazio dedicato al corpo della pagina in questo caso. Se fosse stato contenuto in una cella di una tabella, occuperebbe lo spazio dedicato alla cella.
Non è stato specificato nessun stile per questo elemento, di conseguenza il processore utilizzerà un font di default. Nel caso in cui si voglia applicargli un font diverso da quello di default bisogna specificare gli attributi nel fo:block.

<fo:flow flow-name='xsl-region-body'>
<fo:block font-family="Arial" font-size="20pt" font-style="italic" font-weight="bold" text-align="center" color="red">Benvenuti</fo:block>
</fo:flow>

Nell'elemento fo:block si possono quindi definire i seguenti attributi:
· font-family definisce il tipo di font.
· font-size dichiara la grandezza del font da utilizzare.
· font-style definisce lo stile. In questo caso abbiamo utilizzato il corsivo.
· font-weight definisce la larghezza del font utilizzato. In questo caso è grassetto.
· color definisce il colore del font.
· text-align specifica l'allineamento del testo, in questo caso il testo è stato allineato al centro.

Il risultato è il seguente:


Figura 4
- Esempio documento pdf

Di seguito è riportato il codice completo per realizzare questo esempio.

<?xml version='1.0' encoding='UTF-8' ?>
<xsl:stylesheet version='1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform' xmlns:fo='http://www.w3.org/1999/XSL/Format'>

<xsl:template match='/'>
<fo:root xmlns:fo='http://www.w3.org/1999/XSL/Format'>

<fo:layout-master-set>
<fo:simple-page-master master-name="page" page-height="29.7cm" page-width="21cm"
margin-top="2.5cm" margin-bottom="2cm" margin-left="2cm" margin-right="2.0cm">

<fo:region-body margin-top="2.5cm" margin-bottom="2.0cm" margin-left="2.0cm" margin-right="2.0cm"/>
</fo:simple-page-master>
</fo:layout-master-set>

<fo:page-sequence master-reference="page" initial-page-number="auto">
<fo:flow flow-name='xsl-region-body'>

<fo:block font-family="Arial" font-size="20pt" font-style="italic"
font-weight="bold" text-align="center" color="red">Benvenuti</fo:block>

</fo:flow>
</fo:page-sequence>
</fo:root>
</xsl:template>
</xsl:stylesheet>

 

Formattiamo un articolo
Nel paragrafo precedente si è visto come scrivere un file xslfo per produrre un qualsiasi pdf in uscita. Ora si vedrà come scrivere un file xslfo per produrre un'articolo di mokabyte in formato pdf.
Il codice che si andrà a scrivere sarà organizzato a template. Questo significa che verrà creato un modello per ogni parte di codice che andrà a comporre l'articolo, e in futuro questi potranno essere riutilizzati per comporre altre tipologie di PDF per Mokabyte.
L'organizzazione a template è molto pratica a livello di sviluppo, in quanto permette un'individuazione dell'errore in minor tempo. Inoltre semplifica molto la lettura del codice.
Saranno creati i seguenti template:

  • pageLayoutTemplate. Qui verranno specificate le misure, i margini della pagina, e quali aree saranno presenti. In questo caso saranno presenti la region-before, la region-after, e la region-start.
  • headerTemplate. In questo template, verrà sviluppata l'area comunemente chiamata intestazione.
  • footerTemplate. Qui sarà costruito il pié di pagina dell'articolo.
  • bodyTemplate. Quest' area sarà destinata a contenere l'intero articolo.

Il primo template risiederà in un file chiamato mokaBytePageLayout.xsl . I successivi tre, risiederanno in un file denominato mokaByteRegionsTemplate.xsl . Inoltre sarà creato un file chiamato mokaByteStyles.xsl che conterrà tutti gli stili da applicare all'articolo. Questi verranno a loro volta inglobati nel file mokaByteArticle.xsl, il quale si preoccuperà di creare il vero e proprio articolo chiamando i vari templates. Si partirà scrivendo alcuni degli stili che dovranno essere applicati.
È importante per una buona riuscita del lavoro, stabilire a priori le caratteristiche che un documento deve avere; è necessario per poter mantenere una linea da seguire poi successivamente.

 

Lo stile
Per tutto il testo sarà utilizzato il font Helvetica di varie misure e di colore verde, tranne che per le parti di codice alle quali verrà applicato il font Courier New di 10pt di colore nero.
Il titolo sarà in grassetto e avrà grandezza pari a 24pt, mentre i titoli delle sezioni saranno anch'essi in grassetto ma di dimensione pari a 12pt.
L'introduzione avrà grandezza di 10pt ma sarà scritta in corsivo, e sia l'intestazione che il piè di pagina avranno anche loro grandezza 10pt e saranno in grassetto la prima e normale il secondo.
Per applicare un certo stile ad una parte di testo, si possono utilizzare i set di attributi, proprio come le classi di stile in CSS.
Per scrivere un set di attributi si utilizza l'elemento xsl:attribute-set , dove al suo interno troviamo l'elemento xsl:attribute che specifica l'attributo CSS da usare dichiarandone anche il valore. Si prendano come esempio i set di attributi sotto riportati.

<xsl:attribute-set name="title">
<xsl:attribute name="font-family">Arial</xsl:attribute>
<xsl:attribute name="font-size">24pt</xsl:attribute>
<xsl:attribute name="color">rgb(0,102,0)</xsl:attribute>
<xsl:attribute name="font-weight">bold</xsl:attribute>
<xsl:attribute name="text-align">left</xsl:attribute>
</xsl:attribute-set>

<xsl:attribute-set name="textCode">
<xsl:attribute name="font-family">CourierNew</xsl:attribute>
<xsl:attribute name="font-size">10pt</xsl:attribute>
<xsl:attribute name="color">rgb(0,0,0)</xsl:attribute>
<xsl:attribute name="text-align">left</xsl:attribute>
</xsl:attribute-set>


Misure e margini
Nel template che identifica e specifica i margini e le misure (pageLayoutTemplate), saranno dichiarati i seguenti valori:

  • fo:simple-page-master
    • master-name="mokaBytePage"
    • page-height="29.7cm"
    • page-width="21cm"
    • margin-top="1.0cm"
    • margin-bottom="1.0cm"
    • margin-left="0.5cm"
    • margin-right="2.0cm"
  • fo:region-body
    • margin-top="2.5cm"
    • margin-bottom="2.0cm"
    • margin-left="4.0cm"
    • margin-right="0.0cm"
  • fo:region-before
    • extent="1.25cm"
  • fo:region-after
    • extent="1.25cm"
  • fo:region-start
    • extent="3.60cm"

Quest'ultima area, è dichiarata, ma conterrà solo un blocco (fo:block) vuoto. Si potrebbe fare a meno di quest' area visto che non conterrà nulla, ma la sua presenza renderà il lavoro più facile in quanto occupa spazio all'interno della pagina e non verrà discussa in seguito.
Il codice completo relativo a questo template è riportato nelle pagine successive al termine dell'articolo.

 

Intestazione
L'intestazione dovrà riportare il testo "Mokabyte" seguito dal numero della rivista e dalla data (in formato mese anno) di pubblicazione. Lo stile da applicare è già stato esplicato prima, e sarà applicato usando il set di attributi identificato con il nome di "header" (al di sotto del testo dovrà apparire una linea puramente estetica di colore verde).
A questo scopo sono state necessarie delle modifiche all' xml in uso. È stato infatti necessario aggiungere gli elementi contenenti le informazioni come il numero della rivista e la data di pubblicazione ecc:

<rivista>
<numero>97</numero>
<mese>Giugno</mese>
<anno>2005</anno>
</rivista>

Per una miglior organizzazione dei dati è stato creato l'elemento rivista, che come si può notare contiene gli elementi numero, mese e anno. Ogni qualvolta che sarà necessario inserire nuove informazioni inerenti alla rivista e non al contenuto di essa, (per esempio in caso Mokabyte venisse stampata, il prezzo della rivista), dovrà essere creato un elemento apposito che contenga l'informazione, e quest' ultimo deve far parte dell'elemento rivista.

<xsl:template name='headerTemplate'>
<fo:block xsl:use-attribute-sets="header">
MokaByte <xsl:value-of select="rivista/numero"/> - <xsl:value-of select="rivista/mese"/>&#160;<xsl:value-of select="rivista/anno"/>
</fo:block>
<fo:block>
<fo:leader leader-pattern="rule" rule-thickness="0.01cm" leader-length="14.9cm" color="rgb(0,102,0)"/>
</fo:block>
</xsl:template>

Introduciamo ora un elemento di cui non si è ancora discusso fo:leader. Questo elemento è utilizzato per "disegnare" righe di diverse altezze e lunghezze, a anche di tipo diverso. Tramite l'attributo leader-pattern specifica il tipo di linea, infatti questo può assumere il valore "rule" che indica una linea continua, oppure può assumere il valore "dots" che indica linea composta da una serie di puntini oppure "space" che disegna una linea di spazi. In genere l'elemento fo:leader è usato per costruire i sommari e gli indici.
Il risultato è mostrato in figura 5.


Figura 5
- Intestazione

 

 

Conclusioni
In questa prima parte abbiamo visto come iniziare a sviluppare con fop ed abbiamo cominciato a sviluppare un foglio di stile per gli articoli di Mokabyte definendone la struttura e le caratteristiche generali. Nel prossimo numero termineremo il lavoro concludendo lo sviluppo dell'xsl di formattazione.