Statt Fotobände online zusammenzustellen, schreibt Mike Schilli lieber mit Ruby und TeX eine Applikation, die PDF-Bücher als Druckvorlage erzeugt.
Eigentlich hatte ich gedruckten Büchern ja schon abgeschworen. Wenn ich heute noch irgendein Werk aus Papier kaufe, meist gebraucht, wandert es sofort durch meinen Stapelschneider. Die Einzelseiten durchlaufen den Scanner und landen schließlich digitalisiert auf meinem iPad, wo ich sie dann lese.
Doch eine Art von Papierbuch finde ich immer noch interessant und sogar der digitalen Form überlegen: den dicken Fotoband, den man zufällig hingestreut auf einem Tischchen in der Hotellobby oder einer Ferienwohnung findet. Man lässt sich in einen danebenstehenden Sessel plumpsen, lehnt sich zurück, legt die Füße hoch und fängt gemütlich an zu blättern.
Auf amerikanisch nennt man so etwas Coffee Table Book, wohl weil es meist auf den niedrigen Kaffeetischchen ausliegt, und man kann solche Werke auch selbst mit eigenen Aufnahmen produzieren. Diverse Online-Anbieter halten Browser-Tools vor, um Fotos hochzuladen und über die Seiten eines virtuellen Papierbuchs zu verteilen. Drückt der Kunde dann den Absenden-Knopf und bezahlt, bringt der Postbote nach ein, zwei Wochen ein hochwertiges Buch mit Hardcover ins Haus (Abbildung 1).
Besser selbst gemacht
Online halten sich die Gestaltungsmöglichkeiten jedoch in Grenzen, und mangels einer Versionierung muss man befürchten, dass die schludrig programmierte Applikation jeden Moment die bisher investierte Arbeit verwirft und man von vorn beginnen muss. Wie wäre es mit einem handgestrickten Programm für zu Hause, das Fotobücher als PDF erzeugt, die man dann einfach und billiger in einem Rutsch bei einem Service wie Epubli.de drucken und binden lassen kann?
Und: Wieso sollte ein Mensch beim Arrangieren der Bilder mit der Maus herumfitzeln müssen, um diese alle auf Linie zu bringen, wenn ein Satzprogramm wie TeX die Fotos auf Kommando automatisch dorthin dirigiert, wo sie hingehören? Allerdings kann man kaum einem Anwender zumuten, sich mit der schrulligen TeX-Syntax herumzuschlagen und Fotobücher im Texteditor einzugeben, mittels gefährlich aussehender Kommandos, die mit umgekehrten Schrägstrichen beginnen und den Text in geschweiften Klammern sehen wollen.
Kleister aus Ruby
Mit etwas Kleister-Code aus Ruby können aber auch Nicht-Programmierer Druckvorlagen für ihre Kaffeetischbücher erstellen. Listing 1 zeigt die Definition eines Fotobands, der Kontaktabzug in Abbildung 2 das daraus generierte PDF. Sie nutzen pro Seite ein Template (etwa cover für die Umschlagseite, four für eine Seite mit vier Bildern) und geben die zugehörigen Fotos als photos und den untermalenden Text als text hinzu. Schwupp, schon spuckt die abschließende Methode print() in Zeile 35 ein PDF unter dem in Zeile 5 definierten Namen ("mybook") aus, das ein PDF-Viewer wie zum Beispiel Evince mit evince mybook.pdf anzeigt. Ein Online-Druckdienst macht daraus ratzfatz einen Prachtband mit Hardcover. Nicht schlecht, oder?
Listing 1
mkbook.rb
#!/usr/bin/ruby
require_relative "bm"
b = Bm.new
b.name = "mybook"
b.add "intro"
b.add "cover",
text: "Unstoppable Mike Schilli",
photos: ["ring.jpg"]
b.add "chapter"
b.add "single",
text: "On the Beach",
photos: ["ob-jump.jpg"]
b.add "twotowers",
text: "Planet of the Apes",
photos: ["icpf.jpg", "icp.jpg"]
b.add "four",
text: "All Along the Coast",
photos: ["thornton-jump.jpg",
"beach-rock.jpg",
"heron.jpg",
"beach-trunk.jpg"]
b.add "chapter",
text: "The End"
b.add "outro"
b.print
Unter der Haube erzeugt das Ruby-Interface dabei anhand der Templates TeX-Snippets und baut dazu mittels Variablen erläuternden Text und Pfade zu den Dateien der einzubettenden Fotos ein. Die Methode print() in Zeile 35 fügt am Ende alles zusammen und ruft das Programm Xelatex auf, das daraus ein professionell aussehendes PDF setzt. Xelatex installieren Sie zum Beispiel unter Ubuntu mit dem Kommando sudo apt install texlive-xetex. Es nimmt TeX-Dateien entgegen, setzt den Text und hält für die Fotos entsprechend ihrem Format und den Satzvorgaben leere Rechtecke frei. Der PDF-Treiber pflanzt anschließend die hereingereichten Fotos in die Löcher, fertig.
Der Vorteil? Jetzt steht die Buchbeschreibung als Code in einer Textdatei, die Sie jederzeit wieder abrufen, modifizieren oder mittels Versionskontrolle auf einen historischen Stand zurücksetzen können.
Urgesteine TeX und LaTeX
Allerdings ist das, was TeX unter der Haube treibt, so ausgefuchst, dass sich oft schwer vorhersagen lässt, ob das Arrangement der Fotos im Template nun den Vorstellungen des Layouters entspricht. Außerdem schreibt heute niemand (außer vielleicht der TeX-Autor Knuth selbst) mehr direkt TeX, um Bücher zu setzen – das übernimmt meist das darauf aufsetzende Makro-Paket LaTeX. Aber die richtige Zauberformel zu finden, damit LaTeX nicht plötzlich unvermittelt die Seite umbricht oder verrückte Entscheidungen trifft, erfordert oft nervenzehrende Fitzelei am Code, bis der TeX-Compiler das richtige Layout ausspuckt.
Steht aber ein Template erst einmal, funktioniert es bis ans Ende der Zeit. Das Originalbuch von TeX-Erfinder Knuth [1] und das Werk seiner LaTeX-Jünger [2] sind übrigens auch heute noch lesenswert, falls man sie in einem Antiquariat findet. Noch immer publizieren Experten mathematische Publikationen in LaTeX, und auch ich habe vor mehr als 20 Jahren einmal ein Perl-Buch in LaTeX geschrieben [3]. Diese Wahl setzt einen Autor definitiv einer extrem steilen Lernkurve aus, aber wer Versionskontrolle und Reproduzierbarkeit ohne manuelle Schritte schätzt, hat auch heute kaum eine andere Wahl. Professionelle Satzprogramme wie Adobe InDesign oder Quark Xpress können selbst heute, Jahrzehnte später, immer noch nichts automatisch.
Elegantes Ruby
Warum Ruby als Kleister-Code und nicht eine moderne Programmiersprache wie Go? Für reine Textmanipulation und simplen, prägnanten und einfach zu erweiternden Code, der fast schon wie eine Config-Datei aussieht, ist eine Skriptsprache wie Ruby einfach nicht zu schlagen. Noch dazu eignet sich Rubys Template-System Emb hervorragend zum Einpflanzen von Text oder Fotodateien in die Snippets mit dem TeX-Salat.
Listing 2 zeigt den Ruby-Kleister. Er definiert eine Klasse, die Sie zum Generieren eines Fotobuchs so wie in Zeile 2 von Listing 1 einbinden müssen. Mit require_relative bm finden Skripts die Bibliothek aus Listing 2 im selben Verzeichnis und können dann sofort mit Bm.new loslegen. Mit der zurückkommenden Instanz bm erstellen Sie mit wenigen Kommandos anspruchsvolle Fotobände.
Handliche Pfade
Die TeX-Templates liegen der Ordnung halber alle in einem Unterverzeichnis tmpl/. Damit Sie sie per einfachem Namen aufrufen können, etwa als cover, definiert Listing 2 eine Instanzvariable @tmpldir, die auf das Unterverzeichnis mit den Templates zeigt. Geht es ans Auslesen eines Templates, stellt Zeile 14 den tmpl-Pfad vor den hereingereichten Namen der Datei und hängt hinter den Namen noch die Endung .tex an. Damit zeigt der generierte Pfad auf eine real existierende Datei, die der Template-Prozessor Erb in Zeile 19 einlesen kann.
Listing 2
bm.rb
#!/usr/bin/ruby
require 'erb'
class Bm
attr_accessor :name
def initialize
@tmpldir = "tmpl"
@photodir = "photos"
@tex = ""
end
def add(tmpl, text: "", photos: [])
tpath = "#{@tmpldir}/#{tmpl}.tex"
photos = photos.map {
|path| "#{@photodir}/#{path}"}
t = ERB.new(File.read(tpath))
@tex += t.result_with_hash(
text: text, photos: photos)
end
def print
texf = "#{@name}.tex"
File.open(texf, "w") {
|f| f.write(@tex) }
system("xelatex", texf)
end
end
Den hereingereichten Text zur Seitenunterschrift und die Pfade zu den Fotodateien baut der Template-Prozessor mittels der Methode results_with_hash() in Zeile 20 in das jeweilige Template ein. Als Platzhalter in den Templates fungieren dabei <%= text %> für den Seitentext sowie <%= photos[0] %> für das erste Element des unter dem Parameter photos übergebenen Arrays zu Pfaden der einzubindenden Fotos. Auch bei den Bildpfaden müssen Sie also nicht jedes Mal umständlich den gesamten Pfad tippen. Solange die Instanzvariable @photodir auf das Verzeichnis zeigt, in dem alle Bilder liegen (im Beispiel photos/), brauchen Sie in Listing 1 jeweils nur den pfadlosen Dateinamen anzugeben.
Namen bestimmen
Um den Namen der zu erzeugenden Buchdatei zu bestimmen, setzt das aufrufende Skript das Attribut name eines Bm-Objekts wie in Zeile 5 von Listing 1. Damit das funktioniert, definiert Listing 2 mit attr_accessor in Zeile 5 mit :name ein les- und schreibbares Attribut name für alle Objekte der Klasse.
So kann eine Instanz der Klasse Bm in bm einfach mit bm.name = "mybook" wie in Zeile 5 von Listing 1 per Zuweisung den Namen setzen. Den fragt Zeile 25 in Listing 2 mit @name von der Instanzvariablen ab und interpoliert ihn innerhalb eines Strings mit "#{@name}". Damit steht der Name der TeX-Datei fest, die den TeX-Salat beherbergen soll, und wird im nächsten Schritt an den LaTeX-Compiler Xelatex geschickt.
So braucht Zeile 26 nur die .tex-Datei zum Schreiben zu öffnen und die in der Instanzvariablen @tex gesammelten TeX-Instruktionen dort abzulegen. Der system()-Aufruf in Zeile 28 setzt dann Xelatex darauf an, das ein gleichnamiges PDF-Dokument mit dem fertigen Fotobuch erzeugt, sofern alles gut geht.
Anfang und Ende
Wie sehen nun die Templates aus? TeX- oder vielmehr LaTeX-Code wimmelt nur so von Backslashes und begrenzt Textbereiche mittels geschweifter Klammern. Nach einer Präambel aus Dokumenttyp und verwendeten Zusatzpaketen beginnen die eigentlichen Dokumente immer mit der Anweisung \begin{document} und enden mit \end{document}. Dem tragen die Templates intro.tex und outro.tex in Listing 3 und**4 Rechnung, die den Anfang und das Ende jedes erzeugten Fotoalbums bilden.
Die LaTeX-Pakete color und pagecolor setzen die Farben des Fonts und des Hintergrunds im Dokument. Da Fotobücher im Dark Mode irgendwie professioneller aussehen, also mit weißer Schrift auf schwarzem Hintergrund, setzt das Template \color{white} und \pagecolor{black}.
Listing 3
intro.tex
\documentclass[10pt]{book}
\usepackage[export]{adjustbox}
\usepackage{color}
\pagecolor{black}
\color{white}
\usepackage[paperwidth=9in,
paperheight=7in,
total={8in,6.5in}]{geometry}
\pagestyle{empty}
\begin{document}
\sffamily
Listing 4
outro.tex
\end{document}
LaTeX-Dokumente drucken normalerweise die Seitennummern unten auf jede Seite. Das ist bei Fotobänden eher unüblich, daher unterdrückt der Befehl \pagestyle{empty} dieses Feature. Zudem wirkt TeXs Standard-Font Computer Modern etwas antiquiert. Die Sans-Serif-Version, die das Kommando \sffamily aktiviert, entspricht wohl eher dem Geschmack der Zeit. Das Paket adjustbox unterstützt das graphics-Paket beim Einbinden von Bildern und deren Schrumpfung, damit sie in die vom Layout-Roboter vorgegebenen Rechtecke passen.
Das Format des Fotobands legt das Paket geometry ab Zeile 6 von Listing 3 fest. Entsprechend der Vorgaben des von mir verwendeten Druckdienstleisters messen die Seiten 9 mal 7 Zoll im Querformat, wobei der tatsächlich bedruckte Bereich mit 8 mal 6,5 Zoll etwas kleiner ausfällt, damit noch etwas Rand bleibt. Für andere Dienstleister nehmen Sie hier Anpassungen am Seitenformat vor.
Das Ende des TeX-Dokuments läutet das Template outro.tex ein, das lediglich ein \end{document} absetzt, damit TeX später weiß, dass Schicht im Schacht ist.
Mittig schwebend
Ein TeX-Template für eine leere Seite mit einem optionalen zentrierten Textbaustein zeigt Listing 5. Der Template-Prozessor ersetzt den Platzhalter <%= text %> in Zeile 3 beim Einbinden durch den als text gesetzten Parameterwert. Damit der in der Größe Huge ausgegebene Text als Kapitelüberschrift zentriert (\center) in der Mitte der Seite zu liegen kommt, setzt Zeile 2 mit \vspace* einen Füllraum oberhalb davon, Zeile 4 erledigt dasselbe unterhalb des Texts. Da die beiden Füllräume oben und unten nach den Regeln der gerechten Platzaufteilung gleich große Flächen einnehmen, landet der Text in der Mitte der Seite. TeX unterscheidet übrigens zwischen \vspace und \vspace*: Das Kommando ohne das Sternchen ignoriert es am Seitenanfang, was die Kapitelüberschrift am oberen Rand der Seite schweben ließe.
Listing 5
chapter.tex
\null\newpage
\vspace*{\fill}
\center{\Huge{<%= text %>}}
\vspace*{\fill}
Guter erster Eindruck
Die Titelseite des Fotobuchs zeigt ein Bild und darunter eine Zeile Text in einem großen Font, beides zum rechten Rand ausgerichtet. Listing 6 leitet dazu im Template cover.tex mittels \begin{center} eine horizontal zentrierte Umgebung ein und bindet mit \includegraphics aus dem graphics-Paket der LaTeX-Bibliothek ein drei Zoll hoch gerendertes Foto ein. Der Template-Prozessor erhält später ein Array mit Fotodateien, der Platzhalter <= photos[0] %> setzt den Pfad der ersten Datei in der Liste ein. LaTeX reserviert daraufhin den vom Bild beanspruchten Platz im Dokument. Der PDF-Treiber setzt später das Foto ein, nachdem er es auf die benötigte Größe skaliert hat.
Listing 6
cover.tex
\vspace*{\fill}
\begin{center}
\hfill
\includegraphics[height=3in,valign=t]{
<%= photos[0] %>}
\hspace**{4cm}
\end{center}
\vspace{2cm}
\begin{center}
\hfill \Huge{<%= text %>}
\hspace*{4cm}
\end{center}
\vspace{1cm}
Für Aufnahmen, die groß herauskommen sollen, zeigt Listing 7 ein Template für ein seitenfüllendes Querformatfoto mit darunterstehendem Text, wie auf Seite 3 des fertigen Fotobuchs in Abbildung 2 zu sehen. Der Befehl \includegraphics{} stellt im Layout Platz für ein Bild bereit. Die Angabe von height beschränkt die Fläche in der Vertikalen, damit auf der Seite noch Platz für den darunterstehenden Text bleibt. Den platziert Zeile 10 mit einem halben Zentimeter Extraabstand unter dem Foto.
Listing 7
single.tex
\null
\begin{figure}
\centering
\includegraphics[height=5.5in,valign=t]{
<%= photos[0] %>}
\linebreak
\par\vspace{.5cm}\par
\Huge{\sffamily <%= text %>}
\end{figure}
Zwei Türme
Möchten Sie auf den querformatigen Seiten des Buchs auf einer Seite lieber zwei Fotos im Hochformat nebeneinander sehen, dann greifen Sie auf das Template twotowers.tex (Sinnbild für zwei Bilder im Hochformat) in Listing 8 zu. Es referenziert die beiden als Parameter hereingereichten Fotos mit <%= photos[0] %> und <%= photos[1] %>. Als Beispiel im Fotoband in Abbildung 2 dient ein Bild von einem Stück abgebrochener Straße, dessen spiegelbildlichen Gegenpart das Tool Convert aus der Sammlung ImageMagick erzeugt hat.
Listing 8
twotowers.tex
\null
\begin{figure}
\centering
\includegraphics[height=5in,valign=t]{
<%= photos[0] %>}
\hspace{1cm}
\includegraphics[height=5in,valign=t]{
<%= photos[1] %>}
\linebreak
\par \vspace{1cm} \par
\Huge{\sffamily <%= text %>}
\end{figure}
Eine Buchseite im Querformat kann aber auch vier quaderförmig angeordnete Querformatfotos aufnehmen. Das Template four.tex in Listing 9 zeigt den dazugehörigen TeX-Code. Für einen ansprechenden Abstand zwischen den Bildern schrumpft das Template die Fotos auf eine Höhe von 2,5 Zoll und setzt den horizontalen Abstand in den Zeilen 5 und 13 auf 0,5 Zentimeter. Den vertikalen Zwischenraum setzt Zeile 9 auf 0,75 Zentimeter.
Der darunterliegende Text in der Riesenschrift \Huge ist innerhalb der \centering-Umgebung ebenfalls zentriert und kommt wie von Zeile 17 vorgegeben 0,5 Zentimeter unterhalb des unteren Bildpaars zu liegen. Die Anweisung \par leitet in TeX jeweils einen neuen Absatz ein, und \vspace{} weist den Satzautomaten an, zwischen den Absätzen Platz zu lassen – in diesem Fall 0,5 Zentimeter.
Listing 9
four.tex
\begin{figure}
\centering
\includegraphics[height=2.5in,valign=t]{
<%= photos[0] %>}
\hspace{.5cm}
\includegraphics[height=2.5in,valign=t]{
<%= photos[1] %>}
\par
\vspace{.75cm}
\par
\includegraphics[height=2.5in,valign=b]{
<%= photos[2] %>}
\hspace{.5cm}
\includegraphics[height=2.5in,valign=b]{
<%= photos[3] %>}
\linebreak
\par\vspace{.5cm}\par
\Huge{\sffamily <%= text %>}
\end{figure}
Eigene Templates
Mit den vorgestellten Templates lässt sich bereits ein ansprechender Fotoband erstellen. Er besteht aus dem Einband, leeren Seiten, Kapitelüberschriften sowie Fotoseiten mit einem Foto im Querformat, zwei Fotos im Hochformat oder gleich vier Fotos im Querformat, alle mit optionalem Seitentext. Zum Erzeugen des fertigen Fotobands im PDF-Format muss nur ein Skript wie Listing 1 her, das die Templates abruft und entsprechende Fotos von der Platte einbindet.
Bei Bedarf lassen Sie Ihrer Kreativität aber freien Lauf und erzeugen beliebige neue TeX-Templates, die Sie dann im aufrufenden Ruby-Skript nutzen. Da die gesamte Buchdefinition in einer Textdatei liegt, idealerweise verwaltet von einem Versionskontrollsystem wie Git, können Sie ohne Verlustangst Änderungen einarbeiten oder auch Teile eines alten Bands in einen neuen übernehmen – programmierte Fotobanderstellung eben.
Tempus curat omnia
Ein Bonmot fand ich übrigens im 1984 in erster Auflage erschienenen TeX-Book von Donald Knuth: Auf Seite 110 erklärt er, warum TeX zwar akribisch versucht, Absätze so umzubrechen, dass die Wortabstände in allen Zeilen möglichst gleich erscheinen – bis zu dem Punkt, an dem ein einziges Wort am Ende eines Absatzes zu einem Totalumbruch des gesamten Absatztexts führt. Auf der anderen Seite schaut es aber beim Seitenumbruch nicht mehrere Seiten voraus, um Abbildungen und Textabsätze möglichst schlau über die Seiten zu verteilen. Den Grund für diese Designentscheidung nennt Autor Knuth auch gleich: Der RAM-Speicher eines typischen Desktop-Computers war damals schlicht nicht groß genug, um mehrere Seiten gleichzeitig vorzuhalten – wie die Zeiten sich ändern. (jlu)
Infos
-
“The TeX Book”: https://www.informit.com/store/computers-typesetting-volume-a-the-texbook-9780137494170
-
“The LaTeX Graphics Companion”: https://books.google.de/books?id=hh6rdgZ9m3MC
-
“Go To Perl 5”: https://books.google.de/books?id=Qs3GAAAACAAJ







