Samstag, 29. März 2014

Silbentrennung für Ebooks

ISOIEC-9995-7-076--IEC-60417-6073--Symbol-for-Soft-Hyphen
Soft-Hyphen Keyboard Symbol
Quelle: Wikipedia, CC0
Ja, der Titel ist geklaut. Vor ca. zwei Wochen war ich wieder einmal auf den Chemnitzer Linuxtagen und bin dort auf den Vortrag von Georg Pfeiffer »Perfekte Silbentrennung in E-Books mit präreformatorischen Texten« gestoßen.

Da ich ja ua. die »Bunte Bilder aus dem Sachſenlande« als E-Book aufbereite, benötige ich für meine Texte ebenfalls eine "perfekte" Silbentrennung. Georg hat in seinem Vortrag auf das Projekt »Trennmuster« der TeX-Leute hingewiesen. Das hat mich neugierig gemacht.

Nach dem Herunterladen des Projektes (was sehr lange dauert, da die Wortlisten knapp 15MB groß sind) mittels

$> git clone git://repo.or.cz/wortliste.git

findet man die Trennmuster in den Dateien pre-1901 und wortliste. Die letztere ist für mich eher uninteressant, da diese nur Wörter nach den jeweiligen Rechtschreibreformen enthält. Die pre-1901 ist recht einfach aufgebaut, hier ein Auszug:

aber<mah-li-gen
ab<füh-re-ten
ab<ge<fer-ti-get
ab<ge<than
ab<ge<theilt
ab<hoh-len
ab<thei-len
ab<theil-ten
Ab<thei-lung
Ab<thei-lun-gen


Das Zeichen '<' bezeichnet die Trennung, falls es sich um eine Vorsilbe handelt. Das Zeichen '-' gibt eine normale Trennung an, das Zeichen '=' (im Beispiel nicht vorhanden) eine Trennung zwischen zusammengesetzten Worten.

Für ein Ebook sind mir diese unterschiedlichen Trennungen egal, so das ich, wie Georg, an all den Trennstellen ein Weiches Trennzeichen setzen möchte.  Unicode kennt solch ein Zeichen als Code U+00AD. Als HTML-Entität wäre es &shy;. Das weiche Trennzeichen erlaubt es, Trennanweisungen zu kodieren, für den Fall, daß das Anzeigeprogramm gezwungen ist, den Text umzubrechen. Es ist also nur an Zeilenumbrüchen als Trennzeichen zu erkennen und sonst im Text unsichtbar.

In meinem Perlscript zur Verarbeitung des Roh-Textes zu einem eigenen Asciidoc lese ich die Datei pre-1901 ein, es entsteht ein Hash %hyphens, der als Schlüssel das ungetrennte Wort verwendet und als Wert die getrennte Version mit weichen Trennzeichen. Dabei werden nicht die Feinheiten, die mit der Trennmuster-Datei möglich wäre unterschieden, sondern eine vereinfachte Variante kodiert.
Aus 'ab<thei-len' würde also der Schlüssel 'abtheilen' und die Trennvariante (hier mit '-' statt Unicode) 'ab-thei-len' als Wert entstehen.


 sub find_hyphens {
    my $filename="hints/pre-1901";
    open (my $fh, "<", "$filename");
    binmode $fh, ":utf8";
    while (<$fh>) {
        chomp;
        # replace '-' to &shy;
        s#([a-z])-$#$1\x{00ad}#g; # &shy; U+00AD
        my $hyphenized=$_; # simplifed hyphenized

        $hyphenized=~s/[<>=-]/\x{00ad}/g;
        my $orig=$_;
        $orig=~s/[<>=-]//g; # original, dehyphenized word
        $hyphens{$orig}=$hyphenized;
    }
    close $fh;
}

Im weiteren Programm bekomme ich die Textzeilen zeilenweise übergeben. Mit folgendem Snippet lese ich dann die Wörter und ersetze sie durch ihre weich-getrennte Version:
        # inject hyphens (for ebooks)
   foreach my $word (keys %hyphens) {
        my $hyphenized = $hyphens{$word};
        s#\b$word\b#$hyphenized#g;
   }
Voila!

Als Nebeneffekt bekommt das Trennzeichenprojekt meine Wortliste aus dem Buchprojekt. Auf alle Fälle war diese Erfahrung ein gutes Beispiel dafür, wie man sich in der Welt der Freien Software gegenseitig befruchten kann. Danke für die Idee an Georg!