Omfg books have tech stacks now: how I used web technologies to layout and print a book
Tags: react, books, html, css
Published: 2019-08-10 12:41:09

Sorry for the title, I just had to quote Kitze here:

{% twitter 1151731672582434821 %}

A few months ago, in April 2019, I published a [book about React](https://buch.react-js.dev). It's a technical book. And by saying that, I mean it's a technical book in a number of ways. Sure, the content is all about React, how React works, how you build components and applications with React. In that way, it's a technical book like any other.

The more interesting aspect is the second way in which it is a technical book: namely, the way it is **produced**.

## The writing phase

I used an early version of the great new version of [gitbook.io](https://www.gitbook.io) because it's meant to be used for technical articles and texts, like documentation or ... books. At least that's what you might think when you take a look at their name.

Well, as it turned out, although it's indeed great for writing comprehensive documentation in a very nice and easy way, it's not really intended to be use to write actual books. By the time I was writing the book, there wasn't even a way to export your Gitbook as PDF or any other format like ePub (and I'm not even sure there is an official way today). What they instead do is to publish a beautifully designed HTML version which is stored entirely on GitHub as Markdown files with a few custom enhancements.

I didn't know how difficult it is to turn your Gitbook into an actual book until I wrote ~120 pages and neither did I want to go back to Google Docs or Word for writing as it's still a technical book with a lot of code examples and they really don't look great in Word docs.

## The fun part

So I did what developers do when they have other more important things to do: I procrastinated and built my own toolset and tech stack around my book.

I cloned the [GitHub repo of my book](https://github.com/manuelbieh/react-lernen). I installed [Showdown](http://showdownjs.com/) and the Showdown Highlight plugin to convert the Markdown source files into HTML, with beautifully styled code examples. I even used [Prettier](https://prettier.io/) to automatically format the code examples within code blocks! I then combined all converted files into one giant HTML file.

I then added [Puppeteer](https://github.com/GoogleChrome/puppeteer) to the stack. This allowed me to to convert the Markdown files I converted into HTML earlier into a PDF very easily. Since I used HTML as source format for conversion, I was able to use CSS to _style_ the whole book! Puppeteer is really great at converting HTML files into PDF with a fairly good support for CSS Print features (well, sometimes more, sometimes less good). This way I was able to layout and style the PDF (which I later sent to the print shop!) pretty much exactly how I liked it.

For the ePub version I decided to use the fantastic [Pandoc](https://pandoc.org/). Pandoc allows you to convert many different text based formats (Docx, HTML, Markdown, ...) into other formats like ePub. Writing CSS for ePub feels a little bit like building email templates. That's really something you don't want to customize too much because you have no guarantee that your ePub will look exactly how you want it to look in every client. So I only used as little custom CSS as necessary.

## Hacks and caveats

The whole process was a bit tricky and required a few hacks (as always, huh?) and it also comes with a few caveats. For example I'm unable to add page numbers to the TOC in the PDF, because by the time I am generating the TOC, I don't know the page numbers, as they will be automatically added by Puppeteer later in the final PDF conversion step.

The CSS [`orphans`](https://developer.mozilla.org/en-US/docs/Web/CSS/orphans) and [`widows`](https://developer.mozilla.org/en-US/docs/Web/CSS/widows) properties also seem to not work properly or at least not how I would have expected them to work. And my impression is that [`break-*`](https://developer.mozilla.org/en-US/docs/Web/CSS/break-after) properties also cause some unexpected behavior sometimes. Not beautiful, but neglectible for me.

In general though, I am really happy about the result: a book, written in my web browser, stored as Markdown on GitHub and converted into a real printed book completely based on web technologies!

The code is still a bit hacky, I never really cleaned it up, but if you're interested in reproducing it, or even want to convert your own Gitbook into a nicely styled PDF, you can find the code on GitHub: https://github.com/manuelbieh/gitbook-pdf-converter

Here's a small impression how the result looks like in the end:
![](https://thepracticaldev.s3.amazonaws.com/i/tmuyyk1dc9yb8g08irx8.jpg)