Feature der Woche: Seitenzahlen der Form »Seite x von y«
Um die Länge des Dokuments in Seiten anzugeben, ist ein zweiter Durchlauf des Publishers notwendig: Am Ende des ersten Durchlaufs wird die aktuelle (= letzte) Seitennummer gespeichert, die man anschließend in den folgenden Durchläufen nutzen kann.
Das folgende Beispiel erzeugt einige Seiten mit Ausgaben in der Form Seite 1 von ??
. Das dient als Basis für die Ergänzungen.
<Layout xmlns="urn:speedata.de:2009/publisher/en"
xmlns:sd="urn:speedata:2009/publisher/functions/en">
<Record element="data">
<!-- Wurzelelement -->
<SetVariable variable="maxseiten" select="'??'"/>
<Loop select="10" variable="i">
<PlaceObject>
<Textblock>
<Paragraph>
<Value select="concat('Seite ', sd:current-page(), ' von ', $maxseiten )"/>
</Paragraph>
</Textblock>
</PlaceObject>
<SetVariable variable="letzteseite" select="sd:current-page()"/>
<NewPage/>
</Loop>
</Record>
</Layout>
Am Ende der letzte Seite kann die Information mithilfe von SaveDataset
für den nächsten Lauf zwischengespeichert werden:
<SetVariable variable="attributSeitenzahl">
<Attribute name="anzahlseiten" select="$letzteseite"/>
</SetVariable>
<SaveDataset
filename="seitenzahl"
elementname="seiteninfo"
attributes="$attributSeitenzahl"/>
SaveDataset
erwartet eine XML-Struktur in »kodierter« Form. Attribute werden im Element Attribute
gespeichert, Elemente in Element
, wobei dieser Befehl wiederum Attribute
als Kindelemente haben kann. Diese Struktur wird als XML auf die Festplatte gespeichert.
Zu Beginn des Laufs kann nun die Datei eingelesen werden, falls sie existiert (d.h. im ersten Lauf wird kein Fehler erzeugt, weil die Datei noch nicht erzeugt wurde):
<Record element="data">
<SetVariable variable="maxseiten" select="'??'"/>
<LoadDataset name="seitenzahl"/>
...
und dazu
<Record element="seiteninfo">
<SetVariable variable="maxseiten" select="@anzahlseiten"/>
</Record>
Der Datensatz seiteninfo
wird dann aufgerufen, wenn die XML-Datei
seitenzahl
eingelesen wird. Es wird nichts anderes gemacht, als die kurz
vorher definierte Variable maxseiten
mit dem korrekten Inhalt zu
überschreiben.
Das vollständige Beispiel sieht nun so aus:
<Layout xmlns="urn:speedata.de:2009/publisher/en"
xmlns:sd="urn:speedata:2009/publisher/functions/en">
<Record element="seiteninfo">
<SetVariable variable="maxseiten" select="@anzahlseiten"/>
</Record>
<Record element="data">
<SetVariable variable="maxseiten" select="'??'"/>
<LoadDataset name="seitenzahl"/>
<Loop select="10" variable="i">
<PlaceObject>
<Textblock>
<Paragraph>
<Value
select="concat('Seite ', sd:current-page(), ' von ', $maxseiten )"/>
</Paragraph>
</Textblock>
</PlaceObject>
<SetVariable variable="letzteseite" select="sd:current-page()"/>
<NewPage/>
</Loop>
<!-- Nun steht die Anzahl der Seiten zur Verfügung -->
<SetVariable variable="attributSeitenzahl">
<Attribute name="anzahlseiten" select="$letzteseite"/>
</SetVariable>
<SaveDataset
filename="seitenzahl"
elementname="seiteninfo"
attributes="$attributSeitenzahl"/>
</Record>
</Layout>
Den weiteren Durchlauf kann man übrigens auf der Kommandozeile mit angeben (sp --runs 2
) oder in der Konfigurationsdatei publisher.cfg
setzen. Dort einfach die Zeile runs=2
eintragen.