von Patrick Gundlach |

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.

In der Serie »Feature der Woche« beschreibe ich jeden Montag mehr oder weniger nützliche Eigenschaften des Publishers. Kommentare gerne an mich per E-Mail oder einfach im Kommentarfeld.