von Patrick Gundlach |

Feature der Woche: Seitenzahlen 2 (Marker)

Letzte Woche wurden Seitenzahlen in der Form »Seite x von y« dargestellt. Die aktuelle Seitenzahl wurde mit sd:current-page() ermittelt. Das funktioniert aber nur dann, wenn bekannt ist, wo man gerade ist. In einer Tabelle beispielsweise ist das Ergebnis das der Startseite. Folgendes Layout gibt 100 Mal die Zahl 1 aus:

<Layout
    xmlns="urn:speedata.de:2009/publisher/en"
    xmlns:sd="urn:speedata:2009/publisher/functions/en">

    <Record element="data">
        <PlaceObject>
            <Table>
                <Loop select="100">
                    <Tr>
                        <Td>
                            <Paragraph>
                                <Value select="sd:current-page()"></Value>
                            </Paragraph>
                        </Td>
                    </Tr>
                </Loop>
            </Table>
        </PlaceObject>
    </Record>
</Layout>

Obwohl eigentlich auf der ersten Seite die 1 gewünscht wäre, auf der zweite Seite die 2.

Nun kann man sogenannte Marker setzen, die erst dann ausgewertet werden, wenn die Seite in das PDF ausgegeben wird. Dadurch ist gesichert, dass die Seitenzahlen dem Ort entsprechen, wo das Objekt ausgegeben wird.

<Action>
  <Mark select="'Name des Markers'"/>
</Action>

Der Marker wird innerhalb eines Textblocks oder Absatzes ausgegeben. Die Seitenzahl zu diesem Marker wird mit der Funktion sd:pagenumber('Name des Markers') ermittelt. Das geht naturgemäß erst auf den Folgeseiten. Möchte man auf einen Marker auf einer Seite weiter hinten im PDF (oder auf der aktuellen Seite) verweisen, dann muss man die Marker zwischenspeichern. Das passiert automatisch, wichtig ist, dass die Marker nicht beim Start des Publishers gelöscht werden. Dafür ist die Option resetmarks="no" da:

<Options resetmarks="no"/>

Damit können wir das Tabellenbeispiel wie folgt schreiben:

<Layout
    xmlns="urn:speedata.de:2009/publisher/en"
    xmlns:sd="urn:speedata:2009/publisher/functions/en">
    <Options resetmarks="no"/>

    <Record element="data">
        <PlaceObject>
            <Table>
                <Loop select="100" variable="i">
                    <Tr>
                        <Td>
                            <Paragraph>
                                <Action>
                                    <Mark select="concat('row',$i)"/>
                                </Action>
                                <Value select="concat(
                                      'Tabellenzeile ',
                                      $i,
                                      ' ist auf Seite ',
                                      sd:pagenumber(concat('row',$i)))"/>
                            </Paragraph>
                        </Td>
                    </Tr>
                </Loop>
            </Table>
        </PlaceObject>
    </Record>
</Layout>

Das Prinzip ist ganz einfach: die Schleife wird 100 Mal durchlaufen, die aktuelle Position wird in $i gespeichert. Für jede Zeile erzeugen wir einen Marker der Form 'row' + $i, also row1, row2, und so weiter. Gleichzeitig wird dieser Marker ausgelesen (sd:pagenumber(concat('row',$i))). Der Inhalt steht erst im zweiten Durchlauf zur Verfügung.

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.