Page numbers: Page x of y

To specify the length of the document in pages, a second pass of the Publisher is necessary: At the end of the first pass, the current (= last) page number is stored, which can then be used in subsequent passes.

The following example creates some pages with output in the form Page 1 of ??. This serves as a basis for the additions.

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

  <Record element="data">
    <!-- ?? is a placeholder that gets overridden -->
    <SetVariable variable="maxpages" select="'??'"/>

    <Loop select="10" variable="i">
      <PlaceObject>
        <Textblock>
          <Paragraph>
            <Value
              select="concat('Page ', sd:current-page(), ' of ', $maxpages )"/>
          </Paragraph>
        </Textblock>
      </PlaceObject>
      <SetVariable variable="lastpage" select="sd:current-page()"/>
      <NewPage/>
    </Loop>
  </Record>
</Layout>

At the end of the last page the information can be cached for the next run using <SaveDataset>:

<SetVariable variable="attrPagenumber">
  <Attribute name="numberofpages" select="$lastpage"/>
</SetVariable>
<SaveDataset
  name="pagecount"
  elementname="pageinfo"
  attributes="$attrPagenumber"/>

<SaveDataset> expects an XML structure at attributes can be stored in the element `<Attributes>' and, elements in `<Element>', whereby this command can in turn have `<Attributes>' as child elements. This structure is saved to disk as XML and has the following form in this example:

<pageinfo numberofpages="10" />

At the beginning of the run, the file can now be read in if it exists (i.e. no error is generated in the first run because the file has not yet been created):

<Record element="data">
  <SetVariable variable="maxpages" select="'??'"/>
  <LoadDataset name="pagecount"/>
  ...

and in addition

<Record element="pageinfo">
  <SetVariable variable="maxpages" select="@numberofpages"/>
</Record>

The record 'pageinfo' is called when the XML file 'pagecount' is read. Nothing else is done than overwriting the recently defined variable maxpages with the correct content.

The complete example now looks like this:

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

  <!-- only evaluated if the file `pagecount` is found (second run) -->
  <Record element="pageinfo">
    <SetVariable variable="maxpages" select="@numberofpages"/>
  </Record>

  <!-- start of data processing -->
  <Record element="data">
    <SetVariable variable="maxpages" select="'??'"/>
    <LoadDataset name="pagecount"/>
    <Loop select="10" variable="i">
      <PlaceObject>
        <Textblock>
          <Paragraph>
            <Value
              select="concat('Page ', sd:current-page(), ' of ', $maxpages )"/>
          </Paragraph>
        </Textblock>
      </PlaceObject>
      <SetVariable variable="lastpage" select="sd:current-page()"/>
      <NewPage/>
    </Loop>
    <!--  Now we know the total number of pages  -->
    <SetVariable variable="attrPagenumber">
      <Attribute name="numberofpages" select="$lastpage"/>
    </SetVariable>
    <SaveDataset
      name="pagecount"
      elementname="pageinfo"
      attributes="$attrPagenumber"/>
  </Record>
</Layout>