Sil-ben-tren-nung

Tilman Kranz, 21.1.2009.

Das Problem

Ich will Dateien, die UTF-8-kodierten, deutschsprachigen Klartext mit UN*X-Zeilenumbrüchen enthalten, so nachbearbeiten, dass eine Markierung für möglichen silbentrennenden Zeilenumbruch eingefügt wird (English: hyphenation hint). Ich folge dabei der UNICODE[tm]-Auslegung des Zeichens SOFT HYPHEN (U+00AD). Da ich Texte für Webseiten mit einem Texteditor schreibe, verwende ich die HTML-Entität ­, da ich sonst keine visuelle Unterscheidung zwischen "Minus", "Bindestrich", "Gedankenstrich", "langem Gedankenstrich" und eben "Silbentrennungs-Strich" hätte. Das verhält sich nämlich zwar unterschiedlich, sieht aber im Texteditor alles gleich aus.

Die Lösung

heisst perl und dazu das Modul TeX::Hyphen. Keine Sorge, man muss dafür nicht das gesamte TeX installieren, das Modul verwendet nur ein paar Regeldateien, und bringt die gleich selbst mit. Alles ganz schmerzfrei. Noch. ;-)

Erstmal etwas Code (Lizenz):

#!/usr/bin/env perl
#hyphenate.pl -- Stream-Filter, der Silbentrennungs-Entitäten einfügt

use TeX::Hyphen;
use strict;
use warnings;

my $hyp = new TeX::Hyphen style => 'german';
my $rep = '­'; # welche Zeichenkette repräsentiert die 
                       # Silbentrennung? In diesem fall ver-
                       # wende ich die entsprechende HTML-Entität.
my $laenge = length($rep);  # 
while(<>){
   # Ein simpler Ansatz, um "Wörter" zu sequentialisieren:
   my @words = split /\s+/, $_;
   foreach my $wort(@words){
      my $versatz = 0; # der Versatz beim Suchen/Ersetzen
                       # verschiebt sich jeweils um die
                       # Länge des eingefügten Silbentrenner-
                       # Strings.

      # hyphenate() liefert offsets im Wort, an denen
      # Silbentrennung möglich zu sein scheint.
      for my $pos ($hyp->hyphenate($wort)) {
         substr($wort, $pos + $versatz, 0, $rep);
         $versatz+=$laenge;
      }
      # Füge einen Worttrenner an:
      print $wort, " ";
   } 
   # Stelle den Zeilenumbruch aus der Eingabe wieder her.
   # Es ist ein bisschen die Frage, ob das gewollt ist,
   # aber in reinem Klartext kann ich anders die
   # Absatzinformation nicht aufrechterhalten. Es stört
   # in HTML nicht, weil dem die eingegebenen Zeilenumbrüche
   # in Fliesstext egal sind.
   print "\n";
}

Ausprobieren!

 $ echo foobarbaz Datenbank | ~/hyphenate.pl
foo&shy;bar&shy;baz Daten&shy;bank
 $

So weit, so hübsch.

Test

Auffällig sollte der Unterschied bei schmalen Spalten und langen Worten werden.

width: 20em;
Eine Datenbankadministrationsschnittstelle ist die Funktionsschnittstelle zur Administrationsfunktionalität einer Datenbank beziehungsweise mehrerer Datenbanken in einem Datenbankverwaltungssystem.

Hier das Ergebnis:

width: 20em;
Eine Daten­bankad­min­is­tra­tionss­chnittstelle ist die Funk­tion­ss­chnittstelle zur Ad­min­is­tra­tions­funk­tion­al­ität ein­er Daten­bank beziehungsweise mehrerer Daten­banken in einem Daten­bankver­wal­tungssys­tem.

Hier die eingefügten Silbentrenner veranschauklicht:

Eine Daten-bankad-min-is-tra-tionss-chnittstelle ist die 
Funk-tion-ss-chnittstelle zur Ad-min-is-tra-tions-funk-tion-al-ität 
ein-er Daten-bank beziehungsweise mehrerer Daten-banken in einem 
Daten-bankver-wal-tungssys-tem.

Ich war damit nicht wirklich zufrieden, denn da fehlen ja einige ziemlich offensichtliche Silbentrennungen. Es stellte sich heraus: die in TeX::Hyphen eingebaute Tabelle ist nur die generische, die ein gewisser Herr D. Knuth in einem massiven Anfall von Genialität für alle Sprachen der Welt auf einmal gecodet hat ;-) Das Setzen irgendwelcher lang="de" usw. Attribute im HTML hatte keine Auswirkungen (und die Software informiert darüber auch nicht). Um schön deutsch trennen zu können, müssen wir uns eine aktuelle, deutsche Wortliste besorgen. So etwas habe ich auf CTAN gefunden (Mirror, Experimental Hyphenation wahlweise für alte oder neue deutsche Rechtschreibung). Man braucht die .pat-Datei (Lizenz).

Ändern wir dann noch das Script:

my $hyp = new TeX::Hyphen 
   style => 'german', 
   file => 'dehyphn-x-2008-06-18.pat';

und wir erhalten:

width: 20em;
Ei­ne Da­ten­bank­ad­mi­nis­tra­ti­ons­schnitt­stel­le ist die Funk­ti­ons­schnitt­stel­le zur Ad­mi­nis­tra­ti­ons­funk­tio­na­li­tät ei­ner Da­ten­bank be­zie­hungs­wei­se meh­re­rer Da­ten­ban­ken in ei­nem Da­ten­bank­ver­wal­tungs­sys­tem.

Veranschaulicht:

Ei-ne Da-ten-bank-ad-mi-nis-tra-ti-ons-schnitt-stel-le ist die 
Funk-ti-ons-schnitt-stel-le zur Ad-mi-nis-tra-ti-ons-funk-tio-na-li-tät 
ei-ner Da-ten-bank be-zie-hungs-wei-se meh-re-rer Da-ten-ban-ken in 
ei-nem Da-ten-bank-ver-wal-tungs-sys-tem. 

Wenn ich hier Kopieren & Einfügen veranstalte (ich benutze firefox 3 auf windows xp und editiere das HTML in vim in screen mit putty mit vim-einstellungen termencoding=iso-8859-15 und encoding=utf-8, also eine denkbar "vielschichtige" Zugriffsmethode), dann werden die hyphenation hints allesamt mitkopiert.

Das ist allerdings schrecklich, wenn man den Text nachträglich irgendwie ändern will. Wer das will, muss alle soft hyphens wieder rausfiltern, was aber mit vim & Co. auch kein Ding ist.

Leider ist der Umbruch der Browser schrecklich dilettantisch, man kann ihm keine Limits setzen. Er wird jetzt ständig umbrechen - die Ausrichtung auf left zu setzen, hilft nicht:

width: 35em;
Ei­ne Da­ten­bank­ad­mi­nis­tra­ti­ons­schnitt­stel­le ist die Funk­ti­ons­schnitt­stel­le zur Ad­mi­nis­tra­ti­ons­funk­tio­na­li­tät ei­ner Da­ten­bank be­zie­hungs­wei­se meh­re­rer Da­ten­ban­ken in ei­nem Da­ten­bank­ver­wal­tungs­sys­tem.

Hier sind sowohl TeX als auch OpenOffice.org weiterhin überlegen, desweiteren natürlich die (entsprechend teuren) "professionellen" Satzsysteme, die ich hier nicht nennen werde.

Vielleicht kann man sich das ja von den entsprechenden freien Softwaresystemen wünschen.

Hier noch etwas weiterführender Lesespass: Typolexikon: Flattersatz (gefunden hier).

Ausbau zu einem Werkzeug in meinem Autorensystem

Tatsächlich schreibe ich HTML direkt hin. Dabei habe ich bislang eine Art „auf vorwärtskompatibilität bedachtes HTML 4“ geschrieben. Damit ist jetzt Schluss, ich steige auf XHTML um, und habe mir in diesem Sinne einen Parser geschrieben, der in einem XHTML-Input allen Textinhalt von p-Elementen silben-trennt.

Auf diese Weise kann ich meine Dokumente schreiben, und muss dann nur noch einen Filter drüber laufen lassen, und sie sind silben-getrennt.

Also habe ich irgendwelchen XML-Parsing-Foo auf die Thematik geworfen, bis genau das ging. Hier ist das Ergebnis.

Ende.


Lizenz Silbentrennungs-Algorithmus und meine perl-Skripten: Wie man ein Wort anhand der points, die einem TeX::Hyphen liefert, silben-trennt, habe ich aus dem Code für die Methode visualize() im Modul Hyphen.pm abgekupfert. Von daher steht dernachfolgende Code unter der selben Lizenz wie das Modul TeX::Hyphen selbst. Da dessen Dokumentation keine spezifische Lizenz nennt, nenne ich auch keine. 8-)

Lizenz Silbentrennungs-Datenbank: Die Silbentrennungs-Musterdatei steht unter der LaTeX project public license. Ich weise darauf hin, dass das gesamte TeX-Zeug extrem nützlich ist und mir in Zusammenhang mit dem perl-Modul irrsinnig viel Arbeit erspart hat. Wenn ich das richtig verstanden habe, generieren der oder die Autoren das mit mächtig viel intelligentem Software-Foo aus irgendwas anderem ... so ganz hab ich's nicht verstanden. Und die LPPL habe ich auch nicht verstanden, deswegen ich hier nur sage, woher man die Datei bekommt und sie nicht selbst weiterverteile. meh.