headerbild blog

Feature der Woche: Silbentrennung

Silbentrennung ist in den meisten westlichen Sprachen notwendig, um ein einigermaßen gutes Erscheinungsbild für schmale Texte zu haben. Silbentrennung ist ein integraler Bestandteil des Umbruchalgorithmus, beispielsweise weil vermieden werden soll, dass mehrere Trennungen in aufeinanderfolgenden Zeilen auftreten.

Die Silbentrennung wird im Publisher über die Sprache gesteuert und musterbasiert vorgenommen (vielleicht sollte ich einen Beitrag dazu schreiben, wie die Silbentrennung in TeX funktioniert…). Die Sprache kann man global einstellen über <Options ...> oder Absatzweise.

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:

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.

von Patrick Gundlach |

Fehlerhafte ZIP-Dateien

Die letzten Tage hatte ich defekte ZIP-Dateien auf dem Server liegen. Das hat sich dadurch geäußert, dass auf Mac und Linux das Programm sdluatex nicht gestartet werden konnte. Die fehlerhaften ZIP-Dateien waren vermutlich zwei Wochen lang online. Sorry!

von Patrick Gundlach |

Feature der Woche: Bilderleiste

Diese Woche gibt ein unscheinbares Feature: man kann mit sd:aspectratio(<Dateiname>) das Seitenverhältnis eines Bildes ermitteln. Das kann man sich zu nutze machen, wenn man eine Bilderstrecke so aufteilen möchte, dass alle Bilder mit derselben Höhe dargestellt werden. Die Breite der Bilder soll aber variabel sein. Ich zeige erst einmal, wie es aussehen könnte:

von Patrick Gundlach |

Release 2.6

Nach recht kurzer (aber intensiver) Entwicklung gibt es nun ein neues »stable« Release: 2.6 Nachdem nun alle Bugs auf Github gefixt wurden, ist es Zeit diesen Stand einzufrieren.

von Patrick Gundlach |

Architektur speedata Publisher: Überblick

[Nachtrag: es gibt zwar diverse Beiträge hier, die die Architektur von anderer Seite betrachten, formal gab es jedoch keine weitere Teile.]

In einer mehrteiligen Serie gebe ich einen Überblick über die Architektur des speedata Publishers. Hinweis: für »normale Anwender« ist diese Serie nicht gedacht, eher für Entwickler und Interessierte.

Ich fange mal direkt mit einem groben Schema an:

Grobe Übersicht über die Komponenten des speedata Publishers

  1. Das Programm sp ist die Schnittstelle zum Benutzer. Es ist in der Programmiersprache Go geschrieben und startet den Prozess sdluatex oder luatex, je nach dem, was verfügbar ist. Bevorzugt ist die erste Variante, damit kein Namenskonflikt mit einer eventuell vorhandenen TeX-Installation verursacht wird. Außerdem wird ein Verbindung auf einem Socket geöffnet und per Umgebungsvariable (SP_SERVERPORT) übermittelt.

  2. LuaTeX in der Version 0.79 wird gestartet. Die Datei sdini.lua wird mit dem Prozess gestartet. Es wird die TeX-Bibliothek kpathsea deaktiviert und durch eine eigene ersetzt, die callbacks dafür werden in sd-callbacks.lua definiert.

  3. Für die Kommunikation mit dem übergeordneten Prozess wird in comm.lua eine TCP-Verbindung zum sp-Prozess gestartet. Derzeit wird diese Verbindung genutzt, um Funktionalität von Go zu nutzen, speziell reguläre Ausdrücke für die Funktionen contains(), replace() und tokenize() und für einen robusten HTML Parser. In Zukunft wird vermutlich weitere Funktionalität im sp- Prozess abgebildet. Die Kommunikation wird über ein sehr einfaches Protokoll abgewickelt.

  4. und

  5. Bilder und Fonts werden über LuaTeX eingelesen. Die Fonts werden mit der Bibliothek fontforge eingelesen. Die OpenType Tabellen werden direkt in Lua-Tabellen abgebildet. Für die eingebundenen Bilder werden Metadaten zur Verfügung gestellt.

  6. LuaTeX erwartet in alter Tradition eine .tex-Datei. Die Datei publisher.tex besteht aus dem minimalen Code

      \catcode`\{=1
      \catcode`\}=2
    
      \directlua{require("publisher.spinit")}
    
      \end
    

    um die Datei spinit.lua zu laden und dort (ganz zum Schluss) die main_loop() zu starten. Hier werden hauptsächlich ein paar Voreinstellungen gesetzt (z.B. die lccodes für die Silbentrennung), die Verbindung zum Go-Prozess erzeugt (siehe Punkt 3) und in der Datei

  7. publisher.lua die Funktion dothings() aufgerufen, die wiederum die

  8. XML-Dateien lädt und sonstige Initialisierung vornimmt. Interessant ist noch der nächste Punkt:

  9. TeX, insbesondere LuaTeX, bietet einen sehr guten Absatzumbruchalgorithmus und andere Funktionalität, die im Publisher sehr nützlich sind. So kann man mit tex.linebreak() den Umbruch erzeugen und das Ergebnis verarbeiten. Mit tex.shipout() kann eine Seite in das PDF ausgegeben werden.

In der nächsten Folge gehe ich speziell auf die Datenstruktur ein, die LuaTeX intern nutzt.

von Patrick Gundlach |

Feature der Woche: Absatzformen

Es gibt zwei Befehle, Text auszugeben: PlaceObject/Textblock und Output/Text. Die erste Variante über Textblock erzeugt einen rechteckigen Bereich, der nicht über mehrere Seiten umbrochen werden kann. Das ist für Produktkataloge in der Regel ausreichend, für Fließtext aber nicht.

von Patrick Gundlach |

Feature der Woche: Raster

Die Wikipedia enthält zum Thema Gestaltungsraster den folgenden Text:

»Der Gestaltungsraster (in der Praxis oft das Gestaltungsraster), auch der typografische Raster, Rastersystem oder auf Englisch auch Grid genannt, ist ein Ordnungssystem in der visuellen Kommunikation, das als Hilfskonstruktion die Organisation von grafischen Elementen auf einer Fläche oder in einem Raum erleichtert. Gestaltungsaufgaben, in denen der Raster Anwendung findet, sind meist typografischer Art – es wird dann von Rastertypografie gesprochen.«

Es handelt sich also um nicht sichtbare Linien oder Kästchen, an dem Objekte ausgerichtet sind. Man kennt es beispielsweise vom Zeitungsdruck, wo es oftmals fünf oder sechs Spalten gibt. Alle Bilder oder Anzeigen füllen dann eine oder mehrere Spalten aus. Ebenso gibt es in Katalogen häufig Rasterzeilen, die ähnlich funktionieren. Dadurch erreicht man ein klares Layout.

Der speedata Publisher arbeitet grundsätzlich mit einem solchen Raster. Da jede Publikation anders ist, gibt es keine Möglichkeit, eine sinnvolle Vorgabe dafür zu machen. In der Voreinstellung ist das Raster mit einer Größe von 1cm × 1cm gesetzt. Es gilt für die Seite sowie alle Positionierungsrahmen und Gruppen. Anzeigen kann man das Raster mit sp --grid oder <Trace grid="yes"/> im Layout.

Diese Datei unter layout.xml speichern und die PDF-Datei mit sp --dummy erzeugen:

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

  <Trace grid="yes"/>
  <Pageformat width="8cm" height="6cm"/>


  <Record element="data">
    <PlaceObject column="3" row="2">
      <Textblock>
        <Paragraph>
          <Value>Hello world!</Value>
        </Paragraph>
      </Textblock>
    </PlaceObject>
  </Record>
</Layout>

ergibt

Einfaches Raster

Wenn man genau hinschaut, sieht man, dass der erste und dann jeder fünfte Strich etwas dunkler gezeichnet wird. Das hilft dabei, Rasterzellen zu zählen, falls das notwendig sein sollte. Die rote Linie zeigt die Begrenzung der Seite, in der Voreinstellung sind die Ränder jeweils 1cm. In dem Beispiel sieht man auch schon, dass die Angaben bei row und column sich auf das Raster bezieht, der Ursprung oben links hat die Koordinate 1,1. Bei row und bei column kann man auch absolute Angaben machen wie 12cm. Das bezieht sich dann immer auf die linke bzw. obere Entfernung zum Papierrand.

Das Raster wird mit dem Befehl <SetGrid> global eingestellt. Z.B.

<SetGrid height="12pt" nx="10"/>

setzt die Rasterhöhe auf 12 Punkt und die -breite auf 1/10 der Seitenbreite. Man kann auch noch Abstände zwischen den Rasterzellen festlegen.

Eine Schwierigkeit gibt es bei der Festlegung eines Rasterwerts auf eine bestimmte Größe: wenn die Papierbreite, der Seitenrand und die Rasterbreite festgelegt werden, können die Angaben sich widersprechen.

Wofür wird das Raster benötigt?

Ruft man sp mit der Option --show-gridallocation auf, so sieht man sofort, wofür das Raster auch gut ist. Belegte Zellen werden intern markiert, so dass kein weiteres Objekt in diesem Bereich platziert werden kann. Zumindest nicht ohne Fehlermeldung oder dem Hinweis, dass kein Bereich dafür freigehalten werden soll (allocate="no" in <PlaceObject>).

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

  <SetGrid height="12pt" nx="10"/>
  <Trace grid="yes" gridallocation="yes"/>
  <Pageformat width="8cm" height="6cm"/>

  <Record element="data">
    <PlaceObject column="3" row="2">
      <Textblock>
        <Paragraph>
          <Value>Hello world!</Value>
        </Paragraph>
      </Textblock>
    </PlaceObject>
  </Record>

</Layout>

ergibt

Raster mit Rasterbelegungsanzeige eingeschaltet. Der gelbe Bereich wird intern als »belegt« markiert.

Der Versuch, ein Objekt in einen schon belegten Bereich zu platzieren, gibt eine Warnung.

Fügt man dem Layout oben noch die Zeilen

<PlaceObject column="1" row="1">
  <Image file="ocean.pdf" height="4"/>
</PlaceObject>

hinzu, ergibt sich folgende Rasterbelegung:

Doppelt belegtes Raster. Rot markiert sind die Flächen, die sich mehrere Objekte teilen (überlappen)

und eine Warnung:

...
PlaceObject: Image in row 1 and column 1, width=4, height=4 (page 1)
Warning: Rasterkonflikt
...

(Die Datei ocean.pdf kann hier herunter geladen werden.)

Lässt man die Angaben für Spalte und Zeile weg, sucht sich der Publisher die nächste freie Position selbsttätig.

Bilder, Barcodes, Boxen etc. haben feste Breiten und Höhen. Texte und Tabellen nutzen die noch vorhandene Breite meist aus. So benötigt die Textbox aus dem Beispiel oben keine Angabe einer Breite. Es wird einfach die Breite angenommen, die in Spalte 3 noch verfügbar ist, bei 10 Spalten Seitenbreite sind das 8 Spalten.

Benötigt ein Objekt (wie das Bild oben) eine Breiten- oder Höhenangabe, kann diese entweder absolut (z.B. 5cm) gegeben werden oder in Rasterzellen. Abstände zwischen den Rasterzellen werden automatisch berücksichtigt.

Eigene Raster in Gruppen

Es folgt ein Beispiel für ein Raster innerhalb einer Gruppe. Ohne die explizite <Grid .../>-Angabe wird das Raster der Seite genommen.

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

  <SetGrid nx="4" ny="4"/>
  <Trace grid="yes" gridallocation="yes" objects="yes"/>

  <Record element="data">
    <Group name="table">
      <Grid width="1cm" height="12pt"/>
      <Contents>
        <PlaceObject>
          <Table width="4" stretch="max">
            <Tr>
              <Td><Paragraph><Value>Spalte 1/1</Value></Paragraph></Td>
              <Td><Paragraph><Value>Spalte 2/1</Value></Paragraph></Td>
            </Tr>
            <Tr>
              <Td><Paragraph><Value>Spalte 1/2</Value></Paragraph></Td>
              <Td><Paragraph><Value>Spalte 2/2</Value></Paragraph></Td>
            </Tr>
          </Table>
        </PlaceObject>
        <PlaceObject row="4" column="2">
          <Image file="ocean.pdf" width="3"/>
        </PlaceObject>
      </Contents>
    </Group>

    <PlaceObject groupname="table"/>
  </Record>
</Layout>

Ausschnitt aus einer Seite. Das Raster innerhalb der Gruppe ist deutlich feiner als das grobe Seitenraster.

Update 1.10.2016: die Option zum Anzeigen des Rasters ist nicht mehr unter Options zu finden, sondern unter Trace. Der Inhalt des Beitrags wurde angepasst. Siehe auch Feature der Woche: Debugging.

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.
von Patrick Gundlach |