Sortierung von Stichwortverzeichnissen
In der Regel sind Stichwortverzeichnisse am Ende eines Dokuments zu finden, um in gedruckten Werken relevante Seiten schnell aufzufinden. Bei diesen Stichworten kann es sich um Wörter oder auch um Artikelnummern oder andere Bezeichnungen handeln.
Im Gegensatz zum Inhaltsverzeichnis (das meist vorne in einer Publikation ist), müssen die Daten nur zusammengestellt werden, ein Zwischenspeichern für den nächsten Lauf entfällt in der Regel.
Beispiel

Die Beispiele sind naturgemäß immer etwas konstruiert, das ist hier ganz besonders der Fall. Der Index wird in der Praxis natürlich anders zusammengestellt. Da hier nur die Sortierung gezeigt werden soll, wird das Stichwort und die Seitenzahl vorgegeben. Die Dateien sind auch im Beispiele-Repository zu finden.
<data>
<keyword word="Giraffe" page="1"/>
<keyword word="Garage" page="2"/>
<keyword word="Greeting" page="3"/>
<keyword word="Elevator" page="4"/>
</data>
Die Layoutdatei besteht aus drei Abschnitten, die einzeln erläutert werden.
<Layout xmlns="urn:speedata.de:2009/publisher/en"
xmlns:sd="urn:speedata:2009/publisher/functions/en">
<Record element="data"> <!--1-->
...
</Record>
<Record element="keyword"> <!--2-->
...
</Record>
<Record element="index"> <!--3-->
...
</Record>
</Layout>
- Der Rahmen, der erst die Einträge zusammenbaut, sortiert und anschließend ausgibt.
- Hier werden die Einträge einzeln in der Variablen
indexeinträgegespeichert. - Die sortierten Einträge werden in einer Tabelle ausgegeben.
Der Abschnitt data ist der erste Teil aus dem vorherigen Listing:
<Record element="data">
<SetVariable variable="indexentries"/> <!--1-->
<ProcessNode select="keyword"/>
<SetVariable variable="index"> <!--2-->
<Element name="index">
<Makeindex select="$indexentries/indexentry" sortkey="name" section="section"
pagenumber="page" />
</Element>
</SetVariable>
<ProcessNode select="$index/index"/> <!--3-->
</Record>
- Eine leere Variable
indexentrieswird deklariert. Diese wird im Recordentrymit den einzelnen Elementen gefüllt (s.u.). - Die nun gefüllte Variable
indexentrieswird um das Eltern-ElementIndexergänzt, sortiert und in$indexgespeichert. - Hier wird der Inhalt der Variablen
$indexals Datenstruktur interpretiert und ausgeführt (siehe die Ergänzung unten).
Der Befehl <Makeindex> sortiert und gruppiert die Daten, die im Attribut select übergeben werden. Die Sortierung erfolgt anhand des Attributs, das bei sortkey angegeben ist. Die Gruppierung erfolgt anhand des ersten Buchstabens des Sortierschlüssels. Die Elementstruktur, die mit dem Befehl <Makeindex> aufgebaut wird, ist folgende:
<index>
<section name="E">
<indexentry name="Elevator" page="4"/>
</section>
<section name="G">
<indexentry name="Garage" page="2"/>
<indexentry name="Giraffe" page="1"/>
<indexentry name="Greeting" page="3"/>
</section>
</index>
Der Abschnitt zum Element keyword (einfügen an Stelle 1 im Listing ) ist einfach gehalten, und entspricht dem »Copy-of« Muster (siehe copyof
). Hier wird die Variable indexeinträge um jeweils einen Eintrag ergänzt.
<Record element="keyword">
<SetVariable variable="indexentries">
<Copy-of select="$indexentries"/>
<Element name="indexentry">
<Attribute name="name" select="@word"/> <!--1-->
<Attribute name="page" select="@page"/>
</Element>
</SetVariable>
</Record>
- In der aktuellen Publisher-Version muss der Eintrag, der sortiert wird, in einem Attribut mit dem Namen
namegespeichert werden.
Im letzten Teil wird die Tabelle ausgegeben (einfügen an Stelle 3 im Listing ).
Für jeden Abschnitt (Element section in <Makeindex>) wird eine Zeile in Hellgrau ausgegeben mit dem Sortierschlüssel.
Anschließend wird für jeden Eintrag innerhalb dieses Abschnittes eine Zeile mit dem Namen des Eintrags und der Seitenzahl ausgegeben.
<Record element="index">
<PlaceObject column="1">
<Table width="3" stretch="max">
<ForAll select="section">
<Tr break-below="no" top-distance="10pt">
<Td colspan="2" background-color="lightgray">
<Paragraph><Value select="@name"></Value></Paragraph>
</Td>
</Tr>
<ForAll select="indexentry">
<Tr>
<Td>
<Paragraph><Value select="@name"/></Paragraph>
</Td>
<Td align="right">
<Paragraph><Value select="@page"/></Paragraph>
</Td>
</Tr>
</ForAll>
</ForAll>
</Table>
</PlaceObject>
</Record>
