weidner/archives/2014/02/

Handbuchseiten als EPUB-Ebook

Eigentlich habe ich auf jedem Linux-Rechner genügend Informationen in Form von Handbuchseiten um bei der Fehlersuche mit Bordmitteln das letzte aus den vorhandenen Werkzeugen herauszuholen. Eigentlich. Außer, wenn der Rechner nicht läuft und ich schon beim Systemstart in der Initramdisk lande. Da sind genug Werkzeuge, um die meisten Probleme zu beheben und die Kiste wieder flott zu machen. Aber wie war jetzt gleich noch mal diese Option von udevadm oder dd genau? Ich kenne etliche Programme so gut, dass meine Finger die Optionen hinschreiben, ohne dass ich darüber nachdenken muss. Aber nur die, die ich täglich oder wenigstens einmal pro Woche verwende.

Wenn nun ein Rechner absolut nicht hochfahren will und kein zweiter in der Nähe ist, um schnell mal nachzuschauen.

Früher, hätte man einen Satz Handbuchseiten ausgedruckt im Regal gehabt. Früher. Ja.

Heute habe ich einen EPUB-Reader, ein Tablett und mein Telefon ist inzwischen so groß wie ein Reclam-Heft und fasst die ganze Reclam-Bibliothek.

Da könnte man doch die Handbuchseiten als Ebook aufbereiten und immer dabei haben. Oder wenigstens die der Programme von der Initramdisk, weil da der man Befehl ja nicht geht.

Gesagt, getan.

Nein, so schnell geht es nicht. Erstmal habe ich nachgeschaut, welche Programme da überhaupt drauf sind:

gunzip -c < /boot/initrd.img-3.2.0-58-generic \
| cpio -it --quiet \
| perl -ne 's|^.*s?bin/([^/]+)$|$1| && print'

Aus der Liste habe ich noch die Programme, für die keine Handbuchseiten existieren, aussortiert.

Diese Handbuchseiten sollten in's Ebook. Auf anderen Systemen sind vermutlich andere Programme auf der Initramdisk.

Handbuchseiten in HTML umwandeln

Nun weiß ich, welche Handbuchseiten ich haben will. Für ein EPUB-Ebook muss ich diese noch in HTML umwandeln. Darüber haben sich auch andere schon Gedanken gemacht. Auf StackExchange (Ask Ubuntu) gibt es dazu folgenden Vorschlag um alle Handbuchseiten umzuwandeln:

for f in `ls -1 /usr/share/man/man*`; do
  n=`echo $f | sed s/[.].*[.]gz//`
  man -Thtml $n > $n.html
done

Ich habe das ausprobiert, war aber mit dem Ergebnis nicht zufrieden. Also habe ich mich weiter umgeschaut und die folgenden Möglichkeiten gefunden, Handbuchseiten in HTML umzuwandeln.

man

Das war der Vorschlag von Ask Ubuntu, der ist nur noch mal zur Referenz aufgeführt:

$ man -Thtml $MANPAGE \
> epub/$MANPAGE.html

groff

Das liegt vermutlich dem vorhergehenden Aufruf zugrunde:

$ zcat /usr/share/man/man1/$MANPAGE.1.gz \
| groff -Thtml -man - \
> epub/$MANPAGE.html

man2html

Das Programm man2html enthält ein CGI-Programm, das die Handbuchseiten für Webbrowser aufbereitet. Natürlich kann man auch Standalone-HTML-Seiten erzeugen:

$ man2html -p -r /usr/share/man/man1/$MANPAGE.1.gz \
> epub/$MANPAGE.html

rman

Rman, auch Polyglotman genannt, nimmt als Eingabe Handbuchseiten, die für eine Vielzahl von Unix-Varianten formatiert sind (keine [gnt]roff-Quellen) und produziert als Ausgabe eine Vielzahl von Dateiformaten.

$ man $MANPAGE \
| rman -f HTML -r off \
> epub/$MANPAGE.html

Die Ausgabe von rman sagte mir am meisten zu, also beschäftigte ich mich mit diesem Programm etwas näher.

Mit dem Perl-Modul App::MakeEPUB und dem darin enthaltenen Program make-epub ist das Erzeugen eines gültigen EPUB-Ebooks aus einer HTML-Datei ein Kinderspiel:

make-epub -output $MANPAGE.epub \
          -creator 'Mathias Weidner' \
          -publisher 'Mathias Weidner' \
          -title 'Initramfs Man Pages' \
          -rights 'CC BY-SA 3.0' \
          -level2 '_tag:h2' \
          -tocdepth 2 \
          epub

Wenn die HTML-Dateien gut genug für epubcheck sind. Das waren sie leider nicht. Außerdem hatte rman in der verwendeten Version (3.2-6 auf Ubuntu 12.04) Probleme mit den UTF8-Zeichen in den Handbuchseiten.

Diese Probleme ließen sich aber mit ein paar Filtern beseitigen.

Unsauberes HTML

Um HTML ohne größeren Aufwand zu bereinigen bietet sich das Programm tidy an. Damit wird der Aufruf von rman zu diesem:

$ man $MANPAGE \
| rman -f HTML -r off \
| tidy -asxml -f tidy.errors \
> epub/$MANPAGE.html

Nun waren die HTML-Seiten schon fast epubcheck-fest.

Die einzelnen Optionen bedeuten:

Zwar hatte ich nun sauberes XHTML, aber epubcheck hatte an diesem immer noch etwas auszusetzen, was ich mit einem kleinen Perl-Skript und dem Modul HTML::TreeBuilder jedoch bereinigen konnte. Das Skript ändert gleich noch die Überschrift der Handbuchseite in eine einheitliche Form, da bei den Handbuchseiten aus verschiedenen Quellen Großschreibung, Kleinschreibung und Mischformen auftraten, die insbesondere das Inhaltsverzeichnis sehr unansehnlich machten.

Der Aufruf von rman änderte sich damit zu:

$ man $MANPAGE \
| rman -f HTML -r off \
| tidy -asxml -f tidy.errors \
| bin/mangle-rman-html.pl -title "$MANPAGE" \
> epub/$MANPAGE.html

Probleme mit den UTF8-Zeichen

Damit war epubcheck zufrieden gestellt, aber beim Durchlesen der Handbuchseiten fiel mir auf, dass einzelne Zeichen nicht korrekt im EPUB ankamen. Bei meinen Untersuchungen dazu stellte ich fest, dass rman nicht mit den UTF8-Zeichen, die es von man bekam, umgehen konnte. Kurzerhand schob ich den folgenden Filter zwischen man und rman, der die problematischen Zeichen entschärfte:

#!/usr/bin/perl
#
# This cleans up man pages for use with rman.
# This means converting from utf8 to latin1 too.
#
use 5.010;
use strict;
use warnings;

binmode(STDIN,':utf8');
binmode(STDOUT,':raw');

my $concat = '';

while (<>) {
    if ($concat) {
        s/^\s*//;
        $_ = $concat . $_;
        $concat = '';
    }
    if (/\x{2010}\s*$/) {   # hyphen at end of line
        s/\x{2010}\s*$//;
        $concat = $_;
        next;
    }
    s/\x{00b1}/\x{b1}/g;    # plusminus
    s/\x{00b7}/*/g;     # middle dot
    s/\x{2012}/-/g;     # figure dash
    s/\x{2014}/-/g;     # em dash
    s/\x{2018}/'/g;     # left single quotation mark
    s/\x{2019}/'/g;     # right single quotation mark
    s/\x{201c}/"/g;     # left double quotation mark
    s/\x{201d}/"/g;     # right double quotation mark
    s/\x{27e8}/</g;     # mathematical left angle bracket
    s/\x{27e9}/>/g;     # mathematical right angle bracket
    print;
}
__END__

Außer der Konvertierung von UTF8 nach Latin1 nimmt der Filter Worttrennungen wieder aus dem Text, da das HTML an beliebigen Stellen umgebrochen werden kann und dann die Worttrennung den Lesefluss stören würde.

Damit wird der Aufruf von rman zu diesem:

$ man $MANPAGE \
| bin/clean-utf8-man.pl \
| rman -f HTML -r off \
| tidy -asxml -f tidy.errors \
| bin/mangle-rman-html.pl -title "$MANPAGE" \
> epub/$MANPAGE.html

Jetzt sieht das EPUB mit den Handbuchseiten gut genug für mich aus. Die Skripts, mit denen ich die Handbuchseiten bearbeitet habe, finden sich in dieser Archivdatei.

Posted 2014-02-12
Tags: