Script

E-book in PDF, EPUB en MOBI maken met Markdown en Pandoc

Samen met Frank Meeuwsen en Oskar van Rijswijk schreef ik het e-book “Lifehacking met Evernote”. Evernote is een digitaal notitieboekje wat je op iedere computer, tablet of smartphone kunt gebruiken. Aan de notities die je maakt kun je bijlagen toevoegen. Bijvoorbeeld documenten, maar ook foto’s die je maakt met de camera van je computer of smartphone en geluidsopnames via de microfoon. Dankzij de synchronisatie tussen al je apparaten heb je je notities in het vervolg altijd doorzoekbaar bij de hand. Met Evernote kun je overal aantekeningen vastleggen en weer terugvinden.

We zijn begonnen met een inventarisatie van wat we wilden vertellen. Daar hebben we een hoofdstukindeling uit gedestilleerd waarna we de hoofdstukken onderling hebben verdeeld. Het grootste deel van het werk is vervolgens met Evernote zelf uitgevoerd. Door per hoofdstuk een tekstbestand aan te maken en dat via Evernote te synchroniseren. Na de review van elkaars teksten bleek het samenvoegen van alle tekstbestanden en afbeeldingen tot een net e-book een dag werk te zijn. Ook bleken sommige tekens zoals aanhalingstekens en quotes problemen op te leveren waardoor we daar steeds rekening mee moesten houden. Dit waren voor mij genoeg redenen om het samenstellen van het boek te automatiseren.

Uiteindelijk hebben we met onderstaande tools gewerkt:

  • Markdown
    Markdown is een opmaaktaal die je gemakkelijk kunt lezen én schrijven. Het idee van bedenker John Gruber is dat je aan platte tekst opmaak mee kunt geven zonder de leesbaarheid van de platte tekst te verstoren.
  • Evernote
    In Evernote zelf hebben we drie notitieboeken gedeeld: een met tientallen notities (een notitie per hoofdstuk), een voor de organisatie met schrijfafspraken, ideeën, input van lezers en to-do’s, en een als collectie van interessante artikelen. In de notities van de hoofdstukken hebben we elkaar ook tips en feedback gegeven.
  • Asana
    Na de lancering van het boek zijn we voor ideeën, to-do’s, tips en feedback overgestapt op Asana. Zo staat alles wat we nog willen doen op één plek en raakt niets ondergesneeuwd in e-mailberichten, tweets of berichten op Google+. In Asana delen we een workspace waarin de taken zijn onderverdeeld in projecten per update of los te benoemen onderdeel.
  • Dropbox
    Bestanden die je in je Dropbox plaatst zijn via internet (“the cloud”) toegankelijk op al je computers. Je kunt de bestanden ook delen met anderen.
  • Pandoc
    Pandoc van John MacFarlane is een zwitsers zakmes om bestanden naar een andere opmaaktaal om te zetten. Bijvoorbeeld van Markdown naar HTML, EPUB, docx (Microsoft Office), MediaWiki of PDF (via LaTeX). Je kunt met Pandoc artikelen of boeken schrijven en slides voor een presentatie genereren. Met Calibre zou je ook een eind moeten komen alleen kreeg ik de afbeeldingen al niet voor elkaar.
  • KindleGen
    Kindlegen is een officiële tool van Amazon om (X)HTML en EPUB-bestanden naar KF8/MOBI te converteren – om te gebruiken op de Kindle. Pandoc converteert niet rechtstreeks naar MOBI dus daar is deze extra tool voor nodig.
  • Script
    Om de tientallen Markdown-bestanden met een druk op de knop binnen 15 seconden om te zetten naar e-books in PDF, EPUB en MOBI heb ik een script geschreven. Geïnspireerd door het principe van Daily Builds van Joel Spolsky. Zo kunnen we snel kleine wijzigingen doorvoeren. Bovendien leveren we het boek een aantal keren op – steeds met extra hoofdstukken – en denken we aan een reeks boeken in de serie “Lifehacking met …”.

In het vorige artikel lichtte ik toe hoe je kunt samenwerken met meerdere auteurs aan een e-book met Markdown en Dropbox, in dit artikel Pandoc en het script. Het steekt wat technisch in elkaar want Pandoc heeft geen interface met knopjes waar je op kunt klikken. Je voert commando’s op een zogenaamde command-line uit – of via een script dus.

Markdown omzetten naar PDF en EPUB met Pandoc

Pandoc hebben we gebruikt om de Markdown bestanden om te zetten naar PDF en EPUB. Pandoc genereert zelf een LaTeX-tussenbestand – om die om te zetten heb je een LaTeX-engine nodig die je kunt installeren in de vorm van TeX Live.

N.B.: Op mijn macOS machine heb ik TeX Live aan het pad toegevoegd met: echo ‘export PATH=/usr/local/texlive/2012/bin/universal-darwin:$PATH’ >> ~/.profile

Pandoc interpreteert Markdown op details anders en heeft de taal uitgebreid. Het meest aansprekende voorbeeld is dat je ook kunt opsommen met romeinse cijfers (i. etc) en letters (a. etc). En dat een numerieke opsomming die begint bij een hoger getal ook echt zo zal worden overgenomen – Markdown zou bij 1 beginnen.

Zie de alinea “Pandoc’s Markdown” in Pandoc’s User Guide voor de details en voorbeelden over hoe je bijvoorbeeld tabellen, tekst doorhalen, sub- en superscript en voetnoten kunt gebruiken.

Als je na het lezen van Pandoc’s User’s Guide en Making an ebook nog vragen over Pandoc hebt dan kun je met vragen over Pandoc terecht op de actieve Google Group pandoc-discuss. Je kunt ook fouten in Pandoc rapporteren (bugs aanmelden). Als je alleen op de hoogte wilt blijven van nieuwe versies van Pandoc, volg dan de Google Group pandoc-announce.

Templates en LaTeX

Pandoc maakt gebruik van templates die de opbouw van het e-book beschrijven. Voor ieder type uitvoer is er een apart template. Met Pandoc genereren wij een EPUB- en PDF-bestand. Wij wilden graag alle uitvoeringen van het boek zoveel mogelijk op elkaar laten lijken.

Voor het EPUB-bestand zijn er drie templates: een voor het coverimage, een voor de titelpagina en een voor een pagina zelf. Verder kun je een CSS-bestand aanpassen. Voor de aanpassingen die wij door wilden voeren hoefden we alleen het .CSS-bestand aan te passen. Om de titels van de hoofdstukken links uit te lijnen in plaats van te centreren: text-align: left; – zie ook de instructie onderaan “Creating an ebook with pandoc”.

Sommige aanpassingen die wij door wilden voeren in EPUB waren helaas niet in templates of CSS door te voeren. Gelukkig vonden we bij de ontwikkelaar een luisterend oor. Als het goed is dan verhuist de inhoudsopgave in een latere versie van de EPUB naar het begin in plaats van in ieder deel van het boek een korte inhoudsopgave.

Voor PDF is het template in de taal LaTeX geschreven. Dit is handig om te weten omdat je het template kunt aanpassen. Voor “Lifehacking met Evernote” hebben ik de volgende LaTeX aangepast/toegevoegd (de tekst achter % is commentaar):

  • Marges instellen
    \usepackage[left=2cm,top=2cm,right=2cm]{geometry} % set margins
    (voor de cover roepen we een apart LaTeX-template aan met overal 0cm marge – en het is een apart bestand: cover.markdown met enkel ![](images/cover.jpg) erin)
  • Hoofdstukken en subhoofdstukken op een nieuwe pagina laten beginnen
    \let\stdsection\section % secties op een nieuwe pagina beginnen
    \renewcommand{\section}{\clearpage\stdsection} % secties op een nieuwe pagina beginnen
    \let\stdsubsection\subsection % subsecties op een nieuwe pagina beginnen
    \renewcommand{\subsection}{\clearpage\stdsubsection} % subsecties op een nieuwe pagina beginnen
  • Regelafstand naar anderhalf
    \usepackage{setspace} % regelafstand naar anderhalf
    \onehalfspacing % regelafstand naar anderhalf
  • Inhoudsopgave limiteren op twee niveaus diep
    $if(numbersections)$
    \setcounter{tocdepth}{2} % show up until 2nd level in table of contents
    \setcounter{secnumdepth}{2} % count up until 2nd level headers
    $else$
    \setcounter{secnumdepth}{0}
    $endif$
  • De pagina afsluiten na de inhoudsopgave (anders begint het eerste hoofdstuk daar direct)
    $endfor$
    $if(toc)$
    {
    \hypersetup{linkcolor=black}
    \tableofcontents
    \newpage % Add a page break after the toc
    }
    $endif$

Een week voor publicatie hebben we het e-book ter review beschikbaar gesteld. Deze versie was voorzien van een watermerk met onderstaande aanpassingen in het template:

  • Watermerk toevoegen (gecentreerd bovenaan de pagina)
    \usepackage{graphicx,eso-pic} % add watermark
    \AddToShipoutPictureBG{% Add picture to background of every page
    \AtPageUpperLeft{%
    \raisebox{-\baselineskip}{\makebox[\paperwidth]{\begin{minipage}{2cm}\centering
    reviewexemplaar
    \end{minipage}}}%
    }
    } % end watermark
  • Watermerk toevoegen dwars over de hele pagina (hebben wij niet voor gekozen)
    \usepackage{draftwatermark} % Place a watermark on all pages (first, bottom, bottomafter are some other available options)
    \SetWatermarkText{REVIEWEXEMPLAAR} % Watermark text
    \SetWatermarkLightness{0.8} % Watermark darkness (higher = lighter)
    \SetWatermarkScale{0.7} % Scale the watermark font size

Helaas had ik ook een klein stukje LaTeX in het Markdown-bestand met het voorwoord nodig om te voorkomen dat deze met hoofdstuknummering mee werd genomen. In plaats van “# Voorwoord” geef ik op onderstaande manier aan dat “Voorwoord” wél als kopje moet worden opgemaakt en voeg ik het vervolgens handmatig toe aan de inhoudsopgave (dezelfde truc is bij de Aanbevelingen in het voorwoord toegepast):

  • Wél in inhoudsopgave maar níet nummeren
    \section*{Voorwoord}
    \addcontentsline{toc}{section}{Voorwoord}

Voor de cover gebruik ik een apart LaTeX-template met overal 0cm marge en zonder pagina/figuurnummering. Het bestand cover.markdown bevat enkel ![](images/cover.jpg):

  • Marges instellen
    \usepackage[left=0cm,top=0cm,right=0cm,nohead,nofoot]{geometry} % discard margins
  • Bijschriften onderdrukken
    \usepackage[labelformat=empty]{caption} % Discard figure
  • Paginanummers onderdrukken
    \thispagestyle{empty} % Discard page number

De LaTeX-code heb ik gevonden via Google door te zoeken op bijvoorbeeld “LaTeX margins”. Er is genoeg documentatie met voorbeelden over te vinden. Bij voorkeur pas je het template niet aan natuurlijk, dat is gemakkelijker en je volgt eventuele verbeteringen van de ontwikkelaar. Nu moeten we daar een extra oogje op houden.

Script voor het automatisch aanmaken van PDF, EPUB en MOBI

Het script boekenbakker.sh (download) is geschreven voor macOS Mountain Lion (verander de extensie voor gebruik naar .sh). Om het om te schrijven naar Windows moet je wat anders omgaan met de variabelen en datum – en vervang je rm door del.

Het script begint met wat formaliteiten om ervoor te zorgen dat de bestanden op de juiste plek worden aangemaakt en gezocht. Vervolgens definieer ik variabelen voor de titel van het boek en de auteursnamen om te voorkomen dat ik die steeds opnieuw moet typen – ze zijn vaker nodig. In een volgende stap genereer ik de boeken in PDF en EPUB met pandoc en voeg ik wat PDF-bestanden samen of splits ze. Daarna converteer ik de EPUB naar MOBI met KindleGen. De boeken zip ik zodat ze straks in één keer kunnen worden gedownload via de website. Aan het einde van het script ruim ik de (eventueel) aangemaakte bestanden op.

Script

Hieronder licht ik een paar onderdelen van het script wat verder toe.

Create title.txt for the title page

Pandoc gebruikt de gegevens uit het bestand title.txt om de titelpagina te maken. Op de titelpagina staat de titel van het boek, de auteurs en de datum van publicatie.

Het script genereert title.txt in de hoofdmap in plaats van de submap eBooks omdat Pandoc de afbeeldingen zoekt in de submap relatief van title.txt.

Create metadata.xml for ePub (and mobi)

Voor het meegeven van eigenschappen aan het EPUB-bestand (taal, publicatiedatum, uitgever, titel, onderwerp, omschrijving en auteurs) maakt het script een bestand metadata.xml met Dublin Core elementen aan. De titel en auteursnamen worden opnieuw gebruikt en de datum wordt in het gevraagde formaat opgeleverd.

Pandoc-commando’s

Pandoc heeft veel parameters waarmee je aangeeft welk(e) bestand(en) je wilt converteren – en waar naartoe.

Helaas heeft Pandoc voor PDF geen coverimage-parameter. Daarom converteer ik een speciaal voor de cover gemaakt Markdown-bestand met een template met 0cm marge naar PDF.

In het script kun je zien dat ik voor de PDF het lettertype Georgia meegeef. Hiervoor hebben we gekozen op basis van een advies van Typofile Magazine: “Both Georgia and Verdana are carefully spaced so that the characters never touch, and this helps make them especially readable.”. Door mee te geven dat de taal van het document Nederlands is (–variable lang=”dutch”) worden woorden aan het einde van een regel goed afgebroken en woorden als “Contents” en “Figure” vertaald naar “Inhoudsopgave” en “Figuur”. Ook geef ik mee dat ik gebruik wil maken van een inhoudsopgave, nummering en een template.

Voor het EPUB-bestand geef ik het bestand met de metadata mee, plus het coverimage. Het resulterende bestand doorstaat de EPUB Validator van het International Digital Publishing Forum. Als er kleine foutjes worden gevonden dan staat er waarschijnlijk iets niet goed in Markdown. Door het .epub bestand te hernoemen naar .zip kun je het .xhtml-bestand waar de EPUB Validator naar verwijst onderzoeken om te vinden waar het mis gaat.

De sed-commando’s voor het pandoc-commando voor EPUB vervangen de LaTeX-code in de Markdown-bestanden voor Voorwoord en Aanbevelingen (zoals eerder omschreven) weer naar Markdown. In EPUB zie je anders een lege regel in de inhoudsopgave. De sed-commando’s vervangen Markdown dan weer door LaTeX voor de volgende keer dat het script gedraaid zal worden. Voor Windows zijn er scripts of andere tools om te zoeken en vervangen.

Je kunt alle mogelijke parameters terugvinden in Pandoc’s User’s Guide.

PDF samenvoegen en splitsen met Pdftk

Met pdftk kun je PDF-bestanden samenvoegen, splitsen, pagina’s draaien etc. Pdftk is ook te downloaden voor Windows.

In het script voeg ik met pdftk de PDF met cover samen met de rest van het boek. Vervolgens splits ik de eerste paar pagina’s van het document zodat we de inhoudsopgave van het e-book los kunnen verspreiden.

Comprimeren en e-books samenvoegen met zip

Het zip-commando zipt de PDF, EPUB en MOBI tesamen met een readme.txt bestand voor plaatsing op de website. Zip is standaard aanwezig op macOS, in Windows moet je even op zoek naar een command-line variant of zipscript.

De parameter –junk-paths zorgt ervoor dat de bestanden in de hoofdmap van het zip-bestand staan. Standaard zipt het mapje “eBooks” mee.

Script laten uitvoeren door andere auteurs

Het leek mij praktisch als andere auteurs het script ook uit kunnen voeren zonder dat ik iets hoef te doen. Op kritische momenten zorg ik dat mijn werkstation aan staat. Als er een bestand met de naam “bakken” in de gedeelde Dropbox-map verschijnt dan start het script “boekenbakker” automatisch.

In macOS kun je eenvoudig een script uitvoeren als er iets in een map gebeurt. Start Automator en kies voor Folder Action. Met onderstaand screenshot waarin ik trigger op een bestand met de naam “bakken” en dan als actie het eerder aangemaakte script uitvoer zou je eruit moeten kunnen komen.

macOS Automator Folder Action

In Windows zit deze functionaliteit standaard niet maar kun je aan de slag met WMI Events of software van derden.

Geef een reactie

Je reactie verschijnt pas na goedkeuring. Je e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *