Handbuch durchsuchen:

- Startseite
- Einleitung
- Hallo Welt!
- Grundlagen
  - Erstellen eines Layoutregelwerks
  - Aufbau der Datendatei und des Layoutregelwerks
  - Objekte ausgeben
  - Raster
  - Bereiche auf der Seite (PositioningArea)
  - Dateiorganisation
  - Silbentrennung / Spracheinstellungen
  - Einbinden von Schriftarten
  - Textformate
  - Textformatierung
  - Farben
- Programmierung
- Bilder einbinden
- Tabellen
- Fortgeschrittene Themen
  - Lesezeichen (Bookmarks)
  - Erzeugen von XML-Strukturen
  - Druckausgabe / Schnittmarken
  - CSS
  - Gruppen (virtuelle Objekte)
  - Virtuelle Seiten
  - Rotieren von Inhalten
  - Sortieren von Daten
  - Umfließen von Bildern
  - Seitentypen
  - Starten des Publishers über den Hotfolder
  - Lua-Filter / Datenvorverarbeitung
  - Schemavalidierung
  - Qualitätssicherung (PDF-Vergleich)
  - Fehlersuche / Debugging
  - Servermodus
  - Steuerung des Layouts beim Aufruf des Publishers
  - Bilder mit MetaPost erstellen und einbinden
- Kochbuch
  - Daumenregister
  - Mehrseitige PDF-Dateien einbinden
  - Layoutoptimierung mithilfe von Gruppen
  - Aufzählungslisten nachahmen
  - Verzeichnisse erstellen
  - Inhaltsverzeichnis in einem Durchlauf erstellen
  - Seitenzahlen: Seite x von y
- Installationsanleitung
- Dateinamen im Publisher
- Voreinstellungen im speedata Publisher
- Starten des Publishers über die Kommandozeile
- Konfiguration des Publishers
- Längenangaben und Maßeinheiten
- XPath- und Layoutfunktionen
- Interne Variablen
- XML Editor mit Schema verbinden
  - Visual Studio Code
  - OxygenXML
- Liste der Änderungen
- Glossar
- Kompatibilität mit anderer Software
- Befehlsreferenz
  - A
  - Action
  - AddSearchpath
  - AtPageCreation
  - AtPageShipout
  - AttachFile
  - Attribute
  - B
  - Barcode
  - Bold
  - BoldItalic
  - Bookmark
  - Box
  - Br
  - Case
  - Circle
  - ClearPage
  - Color
  - Column
  - Columns
  - Compatibility
  - Contents
  - Copy-of
  - DefineColor
  - DefineColorprofile
  - DefineFontalias
  - DefineFontfamily
  - DefineGraphic
  - DefineMatter
  - DefineTextformat
  - Element
  - Fallback
  - Fontface
  - ForAll
  - Frame
  - Grid
  - Group
  - Groupcontents
  - HSpace
  - Hyphenation
  - I
  - Image
  - Include
  - Initial
  - InsertPages
  - Italic
  - Layout
  - Li
  - LoadDataset
  - LoadFontfile
  - Loop
  - Makeindex
  - Margin
  - Mark
  - Message
  - NewPage
  - NextFrame
  - NextRow
  - NoBreak
  - Ol
  - Options
  - Otherwise
  - Output
  - Overlay
  - Pageformat
  - Pagetype
  - Paragraph
  - PDFOptions
  - PlaceObject
  - Position
  - PositioningArea
  - PositioningFrame
  - ProcessNode
  - Record
  - Regular
  - Rule
  - SaveDataset
  - SavePages
  - SetGrid
  - SetVariable
  - SortSequence
  - Stylesheet
  - Span
  - Sub
  - Sup
  - Switch
  - Table
  - TableNewPage
  - Tablefoot
  - Tablehead
  - Tablerule
  - Td
  - Text
  - Textblock
  - Tr
  - Trace
  - Transformation
  - U
  - Ul
  - Until
  - URL
  - Value
  - VSpace
  - While

Version 4.10.0
Handbuch durchsuchen

- Startseite
- Einleitung
- Hallo Welt!
- Grundlagen
  - Erstellen eines Layoutregelwerks
  - Aufbau der Datendatei und des Layoutregelwerks
  - Objekte ausgeben
  - Raster
  - Bereiche auf der Seite (PositioningArea)
  - Dateiorganisation
  - Silbentrennung / Spracheinstellungen
  - Einbinden von Schriftarten
  - Textformate
  - Textformatierung
  - Farben
- Programmierung
- Bilder einbinden
- Tabellen
- Fortgeschrittene Themen
  - Lesezeichen (Bookmarks)
  - Erzeugen von XML-Strukturen
  - Druckausgabe / Schnittmarken
  - CSS
  - Gruppen (virtuelle Objekte)
  - Virtuelle Seiten
  - Rotieren von Inhalten
  - Sortieren von Daten
  - Umfließen von Bildern
  - Seitentypen
  - Starten des Publishers über den Hotfolder
  - Lua-Filter / Datenvorverarbeitung
  - Schemavalidierung
  - Qualitätssicherung (PDF-Vergleich)
  - Fehlersuche / Debugging
  - Servermodus
  - Steuerung des Layouts beim Aufruf des Publishers
  - Bilder mit MetaPost erstellen und einbinden
- Kochbuch
  - Daumenregister
  - Mehrseitige PDF-Dateien einbinden
  - Layoutoptimierung mithilfe von Gruppen
  - Aufzählungslisten nachahmen
  - Verzeichnisse erstellen
  - Inhaltsverzeichnis in einem Durchlauf erstellen
  - Seitenzahlen: Seite x von y
- Installationsanleitung
- Dateinamen im Publisher
- Voreinstellungen im speedata Publisher
- Starten des Publishers über die Kommandozeile
- Konfiguration des Publishers
- Längenangaben und Maßeinheiten
- XPath- und Layoutfunktionen
- Interne Variablen
- XML Editor mit Schema verbinden
  - Visual Studio Code
  - OxygenXML
- Liste der Änderungen
- Glossar
- Kompatibilität mit anderer Software
- Befehlsreferenz
  - A
  - Action
  - AddSearchpath
  - AtPageCreation
  - AtPageShipout
  - AttachFile
  - Attribute
  - B
  - Barcode
  - Bold
  - BoldItalic
  - Bookmark
  - Box
  - Br
  - Case
  - Circle
  - ClearPage
  - Color
  - Column
  - Columns
  - Compatibility
  - Contents
  - Copy-of
  - DefineColor
  - DefineColorprofile
  - DefineFontalias
  - DefineFontfamily
  - DefineGraphic
  - DefineMatter
  - DefineTextformat
  - Element
  - Fallback
  - Fontface
  - ForAll
  - Frame
  - Grid
  - Group
  - Groupcontents
  - HSpace
  - Hyphenation
  - I
  - Image
  - Include
  - Initial
  - InsertPages
  - Italic
  - Layout
  - Li
  - LoadDataset
  - LoadFontfile
  - Loop
  - Makeindex
  - Margin
  - Mark
  - Message
  - NewPage
  - NextFrame
  - NextRow
  - NoBreak
  - Ol
  - Options
  - Otherwise
  - Output
  - Overlay
  - Pageformat
  - Pagetype
  - Paragraph
  - PDFOptions
  - PlaceObject
  - Position
  - PositioningArea
  - PositioningFrame
  - ProcessNode
  - Record
  - Regular
  - Rule
  - SaveDataset
  - SavePages
  - SetGrid
  - SetVariable
  - SortSequence
  - Stylesheet
  - Span
  - Sub
  - Sup
  - Switch
  - Table
  - TableNewPage
  - Tablefoot
  - Tablehead
  - Tablerule
  - Td
  - Text
  - Textblock
  - Tr
  - Trace
  - Transformation
  - U
  - Ul
  - Until
  - URL
  - Value
  - VSpace
  - While

- This manual in English

# Inhaltsverzeichnis in einem Durchlauf erstellen

Oft genug hat man Dokumente mit einem Inhaltsverzeichnis, das irgendwo am Anfang des Dokuments stehen soll. Der normale Weg beim speedata Publisher ist es, die Daten für das Inhaltsverzeichnis während eines Durchlaufs zu sammeln (welche Abschnitte gibt es? auf welcher Seite fangen diese an?). Im nächsten Durchlauf werden diese Daten dann benutzt, um das Inhaltsverzeichnis zu erstellen. Diese Methode war bisher notwendig, weil diese Informationen benötigt werden, bevor sie zur Verfügung stehen.

Nun hat PDF aber eine ganz nette Eigenschaft: man kann die Seiten in einer beliebigen Reihenfolge anzeigen lassen.

Der Seitenbaum in einer PDF-Datei besteht im einfachsten Fall aus einer Liste der vorhandenen Seiten.

Es ist möglich, die Reihenfolge der Seiten nachträglich zu ändern, in dem die Liste der Seiten geändert wird.

Der Seitenbaum muss nicht in der Reihenfolge der geschriebenen Seiten entsprechen.

Die Schnittstelle zum speedata Publisher läuft über die schon vorhandenen Befehle `<InsertPages>` und `<SavePages>`:

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

      <Record element="data">
        <InsertPages name="table of contents" pages="1" />

        <ProcessNode select="chapter" />

        <SavePages name="table of contents">
          <PlaceObject>
            ...
          </PlaceObject>
        </SavePages>
      </Record>
    </Layout>

Das Ziel der später erstellten Seiten wird mit `<InsertPages>` markiert und die eigentlichen Seiten mit `<SavePages>` erzeugt. Der speedata Publisher kümmert sich darum, dass die interne Seitenzahl nach `<InsertPages>` um die angegebene Zahl erhöht wird und dass im Inhalt von `<SavePages>` wiederum die Seitenzahl angepasst wird.

Damit die Seitennummerierung auch richtig ist, muss man die Anzahl der einzufügenden Seiten vorab kennen. Das ist bei Datenblättern und Produktkatalogen (dem eigentlichen Anwendungsfall für den speedata Publisher) fast immer gegeben, so dass das in der Praxis nur eine kleine Einschränkung ist.

## Beispiel

Dieses Beispiel ist aus dem Beispiel-Repository und wird in drei Schritten erläutert.

Zuerst wird ein Seitentyp definiert, der für alle Seiten gleich ist (Bedingung ist `true()`, diese Seite wird also immer ausgewählt). Dieser Seitentyp definiert einen Textrahmen (`text`) und gibt im Seitenfuß die Seitenzahl im äußeren Rand aus. Das dient hier nur zur Kontrolle, dass die Seiten auch richtig gezählt werden, denn es wird eine Seite vom Schluss an den Anfang geschoben.

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

      <Pageformat height="228pt" width="12cm" />
      <SetGrid height="12pt" nx="10"/>

      <Pagetype name="allPages" test="true()">
        <Margin left="1cm" right="1cm" top="24pt" bottom="24pt"/>
        ①
        <PositioningArea name="text">
          <PositioningFrame
            height="{sd:number-of-rows() - 2}"
            width="{sd:number-of-columns() }"
            column="1"
            row="1" />
        </PositioningArea>
        <AtPageShipout>
          ②
          <PlaceObject
                  column="1"
                  row="{sd:number-of-rows()}"
                  valign="bottom"
                  allocate="no">
            <Table  stretch="max">
              <Tr>
                <Td align="{if (sd:even(sd:current-page()))
                       then 'left' else 'right'}">
                  <Paragraph>
                    <Value select="sd:current-page()" />
                  </Paragraph>
                </Td>
              </Tr>
            </Table>
          </PlaceObject>
        </AtPageShipout>
      </Pagetype>

① Der Bereich `text` ist etwas kürzer als die Seite, damit im Seitenfuß die Seitenzahl ausgegeben werden kann.

② Die Seitenzahl wird in einer Tabelle ausgegeben. Je nachdem ob es eine gerade oder ungerade Seite ist, wird das Attribut `align` auf `left` oder `right` gesetzt.

Der Abschnitt `chapter` speichert die Seitenzahl und den Titel des Kapitels und gibt den Titel sowie ein paar Absätze eines Blindtexts aus.

      <Record element="chapter">
        ①
        <SetVariable variable="chapter{position()}title" select="@title" />
        <SetVariable variable="chapter{position()}page" select="sd:current-page()" />

        <Output area="text" row="1">
          <Text>
            <Paragraph>
              <B>
                <Value select="@title" />
              </B>
              <Action>
                ②
                <Mark select="concat('chapter',position())" pdftarget="yes" />
              </Action>
            </Paragraph>
            <Loop select="@paragraphs">
              <Paragraph>
                <Value select="sd:dummytext()" />
              </Paragraph>
            </Loop>
          </Text>
        </Output>
        <ClearPage />
      </Record>

① Die Variable `chapterXtitle` verhält sich wie ein array durch die Veränderung von X im Variablennamen.

② Durch `pdftarget="yes"` wird ein Ziel für interne Hyperlinks erzeugt.

Hier folgt das Herzstück und die Einsprungstelle für die Datenverarbeitung. Nachdem eine Seite für das Inhaltsverzeichnis reserviert wurde, werden die Kapitel ausgegeben und zum Schluss das Inhaltsverzeichnis erzeugt. Der speedata Publisher fügt das Verzeichnis an die richtige Stelle ein.

      <Record element="data">
        ①
        <InsertPages name="table of contents" pages="1" />

        ②
        <ProcessNode select="chapter" />

        ③
        <SavePages name="table of contents">
          <PlaceObject>
            <Table padding="4pt">
              <Columns>
                <Column width="7cm" />
              </Columns>
              <Loop select="count(chapter)" variable="n">
                <Tr>
                  <Td>
                    <Paragraph>
                      <A link="chapter{$n}">
                        <Value select="concat($n,' ' , sd:variable('chapter',$n,'title')" />
                        <HSpace leader="." />
                        <Value select="sd:variable('chapter',$n,'page')" />
                      </A>
                    </Paragraph>
                  </Td>
                </Tr>
              </Loop>
            </Table>
          </PlaceObject>
        </SavePages>
      </Record>
    </Layout>

① Hier wird eine Seite für das Inhaltsverzeichnis reserviert. Der Name muss identisch sein mit dem von `<SavePages>`.

② Erst werden alle Kapitel ausgegeben

③ Nun sind alle Seiten der Kapitelanfänge und die Namen der Kapitel bekannt und können ausgegeben werden. `<SavePages>` erzeugt virtuelle Seiten (in diesem Fall nur eine), die vorne eingefügt wird.

Das Inhaltsverzeichnis wird in einem Durchlauf erzeugt und vorne eingefügt.

- Verzeichnisse erstellen
- Seitenzahlen: Seite x von y