Eigenen Textexport erzeugen mit XSLT

Hier findest du Anleitungen und kleine Tipps und Tricks zu Scribus
Antworten
Benutzeravatar
Manutius
Beiträge: 31
Registriert: So 27. Sep 2015, 22:37

Eigenen Textexport erzeugen mit XSLT

Beitrag von Manutius »

Es kann vorkommen, dass man vor folgender Frage steht: Ich habe z.B. eine Broschüre o.Ä. mit Scribus gestaltet und will den Inhalt auch auf eine Webseite stellen oder anderweitig weiterverwenden. Wie kann man das machen? - Das ist das, was man heute "Cross Media Publishing" nennt.

Für den Export von Text stellt Scribus tatsächlich nur den Export der Inhalte von Textrahmen im reinen Textformat zur Verfügung, alle Formatierungen gehen also verloren. Export als HTML usw. geht nicht.

Mit dem Export ist es ähnlich wie mit dem Import - solche Funktionen sind schwer zu programmieren, weil sich ein grundlegendes Problem stellt: Ein DTP-Programm ist keine eierlegende Wollmilchsau. Ein Seitenlayoutprogramm ist zur freien Gestaltung von Seiten gemacht und soll dabei der Kreativität keine Grenzen setzen: Wer einen bunten Buchstabensalat produzieren möchte, kann es tun. Formate wie HTML, EPUB usw. beruhen hingegen auf Strukturinformationen, sie setzen eine regelmäßige Struktur voraus. Bekanntlich kann man z.B. aus Word auch HTML-Dokumente erzeugen, aber das, was dabei herauskommt, ist alles andere als sauberes, effizientes HTML, sondern ein Wust, der sich schwer weiterverarbeiten lässt. Cross-Media-Publishing wird heute zunehmend verlangt, aber selbst bei den professionellen Programmen sind die dafür vorgesehenen Standardfunktionen mit Vorsicht zu genießen. (Man arbeitet dann am besten von vornherein mit einem gut durchdachten XML-Workflow, Scribus bietet diese Möglichkeit jedoch nicht.)

Ich erstelle mit Scribus regelmäßig einen Vereins-Newsletter mit einem zeitungsartigen Layout, der als PDF an die Empfänger verschickt wird, die ihn sich dann ausdrucken können. Unter den Empfängern gibt es auch Blinde. Diese haben das Problem, dass sie mehrspaltige PDF-Dokumente kaum lesen können - die Screenreader kommen mit Mehrspaltigkeit nicht zurecht. Deshalb erstelle ich immer auch eine reine Textversion. Dafür reicht im Prinzip die Text-Exportfunktion von Scribus aus. Allerdings ist es ein bisschen umständlich, weil ich immer alle einzelnen Artikel exportieren und dann zusammenfügen muss. Ich habe also überlegt, ob es dafür nicht eine bessere Lösung gibt.

Es gibt sie. Ein Vorteil von Scribus besteht darin, dass das *.sla-Dokumentformat nichts anderes ist als ein XML-Textformat (wenn auch mit einer etwas eigenwilligen Struktur). XML lässt sich prinzipiell in andere Formate transformieren - mit XSLT.

Dazu braucht man einen XSLT-Prozessor und eine XSL-Stylesheet-Datei, in der die Transformationsregeln festgelegt werden.

Ich habe mich also ein bisschen damit beschäftigt, wie man mit XSLT den Text aus Scribus-Dokumenten exportieren kann - und zwar den ganzen Text auf einmal. (Dabei werden keine Texte aus Musterseiten berücksichtigt - dies sind üblicherweise Standardseitenelemente, die außerhalb des Layouts meist nicht benötigt werden.)

Hier ist ein minimales XSLT-Stylesheet:

Code: Alles auswählen

<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
  xmlns:xhtml="http://www.w3.org/1999/xhtml"
  xmlns="http://www.w3.org/1999/xhtml"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  exclude-result-prefixes="xhtml xsl xs">
<xsl:output method="text" encoding="utf-8"/>
<xsl:strip-space elements="*"/>

<xsl:template match="DOCUMENT">
  <xsl:apply-templates/>
</xsl:template>

<!-- wir wollen keine Texte aus Musterseiten übernehmen -->
<xsl:template match="MASTEROBJECT"/>

<!-- Seitenobjekte nur verarbeiten, wenn sie Textknoten enthalten -->
<xsl:template match="PAGEOBJECT">
  <xsl:if test="./ITEXT">
    <xsl:apply-templates/>
    <xsl:text>&#10;&#10;&#10;</xsl:text>
  </xsl:if>
</xsl:template>

<!-- Absätze mit Leerzeilen ausgeben -->
<xsl:template match="para">
  <xsl:apply-templates/>
  <xsl:text>&#10;&#10;</xsl:text>
</xsl:template>

<!-- Text ausgeben -->
<xsl:template match="ITEXT">
  <xsl:value-of select="@CH"/>
</xsl:template>

<!-- Handhabung verschiedener Zeichen -->
<xsl:template match="nbspace">
  <xsl:text>&#160;</xsl:text>
</xsl:template>
<xsl:template match="tab">
  <xsl:text>&#9;</xsl:text>
</xsl:template>
<xsl:template match="breakline">
  <xsl:text>&#10;</xsl:text>
</xsl:template>

</xsl:stylesheet>
Anwendung unter Linux:

Der Code wird in einer Textdatei scrtext.xsl gespeichert (Codierung: UTF-8).

Der XSLT-Prozessor xsltproc muss installiert werden - er sollte in den Repositorien aller gängigen Distributionen verfügbar sein.

Die zu verarbeitende Datei scribusdokument.sla und das Stylesheet scrtext.xsl werden zusammen in ein Verzeichnis gelegt. In diesem Verzeichnis erfolgt dann der Terminalaufruf

$ xsltproc scrtext.xsl scribusdokument.sla > ausgabe.txt

Der gesamte Text aus dem Dokument wird dann in die Datei ausgabe.txt geschrieben.

(Windows- und Mac-Anwender müssen einen XSLT-Prozessor installieren und nach dessen Bedienungsanleitung verfahren.)

Nun ein Ansatz zu einer Verfeinerung für die Ausgabe von Text, der zu HTML weiterverarbeitet werden kann:

Das folgende Stylesheet gibt den Text mit einigen Elementen der Auszeichnungssprache Markdown (http://de.wikipedia.org/wiki/Markdown) aus, mit der auf einfache Weise HTML-Dokumente erzeugt werden können. Wenn im Scribus-Dokument Überschriften erster Ordnung mit einem Absatzstil HEAD1 und Überschriften zweiter Ordnung mit HEAD2 formatiert werden, so werden diese mit ===== und ----- unterstrichen ausgegeben - diese Unterstreichungen stehen in Markdown für die HTML-Elemente <h1> und <h2>. Alles, was mit Zeichenstilen formatiert wurde, wird in der Ausgabe mit *Asterisken* markiert, diese werden in Markdown kursiv formatiert.

Code: Alles auswählen

<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
  xmlns:xhtml="http://www.w3.org/1999/xhtml"
  xmlns="http://www.w3.org/1999/xhtml"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  exclude-result-prefixes="xhtml xsl xs">
<xsl:output method="text" encoding="utf-8"/>
<xsl:strip-space elements="*"/>

<xsl:template match="DOCUMENT">
  <xsl:apply-templates/>
</xsl:template>

<!-- wir wollen keine Texte aus Musterseiten übernehmen -->
<xsl:template match="MASTEROBJECT"/>

<!-- Seitenobjekte nur verarbeiten, wenn sie Textknoten enthalten -->
<xsl:template match="PAGEOBJECT">
  <xsl:if test="./ITEXT">
    <xsl:apply-templates/>
    <xsl:text>&#10;&#10;&#10;</xsl:text>
  </xsl:if>
</xsl:template>

<!-- Absätze mit Leerzeilen ausgeben, HEAD1 und HEAD2 als Überschriften -->
<xsl:template match="para">
  <xsl:choose>
     <xsl:when test="@PARENT = 'HEAD1'">
       <xsl:text>
========================================================================</xsl:text>
     </xsl:when>
     <xsl:when test="@PARENT = 'HEAD2'">
       <xsl:text>
------------------------------------------------------------------------</xsl:text>
     </xsl:when>
     <xsl:otherwise/>
  </xsl:choose>
  <xsl:apply-templates/>
  <xsl:text>&#10;&#10;</xsl:text>
</xsl:template>

<!-- Text ausgeben -->
<xsl:template match="ITEXT">
  <xsl:variable name="content">
    <xsl:value-of select="@CH"/>
  </xsl:variable>
  <xsl:variable name="style">
    <xsl:value-of select="@CPARENT|@FONT"/>
  </xsl:variable>
  <xsl:choose>
    <!-- Zeichenstile werden mit * markiert -->
    <xsl:when test="$style != ''">
      <xsl:text>*</xsl:text>
      <xsl:value-of select="$content"/>
      <xsl:text>*</xsl:text>
    </xsl:when>
    <!-- alles Übrige wird als reiner Text ausgegeben -->
    <xsl:otherwise>
      <xsl:value-of select="$content"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

<!-- Handhabung verschiedener Zeichen -->
<xsl:template match="nbspace">
  <xsl:text>&#160;</xsl:text>
</xsl:template>
<xsl:template match="tab">
  <xsl:text>&#9;</xsl:text>
</xsl:template>
<xsl:template match="breakline">
  <xsl:text>&#10;</xsl:text>
</xsl:template>

</xsl:stylesheet>
Der Code ist z.B. in einer Datei scrtextmd.xsl abzuspeichern. Die Verarbeitung mit XSLT erfolgt wie im vorigen Beispiel beschrieben. Die Ausgabedatei kann dann mit einem Markdown-Prozessor in ein HTML-Dokument umgewandelt werden.

Für eine Ausgabe mit weiteren dokumentspezifischen Stilen müsste das Stylesheet entsprechend angepasst werden. Eines ist klar: Man kann sich mit XSLT maßgeschneiderte Lösungen für bestimmte Dokumentstandards schaffen. Eine allgemeine Lösung für alles und jedes ist nicht möglich - aus den oben angeführten Gründen.

Grundsätzlich kann man XML-Dateien mit XSLT natürlich direkt in HTML und beliebige andere textbasierte Formate transformieren. Eine direkte Lösung für die Umwandlung von Scribus-Dokumenten in HTML ist mir jedoch bislang nicht gelungen. Das Problem liegt darin, dass im Scribus-Dokumentformat eine, vorsichtig ausgedrückt, etwas eigenwillige XML-Struktur verwendet wird (in welcher der Text in Attributen [!] von ITEXT-Elementen abgelegt wird), die sich mit XSLT schwer parsen lässt.
Benutzeravatar
Arran
Beiträge: 417
Registriert: Sa 31. Jan 2015, 12:27
Wohnort: Isle of Arran, Schottland
Kontaktdaten:

Re: Eigenen Textexport erzeugen mit XSLT

Beitrag von Arran »

Tolles und ausführliches Tutorial. Da bin ich als Bleifritz sogar einigermassen drausgekommen. Ob ich es allerdings je anwenden kann, weiss ich nicht.
________________________________________________________

Off-topic:
Bist Du der ältere oder der Jüngere Aldus? Das waren doch die beiden, die die Bembo zuerst hatten?
Ein Cicero muss nicht zwangsläufig 12 Punkte haben, wie ein Waisenkind auch nicht immer im Heim leben muss.
Bild
Kubuntu 14.04-3, Scribus-Version 1.4.3.svn
Benutzeravatar
Manutius
Beiträge: 31
Registriert: So 27. Sep 2015, 22:37

Re: Eigenen Textexport erzeugen mit XSLT

Beitrag von Manutius »

So, nun habe ich mein XSL-Template für meinen Newsletter zur Perfektion gebracht und freue mich auf die nächste Produktion: Da macht die Arbeit mit Scribus richtig Spaß. Ein Terminalbefehl, und der gesamte Inhalt wird sauber als Textdatei abgespeichert. Nie wieder muss ich die einzelnen Artikel aus den diversen Textrahmen exportieren und dann zusammensetzen.

Jetzt ist mir aber noch etwas aufgefallen, was ich bislang nicht bemerkt hatte - weil es unsichtbar ist: Scribus speichert die Silbentrennstellen im Text mit ab. Das ist das Unicode-Zeichen U+00AD. In den meisten Texteditoren sieht man es nicht (wohl aber in Vim). Die problematische Folge ist die, dass dann auch die Suche nach Text nicht funktioniert.

Nach dem Export der Textdatei sollte also noch ein Suchen/Ersetzen-Lauf erfolgen: Das Zeichen U+00AD ist durch nichts zu ersetzen. Das geht leider nicht mit XSLT. Aber natürlich lässt es sich mit sed oder Perl automatisieren, ich fasse die XSLT-Transformation und den Ersetzungsvorgang in einem Bash-Skript zusammen.
fridolin1
Beiträge: 1
Registriert: Mo 21. Dez 2015, 15:02

Re: Eigenen Textexport erzeugen mit XSLT

Beitrag von fridolin1 »

Super Tutorial!
Wer noch mehr Infos zu xslt sucht kann sich hier mal umschauen: http://www.data2type.de/xml-xslt-xslfo/xslt
Hat mir weiter geholfen!
Antworten