Das feuerrote Kindle-Mobil (Linux-Magazin, August 2012)

Fertige E-Books für den Kindle leicht gemacht: Das CPAN-Modul EBook::MOBI überführt das bewährte POD-Format für Perl-Dokumentation per Tastendruck in das digitale Mobi-Format für unterschiedlichste mobile Endgeräte der Kindle-Familie und ihrer Ableger.

Es dürfte kaum verwundern, dass die Artikel der Perl-Snapshot-Reihe ihr Dasein als Manuskripte im POD-Format beginnen (Abbildung 1). Schließlich ist das seit Jahrzehnten bewährte Dokumentationsformat einfach zu tippen und zu lesen, und eine Reihe von Tools wandelt es problemlos um: In HTML, in Manual-Seiten, in LaTeX und damit PDF oder PostScript, oder in das vom der Redaktion des Linux-Magazins gewünschte Format ([2]). Mit dem CPAN-Modul EBook::MOBI ist es sogar möglich, aus POD Mobi-Dateien zu erzeugen und private Erzeugnisse als E-Books für Kindle-Lesegeräte und -Apps zu veröffentlichen.

Abbildung 1: Die POD-Datei mit dem Original-Manuskript dieses Artikels.

Cloud teilt aus

Dank einer Reihe von Mechanismen zur Verbreitung von E-Book-Dateien innerhalb Amazons Cloud und daran angeschlossenen Endgeräten dauert es nicht lange, bis nach der Transformation in das proprietäre HTML-ähnliche Format selbstgefertigte E-Books auf Kindle-Geräten verschiedener Generationen, aber auch Android-Geräten, iPads, oder iPhones erscheinen. Kurz: Auf jeder Plattform, auf der Amazons Kindle-App läuft. Abbildung 2 zeigt zum Beispiel das Android-Modell "Galaxy 4.0", ein telefonloses Smartphone (einem iPod Touch nicht unähnlich), mit einer Neuerscheinung im Kindle-Store: Dem aus dem Manuskript-POD der aktuellen Snapshot-Folge generierten E-Book. Die zugehörige Textansicht in Abbildung 3 zeigt, wie die Kindle-App den POD-markierten Inhalt in ein ansprechendes digitales Layout verwandelt.

Abbildung 2: Die selbstgestrickte Mobi-Datei in der Rubrik "Neuerscheinungen" in der Kindle-App auf einem Galaxy 4.0 Android.

Abbildung 3: Text der Mobi-Datei in der Kindle-App auf dem Galaxy 4.0 Android.

Ein genauerer Blick auf das Original-Manuskript in Abbildung 1 offenbart außerdem, dass die Redakteure meine radikalen Titelvorschläge oft umschreiben: Aus "Das feuerrote Kindle-Mobil" wurde ein konservatives "XXX".

Noch etwas fällt auf: Das POD-Format verfügt von Haus aus über kein Image-Tag, aber EBook::MOBI versteht das Pseudo-Tag

    =image /pfad/image.jpg Beschreibung

und fügt die Bilddatei mitsamt der Unterschrift in das E-Book ein. Doch wie wurde aus der POD-Datei ein digitales E-Book im Amazon-Format?

Aus POD mach Mobi

Listing 1 benötigt lediglich drei CPAN-Module, Sysadm::Install, Pod::Parser und EBook::MOBI, die sich mittels des Aufrufs

    $ perl -MCPAN -e 'install Sysadm::Install, EBook::MOBI, Pod::Parser'

vom nächsten CPAN-Mirror auf den heimischen Rechner holen und installieren lassen. Mit diesen verfügt es über das notwendige Handwerkszeug, um aus einer auf der Kommandozeile übergebnen POD-Datei ein E-Book für Kindle-Apps namens book.mobi zu generieren.

Listing 1: pod2mobi

    01 #!/usr/local/bin/perl -w
    02 
    03 ###################
    04 package MyParser;
    05 ###################
    06 our @ISA = qw(Pod::Parser);
    07 
    08 ###########################################
    09 sub title {
    10 ###########################################
    11   my( $self ) = @_;
    12 
    13   return $self->{ __title };
    14 }
    15 
    16 ###########################################
    17 sub command {
    18 ###########################################
    19   my ($parser, $command, 
    20       $paragraph, $line_num) = @_;
    21 
    22   $paragraph =~ s/\n+$//;
    23 
    24   if( $command eq "head1" ) {
    25     $parser->{ __title } = $paragraph if
    26     !defined $parser->{ __title };
    27   }
    28 }
    29 
    30 ###################
    31 package main;
    32 ###################
    33 use strict;
    34 use Sysadm::Install qw( slurp );
    35 use EBook::MOBI;
    36 use Pod::Parser;
    37 
    38 my( $pod_file ) = @ARGV;
    39 
    40 if( !defined $pod_file ) {
    41     die "usage: $0 file.pod";
    42 }
    43 
    44 my $parser = MyParser->new();
    45 $parser->parse_from_file( 
    46     $pod_file, "/dev/null" );
    47 
    48 my $book = EBook::MOBI->new();
    49 my $pod = slurp ( $pod_file, 
    50                   { utf8 => 1 } );
    51 
    52 $book->set_author( "Mike Schilli" );
    53 $book->set_title( $parser->title() );
    54 
    55 $book->set_encoding(':encoding(UTF-8)');
    56 
    57 $book->add_pod_content($pod, 'pagemode');
    58 $book->make();
    59 $book->save();

Parser-Klasse sucht Titel

Eigentlich benötigt EBook::MOBI in Listing 1 nur die Zeilen ab package main, aber da pod2mobi den Inhalt der ersten =head1-Zeile des PODs extrahiert und mittels set_title() zum Titel des E-Books erhebt, definiert package MyParser ab Zeile 4 eine von Pod::Parser abgeleitete Klasse. Ihre einzige Ausgabe ist es, im Callback command ab Zeile 17 zu prüfen, ob es sich beim aktuellen POD-Kommando um die erste Hauptüberschrift vom Typ =head1 handelt, und falls ja, deren Inhalt in der Instanzvariablen __title zu sichern. Die Methode title() ab Zeile 9 spielt diesen dann interessierten Nutzern wie dem Hauptprogramm zu. Dieses ruft die Methode parse_from_file() des Parsers auf und übergibt ihr den Namen der POD-Datei und die Datei "/dev/null", damit beim Durchforsten des POD-Codes keinerlei Ausgaben auf STDOUT erfolgen.

Die Methoden set_author() und set_title() der Klasse EBook::MOBI setzen dann Autor und Titel des Mobi-Dokuments. Damit Umlaute im utf8-kodierten POD-Text auch im E-Book ordentlich erscheinen, ist es wichtig, wie in Zeile 55 die Kodierung mit set_encoding() auf "UTF-8" zu setzen. Fehlt nur noch, den vorher eingesaugten POD-Code mit add_pod_content() zum E-Book hinzuzufügen. Der zweite Parameter "pagemode" veranlasst den Konverter, nach jeder =head1-Überschrift einen Seitenumbruch einzufügen. Ein anschließendes make() genieriert das Mobi-Format. Die in Zeile 59 aufgerufene Methode save() sichert letzteres auf der Festplatte under dem Namen book.mobi.

Portables E-Book

Wie gelangt das frisch erzeugte E-Book nun auf die Endgeräte, die das Format lesefreundlich anzeigen? Die unter Linux und auch anderen Betriebssystemen verfügbare Applikation Calibre stellt das generierte E-Book zwar dar (Abbildung 4), kommt aber später mit den Abbildungen durcheinander. Sie scheint allgemein mit dem Mobi-Format auf Kriegsfuß zu stehen, und leider brachte sie bei den im Zuge dieses Artikels durchgeführten Tests einige Male angeschlossene Kindle-Geräte beim Hochladen der von ihr offiziell unterstützen Dateien zum Absturz. Bis zur Produktionsreife müssen Anwender wohl noch einige Versionen warten.

Abbildung 4: Auf Linux lädt das Programm calibre die Mobi-Datei.

SSH auf dem Android

Das im Test verwendete Android-Gerät "Galaxy 4.0" hatte zum Glück die kostenpflichtige proprietäre App QuickSSHd installiert (Abbildung 5), die auf dem handyähnlichen Gerät einfach einen SSH-Server startet, mit dem sich das ssh-Programm auf einem Laptop über das Wireless-Netzwerk verbindet. User authenisieren sich entweder mit einem fest eingestellten Passwort oder einer Private/Public-Key-Kombination. Experimentierfreudige können so (ohne das Gerät rooten zu müssen) das dortige Dateisystem erforschen. Abbildung 6 zeigt, wie das Kommando scp vom Laptop aus die Mobi-Datei in das Verzeichnis /mnt/sdcard/kindle kopiert. Es handelt sich um einen Ordner auf der im Android eingestöpselten SD-Speicherkarte, den die auf dem Gerät installierte Kindle-Applikation überwacht. Findet sich dort eine neue Mobi-Datei, erscheint sie in den Bereichen "Home" und "On Device" der Kindle-Applikation (Abbildung 2).

Abbildung 5: Die App QuickSshd startet einen ssh-Server, der per scp die Mobi-Datei im Kindle-Verzeichnis speichert.

Abbildung 6: Das scp-Kommando kopiert die Mobi-Datei in den Ordner der Kindle-Applikation auf dem Android-Gerät.

Steckt ein Kindle-Gerät im USB-Port einer Linux-Box, lässt sich die Mobi-Datei auch ganz einfach in das lokal gemountete Verzeichnis /media/Kindle/documents kopieren.

Ab die Post

Listing 2 nutzt statt dessen die Email-Schnittstelle von Amazon, um die Mobi-Datei an ein Endgerät zu senden. Die Übertragung ist kostenlos, solange der Kindle (oder ein Android-Gerät, ein iPad oder ein iPhone mit der Kindle-App) über eine Wireless-Verbindung erreichbar sind ([5]). Empfängt der Service eine Email mit einer als Attachment angehängten Mobi-Datei, schickt sie diese an das angegebene Zielgerät. Außerdem sind so hochgepumpte E-Books anschließend über die Kindle-Cloud auf jedem damit verlinkten Gerät des Users verfügbar (Abbildung 7).

Abbildung 7: Das selbstgefertigte E-Book erscheint in der persönlichen Kindle-Library auf dem Amazon-Service.

Listing 2: mail-to-kindle

    01 #!/usr/local/bin/perl -w
    02 use strict;
    03 use MIME::Lite;
    04 
    05 my( $file ) = @ARGV;
    06 
    07 if( !defined $file ) {
    08     die "usage: $0 file.mobi";
    09 }
    10 
    11 my $msg = MIME::Lite->new(
    12     From    => 'm@perlmeister.com',
    13     To      => 
    14       'Gaxy Galaxy xxx@Kindle.com>',
    15     Subject => 'My Ebook',
    16     Type    => 'multipart/mixed'
    17 );
    18 
    19 my $part = MIME::Lite->new(
    20     Type     => 'text/plain',
    21     Data     => "some text\n",
    22 );
    23 
    24 $msg->attach( $part );
    25 
    26 $msg->attach(
    27     Type        => 'application/mobi',
    28     Path        => $file,
    29     Filename    => $file,
    30     Disposition => 'attachment',
    31 );
    32 
    33 $msg->send( 'smtp', 'mail.some-smtp.com' );

Das Skript in Listing 2 erwartet den Namen der zu übertragenden Mobi-Datei auf der Kommandozeile (zum Beispiel mail-to-kindle book.mobi) und erzeugt mittels des CPAN-Moduls MIME::Lite eine Email mit Attachment. Abschließend schickt es diese an einen SMTP-Mailserver, der sie zu der angegebenen Amazon-Adresse weiterleitet Der Name des SMTP-Servers in Zeile 33 ist an an den verwendeten Mail-Provider anzupassen. Jedes Kindle-Endgerät und auch jede Kindle-App zeigt in ihrem "Settings"-Menü eine personalisierte Email-Addresse unter @Kindle.com an. Dort nimmt Amazon Mobi und eine Reihe anderer Formate (allerdings kein .epub) entgegen und leitet sie an das über das Internet an die Cloud angeschlossene Lesegerät weiter. Die Empfängeradresse in Zeile 14 muss also im Skript an das jeweilige Endgerät angepasst werden. Und Vorsicht: Nur über eine Wireless-Verbindung ist die Übertragung kostenlos, läuft sie über Amazons Handy-Netzwerk "Whispernet", fallen pro MB Gebühren an.

Einmal in der Kindle-Library angelangt (Abbildung 7), kann jedes weitere Lesegerät des Users das handgeschriebene E-Book herunterladen. Abbildung 8 zeigt, wie die Kindle-App auf einem iPad2 das Artikel-Manuskript anzeigt.

Abbildung 8: Das fertige E-Book in der Kindle-Applikation auf dem iPad.

Noch nicht ganz perfekt

Der Teufel liegt natürlich wie immer im Detail. Damit ein E-Book schön formatiert daher kommt, muss ein Layouter oft manuell eingreifen. Abbildungen dürfen nicht zu dicht hintereinander stehen, damit sie den Textfluss nicht unterbrechen. Manchmal muss der Redakteur sogar Sätze umgeschreiben, wenn zu viele lange Wörter den Zeilenumbruch erschweren. Außerdem ist das proprietäre Mobi-Format weniger durch eine vollständige Spezifikation definiert als dadurch, was auf den unterschiedlichen Readern gut ankommt. So erfordern bestimmte Reader bestimmte Auflösungen für Grafiken, die auf anderen nicht so gut ankommen. Amazons Kindle-Shop ist voll von entsprechenden Praxisratgebern.

Das CPAN-Modul EBook::MOBI baut auf dem MobiPerl-Code [3] von anno dunnemals auf und unterstützt (anders als das Original) leider keine Cover-Abbildungen. Der Code vertrüge durchaus noch einige Verbesserungen, wer mag, sollte sich an dem Projekt beteiligen.

Infos

[1]

Listings zu diesem Artikel: ftp://www.linux-magazin.de/pub/listings/magazin/2012/08/Perl

[2]

"Linux-Magazin: Hinweise für unsere Autoren", http://www.linux-magazin.de/Heft-Abo/Kontakt/Autor-werden#textformat

[3]

"MobiPerl" SVN-Repository, https://dev.mobileread.com/svn/mobiperl/

[4]

"Kindle Personal Documents Service", http://www.amazon.com/gp/help/customer/display.html?nodeId=200767340

Michael Schilli

arbeitet als Software-Engineer bei Yahoo in Sunnyvale, Kalifornien. In seiner seit 1997 laufenden Kolumne forscht er jeden Monat nach praktischen Anwendungen der Skriptsprache Perl. Unter mschilli@perlmeister.com beantwortet er gerne Ihre Fragen.