4 Punkte von GN⁺ 2024-04-29 | 1 Kommentare | Auf WhatsApp teilen
  • Auch nach dem Ende der Web-Veröffentlichung brauchte Crafting Interpreters weitere 15 Monate Arbeit, bis daraus ein echtes Buch wurde; am Ende erschien es als Druckausgabe, E-Book und PDF
  • Um ein Bündel aus Markdown- und PNG-Dateien in ein Buch zu verwandeln, mussten ein Build-System in Dart, XML-Import für InDesign, JavaScript-Automatisierung und Satzprüfung neu aufgebaut werden
  • Das Endergebnis hat das Format 8×10 Zoll, 640 Seiten, mehr als 200.000 Wörter, 1.133 Code-Snippets und Hunderte Illustrationen – mit deutlich strengeren Layout-Anforderungen als gewöhnliche Web-Inhalte
  • Es folgten fünf Monate komplette Durchsicht, professionelles Copyediting, zwei Monate Satz, zwei Wochen Indexarbeit, die Prüfung von Korrekturabzügen und automatisierte PDF-Vergleiche
  • Ein selbst verlegtes technisches Buch ist mit dem Schreiben allein nicht abgeschlossen; Build-, Layout-, Prüf- und Distributionsautomatisierung entscheiden über Qualität und Vollendung des Buchs

Die Arbeit, die nach der Fertigstellung der Web-Inhalte noch blieb

  • Der Haupttext von Crafting Interpreters war bereits fertig, doch das damalige Ergebnis bestand aus Markdown- und PNG-Dateien, die per Python-Code in eine Website umgewandelt wurden
  • Das Ziel war von Anfang an ein echtes gedrucktes Buch; nach dem Hochladen des letzten Kapitels ins Web legte der Autor etwa einen Monat Pause ein
  • Nach fast vier Jahren täglichen Schreibens war er stark erschöpft, und auch die Lage Anfang 2020 machte es schwer, die Arbeit fortzusetzen

Ein neu in Dart gebautes Build-System

  • Zunächst wurden Tippfehler und Fehler korrigiert, die Leser über GitHub-Issues gemeldet hatten
  • Danach wurde das gesamte Build-System des Buchs in Dart neu geschrieben
    • Das Build-Skript des ersten Buchs war ein einzelnes Python-Skript gewesen, das Markdown-Dateien pro Kapitel in HTML renderte und Codefragmente einfügte
    • Crafting Interpreters musste über 30 Kapitel hinweg schrittweise den Code zweier vollständiger Interpreter aufbauen, weshalb ein komplexerer Build nötig war
  • Das neue Build-System konnte den Interpreter-Code programmatisch bis zu einem bestimmten Kapitel oder sogar bis zu einer bestimmten Stelle innerhalb eines Kapitels ausgeben, kompilieren und durch automatische Tests laufen lassen
  • Die Python-basierten Werkzeuge waren gemessen an den Fähigkeiten des Autors wartungsintensiv und außerdem langsam
  • Die Dart-Version erzeugte das gewünschte HTML und den Code für Syntaxhervorhebung exakt und war 10-mal schneller als die alte Python-Version
  • Die größere Kontrolle über die Markdown-Verarbeitung erwies sich später auch beim XML-Export für InDesign als nützlich

Buchdesign und Entscheidung für das Format

  • Das Buchdesign ähnelte eher Web- oder Spieleentwicklung: Zuerst wurde ein Framework geschaffen, in das anschließend die Inhalte gegossen wurden
  • In InDesign wurden Master für Seitenränder und Raster sowie Styles für Schriftarten, Stile und Farben von Text und Objekten eingerichtet
  • Crafting Interpreters enthielt viele Elemente mit hohem Design-Schwierigkeitsgrad
    • Sehr viel Fließtext
    • Viele lange Asides, die bestimmte Sätze, Code oder Illustrationen direkt daneben erklären
    • Viel Code, und neben jedem Code-Snippet steht eine Beschreibung seiner Position im Ergebnisprogramm
  • Bei der Seitenbreite mussten lange Codezeilen, der Aside-Bereich und der innere Rand eines dicken Buchs zugleich berücksichtigt werden
  • Die üblichen CS-Lehrbücher im Regal des Autors waren oft 7,5 Zoll breit, doch Code, Asides und Ränder ließen sich darin schwer unterbringen; daher fiel die Entscheidung auf 8 Zoll Breite
  • Beim Self-Publishing musste man die begrenzten Formate verwenden, die KDP und IngramSpark unterstützen; bei 8 Zoll Breite war 8×10 Zoll die sinnvolle Wahl
  • In der Vertikalen wurde der Text an einem klassischen 12-pt-Baseline-Grid ausgerichtet

XML-Pipeline für den Transfer nach InDesign

  • InDesign versteht weder Markdown noch das Build-System des Autors direkt; manuelles Kopieren und Einfügen war daher nicht realistisch
  • InDesign unterstützt XML-Import und die automatische Anwendung von Styles je Tag
  • Allerdings hat die XML-Unterstützung Einschränkungen bei verschachtelten Tags und kann Konstruktionen wie kursiv gesetzte Tags innerhalb von Überschriften – wie in HTML üblich – nicht korrekt verarbeiten
  • Da der Autor das Build-System selbst kontrollierte, schrieb er einen custom XML exporter, der Tags erzeugte, die InDesign gut akzeptieren konnte

InDesign-Automatisierung mit JavaScript und ihre Grenzen

  • Der XML-Import erzeugt in InDesign eine „Story“, also einen durchgehenden Textfluss entlang des Haupttextrahmens
  • Fließtext und Code-Snippets gehören in diesen Hauptfluss, Asides und Location Marker mussten jedoch seitlich herausgezogen werden
  • Beim vorherigen Buch hatte der Autor Asides manuell ausgeschnitten und in neue Textrahmen eingefügt; bei diesem Buch war dieselbe Methode wegen 1.133 Code-Snippets unmöglich
  • InDesign unterstützt JavaScript-Scripting, doch Dokumentation und Debugging-Umgebung waren äußerst dürftig
    • Kein Debugger
    • Keine Stack Traces
    • Kein übliches Debug Print
    • Nur alert() war nutzbar, und bei jedem Aufruf hielt das Skript an
  • Ein JavaScript-Skript fand Asides und Location Marker, entfernte sie aus dem Haupttextfluss und machte daraus separate Textrahmen
  • Die Automatisierung der Positionierung wurde bis zum Schluss nicht vollständig fertig
    • Eine Platzierung über InDesigns Anchor-Funktion und Object Styles wurde versucht, führte aber in einigen Fällen dazu, dass die Rahmen um benachbarte Code-Snippets verschwanden
    • Am Ende mussten einige Location Tags manuell positioniert werden

Redaktion und Copyediting

  • Der gesamte Text wurde in einem Editierdurchlauf noch einmal von Anfang bis Ende gelesen
  • Jedes Kapitel hatte während des Schreibens bereits drei Drafts durchlaufen, doch zur Beurteilung des Gesamtflusses des Buchs wurde es noch einmal geprüft
  • Diese Arbeit dauerte 5 Monate, und die meisten wiederholten Witze wurden überarbeitet
  • Danach wurde die professionelle Copyeditorin Kari Somerton engagiert
  • Der übliche Redaktions-Workflow setzt oft auf Microsoft Word und Track Changes, doch der Autor wollte seinen plaintext- und Git-basierten Workflow beibehalten
  • Kari Somerton arbeitete sich in Git und das maßgeschneiderte Build-System ein, prüfte das gesamte Buch und fand Hunderte Fehler
  • Obwohl es bereits vier Drafts und Hunderte Issues von Lesern gegeben hatte, entdeckte die professionelle Copyeditorin noch viele Probleme

Die Einschränkungen beim Satz von 640 Seiten

  • Nachdem die Worte ausreichend geschliffen waren, wurde der Satz kapitelweise in InDesign erledigt
  • Die Arbeit pro Kapitel wiederholte sich in diesem Ablauf
    • Neue InDesign-Datei erstellen
    • XML exportieren
    • XML in InDesign importieren
    • Asides und Location Marker per JavaScript herausziehen
    • Anchors für Sidebar-Elemente setzen
    • Leerraum am Seitenende anpassen
  • Die ersten fünf Schritte ließen sich pro Kapitel in etwa 30 Minuten erledigen, doch die abschließende Anpassung des Leerraums war am schwierigsten
  • Beim Buchsatz gibt es mehrere vertikale Platzierungszwänge
    • Illustrationen dürfen nicht mitten auf der Seite abgeschnitten werden
    • Asides sind leichter verständlich, wenn sie auf eine Seite passen
    • Auch Code-Snippets sollten möglichst nicht über Seitenumbrüche hinweg zerteilt werden
    • Man sollte vermeiden, dass nur eine Überschrift am Seitenende stehen bleibt
    • Widows and orphans sollte man ebenfalls möglichst vermeiden
  • InDesign verschiebt Inhalte in solchen Situationen auf die nächste Seite, wodurch am Seitenende jedoch große weiße Flächen entstehen
  • Illustrationen und Code-Snippets verhielten sich wie ein miteinander verflochtenes Bin-Packing-Problem; deshalb dauerte der Satz aller Kapitel 2 Monate
  • Um Leerraum zu reduzieren, mussten Code-Snippets geteilt, Abstände um Bilder angepasst oder die Höhe von Illustrationen geändert werden

Illustrationen, Index sowie Vor- und Nachspann

  • Für die Illustrationen wurden druckfreundliche Schwarzweiß-Zeichnungen mit Stift gewählt; beim ersten Scannen wurden sie mit 1200 DPI erfasst
  • Der Export als hochauflösende Bitmaps war einfach, die Platzierung im Seitenlayout jedoch schwierig
  • Da der Text nicht nach dem Muster „siehe Abbildung 123“ funktionierte, sondern direkt auf die Illustration daneben verwies, musste die Illustration in unmittelbarer Nähe stehen
  • Ohne einen professionellen Indexer zu engagieren, ging der Autor 2 Wochen lang noch einmal alle Kapitel durch und erstellte selbst den Index
  • Die Indexfunktion von InDesign konnte ausgewählten Text zu Indexeinträgen machen und den gesamten Index erzeugen, doch das Hinzufügen der Einträge selbst war repetitiv und ermüdend
  • Hinten im Buch stand der Index; vorne kamen Titelseite, Copyright-Seite, Widmung, Danksagung und das von InDesign erzeugte Inhaltsverzeichnis hinzu

Coverdesign

  • Der Autor hielt die künstlerische Qualität des Covers bei technischen Büchern möglicherweise für weniger wichtig als bei Romanen, doch da er nicht in der Lage war, Verkäufe über eine Professorenposition zu erzwingen, investierte er viel Zeit in das Cover
  • Anfangs wollte er ein selbst aufgenommenes Foto für das Cover verwenden, fand aber kein passendes Bild
  • Am Ende entschied er sich für die visuelle Sprache des Buchs: Illustrationen mit Feder und Tusche
  • Die Bergzeichnung zur Erklärung des Kompilierungsprozesses wurde größer und detaillierter neu gezeichnet, und auch die Titelbuchstaben wurden neu in handschriftlicher Anmutung erstellt
  • Für den Titel wurde Acumin Pro Extra Condensed ausgedruckt und von Hand nachgezeichnet, um einen unvollkommenen Eindruck zu erzeugen; dazu wählte er eine Farbpalette, die an vervielfältigte Scout-Handbücher aus den 1950er-Jahren erinnerte

Korrekturabzug und Prüfung von PDF-Änderungen

  • Das PDF wurde bei KDP hochgeladen und ein Korrekturabzug bestellt; eine Woche später traf ein schwerer Karton ein
  • Erst beim Anblick des physischen Buchs wurde die Größe des Projekts nicht mehr als Datendatei, sondern als materieller Gegenstand greifbar
  • Da im Satzprozess viel Handarbeit steckte, las der Autor den Korrekturabzug selbst durch, suchte nach Fehlern und markierte sie mit Sticky Notes
  • Die InDesign-Dateien lagen zwar in einem Git-Repository, waren aber riesige, undurchsichtige Binärdateien, sodass sich Diffs nicht wie bei Quellcode betrachten ließen
  • InDesign verändert Dateien manchmal auch dann, wenn scheinbar keine echte Änderung vorgenommen wurde; dadurch war schwer zu erkennen, was sich tatsächlich geändert hatte
  • Der Autor schrieb ein Dart script, das alle Seiten des Buch-PDFs extrahierte und daraus ein großes PNG-Kachelbild machte
  • Bei jedem Commit wurde ein PDF exportiert und ein Kachelbild erzeugt; eine Photoshop action zeichnete rote Rahmen um die unterschiedlichen Pixel zweier Bilder, um geänderte Seiten zu finden
  • Diese Methode zeigte zwar nicht direkt die Detailänderungen, aber sie zeigte, welche Seiten visuell geprüft werden mussten, und machte nachvollziehbar, ob nur die erwarteten Änderungen enthalten waren

E-Books und Veröffentlichung

  • Nach Abschluss der Korrekturen an der Druckausgabe wurden auch Kindle- und EPUB-E-Books erstellt
  • Das eigene Build-System wurde so angepasst, dass es das von EPUB geforderte ältere XHTML, Metadaten und das Manifest ausgeben konnte
  • Nach einigen Kommandozeilenläufen entstanden Kindle- und EPUB-E-Books, die auf mehreren Readern getestet wurden; dabei wurde das CSS angepasst
  • Nachdem die finalen Dateien bereit waren, wurde die Startseite der Buch-Website aktualisiert, sodass sie zu den Bezugsquellen führte; auch Fotos und responsive Layout wurden bereinigt
  • Erst nachdem Store-Uploads, Website-Update und Benachrichtigung der Mailingliste abgeschlossen waren, war das Buch „wirklich“ fertig

Pläne danach

  • Auch nach dem letzten Kapitel fragten die Leute nach der nächsten Arbeit oder dem Thema des nächsten Buchs
  • Nach sechs Jahren an einem einzigen Projekt wollte der Autor vorerst kein neues Buch planen
  • Während der Pandemie war viel liegen geblieben, und der Plan war, sich erst einmal auszuruhen, ohne festzulegen, was als Nächstes kommt
  • Er nannte Möglichkeiten wie Musikmachen, Angeln, Zeit mit Freunden und Familie oder Arbeit an einem Roguelike-Projekt, wollte aber nicht sofort entscheiden, was er tun würde
  • Irgendwann könnte wieder der Wunsch nach einem großen Projekt entstehen, doch er machte klar, dass er nicht noch einmal sechs Jahre in ein einzelnes Projekt stecken möchte

1 Kommentare

 
GN⁺ 2024-04-29
Meinungen auf Hacker News
  • Auf dieser Seite gibt es sowohl einen Link zum Kauf des Buchs als auch einen Link zur kostenlosen Online-Version: https://craftinginterpreters.com/
    Dieses Buch ist definitiv einen Kauf wert. Allein die Sorgfalt, die Nystrom in das Design des gedruckten Buchs gesteckt hat, reicht für Leute, die Print mögen, völlig aus; dazu kommen handgezeichnete Illustrationen und hervorragende Texte, was es meiner Meinung nach besser macht als 99 % aller technischen Bücher.

  • Eines der besten technischen Bücher, die ich bisher gelesen habe. Die Struktur, bei der in jedem Kapitel schrittweise weiterentwickelter Code und ein lauffähiges Programm übrig bleiben, ist eine erstaunliche Idee, und ich bewundere den Autor dafür, dass er sie tatsächlich umgesetzt hat.
    Da ich früher schon einmal etwas Ähnliches geschrieben hatte, habe ich den Teil zum Tree-Walk-Interpreter eher überflogen; beim C-basierten Bytecode-Interpreter habe ich jedoch viel mehr gelernt.

  • Ich dachte, der Beitrag sei neu und es gebe eine zweite Ausgabe.
    Ich möchte dem Autor gratulieren. Dieses Buch ist nicht nur wegen seiner technischen Tiefe im Bereich Programmiersprachen eine hervorragende Ressource, sondern auch wegen der kleinen Details in Layout und Grafik, die einen beim Lesen bei der Stange halten. Es fühlt sich an wie ein Buch, das lange relevant bleiben wird.

  • 2017 begann ich, Crafting Interpreters zu folgen, und während ich die erste Hälfte des Buchs durcharbeitete, schrieb ich die lox-Implementierung nicht in Java, sondern in Scala. Dabei wurden Tokenizer/Lexer/Parser/Interpreter für mich vollständig entmystifiziert.
    Früher dachte ich, das sei so eine visionäre Domäne, mit der nur eine bestimmte Art von Programmierern umgehen könne, aber ich denke, das lag an Nystroms hervorragendem Schreibstil und seinem tiefen Verständnis des Themas. Den zweiten Interpreter begann ich in Rust zu schreiben, kam wegen des Alltags aber nicht weit und habe ihn auch nie fertiggestellt. Es scheint, als wäre jetzt die Zeit gekommen, wieder dorthin zurückzukehren. Dieser Beitrag ist zwar schon ein paar Jahre alt, aber ich wusste nicht, dass es das Buch als gedruckte Ausgabe gibt; für meine Art zu lernen ist das zwar nicht optimal, aber ich möchte mir ein Exemplar kaufen, um es zu besitzen und den Autor zu unterstützen.

    • Bei mir ist es vielleicht ähnlich. Webbasierte Veröffentlichungen passen besser zu mir, aber ich habe das Buch ebenfalls gekauft, um Bob zu unterstützen.
  • Es gehörte zu den besten Computer-Fachbüchern, die ich bisher gelesen habe. Ich habe es wirklich mit großem Vergnügen gelesen und viel gelernt.
    Neben dem ausgezeichneten technischen Inhalt ist es auch gut geschrieben, unterhaltsam und schön illustriert. Ich halte es für eine monumentale Leistung.

  • Ein hervorragendes Interview, in dem Bob über dieses Buch spricht, und das sich anzuhören lohnt: https://corecursive.com/032-bob-nystrom-on-building-an-inter...

  • Ironischerweise habe ich 15 Monate gebraucht, um das Buch ganz zu lesen :). Ich kann die Situation des Autors sehr gut nachvollziehen. Es ist ein hervorragendes Buch eines gewissenhaften und sehr guten Autors, und ich habe eine starke Bindung zu dem Buch entwickelt, sodass ich auf Basis des Gelernten sogar eine Seite erstellt habe: https://hexmos.com/compiler

  • Ist der Autor vom Grafikdesigner zum Compiler Engineer geworden? Erstaunlich und beeindruckend.

    • Für die Erstellung des druckfertigen PDFs des Buchs dürfte InDesign deutlich schneller sein als LaTeX. Ich hätte mich auch für InDesign entschieden. Ich bin ebenfalls ehemaliger Designer.
  • Dieses Buch steht in meinem Regal. Es wird das nächste Interpreter-Buch sein, das ich nach „Writing an interpreter in Go“ lese, und dieses Buch hat etwa 200 Seiten, was mir wirklich gefällt.

  • Ich habe gerade den Lexer statt in Java in Rust fertiggestellt und freue mich auf den Rest. Bisher ist es ein hervorragendes Buch.