Seitenlayout
Im vorherigen Thema haben Sie ja bereits das Wurzelelement root
von XSL-FO kennengelernt. In diesem Thema wollen
wir uns nun mit den untergeordneten Elementen und dem Seitenlayout beschäftigen. Dem root
-Element muss exakt ein
layout-master-set
-Element und ein oder mehrere page-sequence
-Element(e) untergeordnet werden.
Dem layout-master-set
werden ein oder mehrere Elemente des Typs simple-page-master
und / oder
page-sequence-master
untergeordnet. Das simple-page-master
-Element wird dazu verwendet, das
Format und die Bereiche einer Seite zu definieren. Mehr dazu im Abschnitt Seitenaufbau. Das
page-sequence-master
-Element wird zur Definition von Seitenfolgen (also von sich wiederholenden Seiten)
verwendet. Darauf werden wir jedoch im 2. Abschnitt noch genauer
eingehen.
Das Element page-sequence
wird dazu genutzt, die „eigentlichen“ Seiten bzw. Seitensequenzen an Hand der
vorliegenden Vorlagen im Ausgabedokument zu platzieren und mit Inhalt zu füllen. Um einer Seitensequenz eine
Vorlage zuzuweisen, wird das Attribut master-reference
im page-sequence
-Element verwendet. Die
wichtigsten Unterelemente von page-sequence
sind static-content
und flow
.
<fo:page-sequence master-reference="DIN-A4"> </fo:page-sequence>
Das static-content
-Element beinhaltet den statischen Inhalt einer Region, d. h. der Inhalt ist fest auf
die jeweilige Region begrenzt, wird nicht umgebrochen und wird, sofern sich der fließende Inhalt über mehrere Seiten erstreckt,
auf diesen Seiten wiederholt. Ein typisches Beispiel für die Anwendung von static-content
-Elementen wäre daher die
Kopf- und Fußzeile. Im flow
-Element hingegen wird der fließende Inhalt einer Region notiert, d. h. ist der
Inhalt (z. B. der Text) zu groß, so wird dieser umgebrochen und auf der nächsten Seite fortgeführt. Jedes page-sequence
-Element
enthält beliebig viele static-content
-Elemente sowie exakt ein flow
-Element. Dabei ist auch die
genannte Reihenfolge einzuhalten. Um das static-content
- und flow
-Element einer definierten Region
zuzuordnen, wird das Attribut flow-name
verwendet.
<fo:page-sequence master-reference="DIN-A4"> <fo:static-content flow-name="kopf"> Titel für die Kopfzeile </fo:static-content> <fo:static-content flow-name="inhalt"> Fließinhalt der Seitensequenz ... </fo:static-content> </fo:page-sequence>
Seitenaufbau
Bevor wir Seiten mit Inhalten befüllen können, müssen wir als erstes den Aufbau definieren. Um einen Seitenaufbau festzulegen,
verwenden wir das Element simple-page-master
. Der Name einer solchen Seitenvorlage wird über das Attribut
master-name
festgelegt. Um die Größe einer Seite festzulegen, verwenden wir die Attribute page-height
(Seitenhöhe) und page-width
(Seitenbreite). Möchten Sie noch zusätzlich einen Druckrand festlegen, so
können Sie die Attribute margin-left
(Druckrand links), margin-right
(Druckrand rechts),
margin-top
(Druckrand oben) und margin-bottom
(Druckrand unten) verwenden.
<fo:simple-page-master master-name="DIN-A4" page-height="297mm" page-width="210mm" margin-left="25mm" margin-right="25mm" margin-top="25mm" margin-bottom="20mm"> </fo:simple-page-master>
In XSL-FO gibt es bereits 5 fest definierte (Druck-)Bereiche (auch Regionen genannt), die wir nutzen können, um eine
Seite zu unterteilen: region-body
, region-start
, region-end
, region-before
und region-after
. region-body
repräsentiert den „Hauptbereich“, welcher i. d. R. für den Fließinhalt
verwendet wird. Die Bedeutung der anderen Elemente unterscheidet sich je nach verwendeter Schreibrichtung. Wenn wir jedoch von
der europäischen Schreibrichtung, also von links nach rechts und anschließend von oben nach unten, ausgehen, dann befindet sich
region-start
links, region-end
rechts, region-before
oben und region-after
unten. Ein typisches Beispiel für region-before
wäre also die Kopfzeile. Die Angaben für die Druckbereiche
(abgesehen von region-body
) sind optional und können, sofern diese nicht benötigt werden, weggelassen werden.
Wollen wir den Regionen später einen Inhalt zuweisen, so können wir den Regionen mit dem Attribut region-name
einen
eindeutigen Namen geben, andernfalls wird automatisch der Name des Elements mit dem Präfix xsl-
verwendet (z. B.
bei region-body
xsl-region-body
). Alle region-x
-Elemente sind inhaltsleer und können
über Attribute genauer spezifiziert werden (z. B. background-color
für die Hintergrundfarbe). Eines der wichtigsten
Attribute ist extent
, mit welchem die Breite bzw. Höhe einer Region festgelegt wird. Dieses Attribut wird bei
region-body
nicht verwendet, da region-body
automatisch die komplette Seite (abzüglich der Druckränder)
füllt. Da i. d. R. der Hauptbereich nicht mit anderen Regionen überlappen sollte, müssen Sie im region-body
-Element
einen Abstand angeben. Hierfür dienen die Attribute margin-left
(Abstand links), margin-right
(Abstand
rechts), margin-top
(Abstand oben) und margin-bottom
(Abstand unten).
<fo:simple-page-master master-name="DIN-A4" page-height="297mm" page-width="210mm"> <fo:region-body region-name="inhalt" margin-left="25mm" margin-right="25mm" margin-top="25mm" margin-bottom="20mm" /> <fo:region-before region-name="kopf" extent="25mm"/> </fo:simple-page-master>
Nun wollen wir uns aber auch mal ein vollständiges Beispiel anschauen. Im folgenden XSL-FO-Code sind unter der Seitenvorlage
DIN-A4
alle Regionen von XSL-FO definiert und mit unterschiedlichen Hintergrundfarben gekennzeichnet. Als Seitengröße
wird, wie der Name schon sagt, DIN-A4 verwendet. Druckränder sind in diesem Beispiel nicht definiert. Im Kopfbereich, Fußbereich
und Hauptbereich (oftmals auch als Inhaltsbereich bezeichnet) werden Texte aus der XML-Datei per XSLT platziert.
XML-Code:
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?> <?xml-stylesheet href="seitenaufbau.xsl" type="text/xsl" ?> <seite> <titel>Homepage-Webhilfe XSL-FO-Kurs</titel> <copy>Copyright by Homepage-Webhilfe</copy> <inhalt>Hier steht der Inhalt ...</inhalt> </seite>
XSL-Code:
<?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:output method="xml" omit-xml-declaration="no" version="1.0" encoding="UTF-8" indent="yes" /> <xsl:template match="/"> <fo:root> <fo:layout-master-set> <fo:simple-page-master master-name="DIN-A4" page-height="297mm" page-width="210mm"> <fo:region-body region-name="inhalt" margin="30mm" /> <fo:region-before region-name="kopf" extent="25mm" background-color="red" /> <fo:region-after region-name="fuss" extent="20mm" background-color="yellow" /> <fo:region-start extent="25mm" background-color="blue" /> <fo:region-end extent="25mm" background-color="lime" /> </fo:simple-page-master> </fo:layout-master-set> <fo:page-sequence master-reference="DIN-A4"> <fo:static-content flow-name="kopf"> <fo:block> <xsl:value-of select="/seite/titel" /> </fo:block> </fo:static-content> <fo:static-content flow-name="fuss"> <fo:block> <xsl:value-of select="/seite/copy" /> </fo:block> </fo:static-content> <fo:flow flow-name="inhalt"> <fo:block> <xsl:value-of select="/seite/inhalt" /> </fo:block> </fo:flow> </fo:page-sequence> </fo:root> </xsl:template> </xsl:stylesheet>
Seitenfolgen
Eine Seitenfolge wird durch das Element page-sequence-master
definiert. Mit dem Attribut master-name
wird
der Name der Folge festgelegt. Dieser Name kann nachher ebenfalls wieder im Attribut master-reference
eines
page-sequence
-Elements verwendet werden. Die Erstellung von Seitenfolgen ist komplex und würde in voller Ausführung
dieses Tutorial sprengen. Daher beschäftigen wir uns hier nur mit der gängigsten und zugleich vielfältigsten Variante.
Innerhalb des page-sequence-master
-Elements werden repeatable-page-master-alternatives
-Elemente untergeordnet
(i. d. R. jedoch nur eines). Als Attribut ist maximum-repeat
verfügbar, um die maximale Anzahl der Seitenwiederholungen
festzulegen.
<fo:page-sequence-master master-name="DIN-A4-Buch"> <fo:repeatable-page-master-alternatives> </fo:repeatable-page-master-alternatives> </fo:page-sequence-master>
Innerhalb des repeatable-page-master-alternatives
-Elements werden die einteiligen conditional-page-master-reference
-Elemente
untergeordnet. Mit dem Attribut master-reference
wird die Referenz zu einer der definierten Seiten festgelegt.
Über die Attribute page-position
, odd-or-even
und blank-or-not-blank
können Bedingungen
definiert werden. Wird beim Erstellungsvorgang des Dokuments eine neue Seite einer Seitenfolge „angefragt“, so müssen alle Bedingungen
zutreffen, sodass die mit dem Attribut master-reference
referenzierte Seite in das Ausgabedokument eingefügt wird. Mit dem
Attribut page-position
legen Sie fest, an welcher Position sich die Seite befinden muss. Mögliche Werte sind
first
(erste Seite), last
(letzte Seite), only
(erste oder letzte Seite), rest
(restliche Seiten) und any
(alle Seiten, Standardwert). Das Attribut odd-or-even
wird verwendet, um die
Bedingung für die Seitennummer festzulegen. Als Wert kann odd
(ungerade Seitennummer), even
(gerade Seitennummer) oder any
(alle Seiten, Standardwert) verwendet werden. Das letzte Attribut, um eine Bedingung
aufzustellen, ist blank-or-not-blank
. Wird der Wert blank
angegeben, so trifft die Bedingung nur dann zu,
wenn für die Seite kein Fließinhalt mehr zur Verfügung steht, d. h. ist kein Fließinhalt mehr vorhanden, so wird die Seite eingefügt
(sofern die anderen Bedingungen auch zutreffen). Dies ist dann sinnvoll, wenn Sie ihr Dokument auf eine gerade Seitenanzahl bringen
möchten. Weitere Werte für das blank-or-not-blank
-Attribut sind not-blank
(Bedingung trifft zu, wenn
Fließinhalt zur Verfügung steht) und any
(Bedingung trifft immer zu, Standardwert).
<fo:page-sequence-master master-name="DIN-A4-Buch"> <fo:repeatable-page-master-alternatives> <fo:conditional-page-master-reference master-reference="DIN-A4-Erste" page-position="first" /> <fo:conditional-page-master-reference master-reference="DIN-A4-Links" page-position="rest" odd-or-even="even" /> <fo:conditional-page-master-reference master-reference="DIN-A4-Rechts" page-position="rest" odd-or-even="odd" /> <fo:conditional-page-master-reference master-reference="DIN-A4-Rechts" page-position="rest" odd-or-even="odd" blank-or-not-blank="blank" /> <fo:conditional-page-master-reference master-reference="DIN-A4-Letzte" page-position="last" /> </fo:repeatable-page-master-alternatives> </fo:page-sequence-master>
Im folgenden Beispiel werden 3 unterschiedliche Seitenvorlagen definiert: DIN-A4-Deckblatt
, DIN-A4-Inhalt-Links
und DIN-A4-Inhalt-Rechts
. Zudem wird die Vorlage für die Seitenfolge DIN-A4-Inhalt
definiert. In der
Seitenfolge wird lediglich die Bedingung für die Seitennummer verwendet, um somit einen unterschiedlichen Abstand für linke und
rechte Seiten zu verwenden. Das zu diesem Beispiel gehörende XML-Dokument ist ebenfalls komplexer und enthält Themen mit Namen
und Absätzen und soll damit ein Buch darstellen. Mit Hilfe des XSL-Skripts wird aus dieser XML-Datei eine buchähnliche PDF-Datei
generiert.
XML-Code:
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?> <?xml-stylesheet href="seitenfolgen.xsl" type="text/xsl" ?> <buch> <titel>Homepage-Webhilfe XSL-FO-Kurs</titel> <copyright>Copyright by Homepage-Webhilfe</copyright> <thema> <name>Grundlagen</name> <absatz>...</absatz> <absatz>...</absatz> <absatz>...</absatz> </thema> <thema> <name>Seitenlayout</name> <absatz>...</absatz> <absatz>...</absatz> <absatz>...</absatz> <absatz>...</absatz> <absatz>...</absatz> </thema> <thema> <name>Textformatierung</name> <absatz>...</absatz> <absatz>...</absatz> </thema> <thema> <name>Abstände und Rahmen</name> <absatz>...</absatz> <absatz>...</absatz> <absatz>...</absatz> </thema> <thema> <name>Listen</name> <absatz>...</absatz> <absatz>...</absatz> </thema> </buch>
XSL-Code:
<?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:output method="xml" omit-xml-declaration="no" version="1.0" encoding="UTF-8" indent="yes" /> <xsl:template match="/"> <fo:root> <fo:layout-master-set> <fo:simple-page-master master-name="DIN-A4-Deckblatt" page-height="297mm" page-width="210mm"> <fo:region-body region-name="inhalt" margin="50mm" /> <fo:region-after region-name="fuss" extent="20mm" /> </fo:simple-page-master> <fo:simple-page-master master-name="DIN-A4-Inhalt-Links" page-height="297mm" page-width="210mm"> <fo:region-body region-name="inhalt" margin-left="25mm" margin-right="10mm" margin-top="15mm" margin-bottom="15mm" /> </fo:simple-page-master> <fo:simple-page-master master-name="DIN-A4-Inhalt-Rechts" page-height="297mm" page-width="210mm"> <fo:region-body region-name="inhalt" margin-left="10mm" margin-right="25mm" margin-top="15mm" margin-bottom="15mm" /> </fo:simple-page-master> <fo:page-sequence-master master-name="DIN-A4-Inhalt"> <fo:repeatable-page-master-alternatives> <fo:conditional-page-master-reference master-reference="DIN-A4-Inhalt-Links" odd-or-even="even" /> <fo:conditional-page-master-reference master-reference="DIN-A4-Inhalt-Rechts" odd-or-even="odd" /> </fo:repeatable-page-master-alternatives> </fo:page-sequence-master> </fo:layout-master-set> <fo:page-sequence master-reference="DIN-A4-Deckblatt"> <fo:static-content flow-name="fuss"> <fo:block> <xsl:value-of select="/buch/copyright" /> </fo:block> </fo:static-content> <fo:flow flow-name="inhalt"> <fo:block> <xsl:value-of select="/buch/titel" /> </fo:block> </fo:flow> </fo:page-sequence> <fo:page-sequence master-reference="DIN-A4-Inhalt"> <fo:flow flow-name="inhalt"> <xsl:apply-templates /> </fo:flow> </fo:page-sequence> </fo:root> </xsl:template> <xsl:template match="/buch/thema"> <!-- Titel --> <fo:block> <xsl:value-of select="name" /> </fo:block> <!-- Absätze anwenden --> <xsl:apply-templates /> <!-- Platzhalter --> <fo:block> <fo:leader /> </fo:block> </xsl:template> <xsl:template match="/buch/thema/absatz"> <fo:block> <xsl:value-of select="." /> </fo:block> </xsl:template> </xsl:stylesheet>
Übrigens: Das leader
-Element in diesem Beispiel wird lediglich dazu verwendet, eine leere Zeile zu erzeugen.
Seitenumbruch
Um den Seitenumbruch nach, vor oder in Elementen zu steuern, gibt es die Attribute page-break-after
,
page-break-before
und page-break-inside
. Mögliche Werte für page-break-after
oder
page-break-before
sind auto
(Umbruch je nach Bedarf, Standardwert), always
(Umbruch
erzwingen), left
(Umbruch erzwingen, sodass nächste Seite eine linke Seite ist), right
(Umbruch
erzwingen, sodass nächste Seite eine rechte Seite ist) und avoid
(Umbruch vermeiden). Für das Attribut
page-break-inside
, mit welchem der Umbruch innerhalb eines Elements gesteuert wird, sind nur die Werte
auto
und avoid
zulässig.
<fo:block> Dieser Block enthält einen Text ... </fo:block> <fo:block page-break-before="always"> Dieser Block beginnt immer auf einer neuen Seite. </fo:block>