Our website is made possible by displaying online advertisements to our visitors. Please consider supporting us by disabling your ad blocker.

Creating an eBook with Pandoc and Markdown

TwitterFacebookRedditLinkedInHacker News

You might already be aware of this, but I’ve accomplished a life achievement of writing and self-publishing two technical eBooks. I published Web Services for the JavaScript Developer, followed by Web Services for the Go Developer, which contain the same concepts using two different programming technologies.

If you’ve ever thought about writing an eBook, you’ve probably opened tools like Apple Pages or Microsoft Word and said to yourself, formatting this is going to be a nightmare. Technical content will, more often than not, contain code, which may have sophisticated formatting. Writing a programming eBook or another technical eBook doesn’t have to be a hassle when you’re using the right tooling.

In this tutorial, we’re going to explore Pandoc, and see how you can write a book quickly and easily with Markdown.

I’m going to assume that you’ve heard of Markdown and have at least a little hands on experience, but if you haven’t, check out a previous tutorial I had written on the subject. It has a very smooth syntax that makes it great for any kind of technical writing, whether that be documentation, blogging, or eBooks.

The first step for writing an eBook with Pandoc is to install Pandoc. If you’re using using macOS and have Homebrew installed, you can execute the following:

brew install pandoc

If you’re using Windows and have Chocolatey installed, you can execute the following:

choco install pandoc

If you’re using Linux, the process is a little more involved, which means you should probably check out the Pandoc documentation on the subject.

The whole premise behind Pandoc is that you can provide it a file in one format and export it to another format. This isn’t limited to Markdown, but I’ve found Markdown as the source file to work best.

So let’s look at a potential project structure (what mine looks like), when writing an eBook:

src
    chapter00.md
    chapter01.md
    chapterXX.md
metadata.txt
cover.png

The above is an example of how you could do things. Essentially, you have a directory with all of your source files, a cover image to represent the cover of your book, and a template to represent author information, cover information, ect..

When we try to build the eBook, in theory we’d have it export to a dist directory or something else.

Let’s take a closer look at the metadata.txt file in our project. Yours, for example, might look like the following:

---
title: Web Services for the Go Developer
author: Nic Raboy
lang: en-US
cover-image: cover.png
---

The cover-image property is a path to the cover image file. This means the above example assumes that when it is build time, the command line is in the same working directory as the cover.png file.

Let’s assume that each of the Markdown files in our src directory has some kind of content. We could execute the following from the root of our project:

pandoc -o dist/book.epub metadata.txt src/*.md --table-of-contents

The above command would export a book.epub file to the dist directory, which may or may not exist. In case you’re new to publishing, EPUB is a common output file for books. In the rest of the command, we are specifying the file with our meta data, our Markdown files, and defining that we want a table of contents to be created.

Notice that we’re using an asterisk with our Markdown. We’re saying that we want all Markdown files in our src directory to be included in our build. When we do this, the Markdown files are built in alphabetical order, which makes the naming convention particularly important. If we didn’t want to have a naming convention, we could list each of the Markdown files, in order, for building, rather than using a wildcard.

The table of contents is created as the first page of the eBook based on the heading syntax used within each of the Markdown files. This means that every h1 tag and similar would show up in the table of contents.

Alright, so let’s say that that you’ve exported your book from Markdown. If this is a technical book, you’ll probably not like the way it is formatted. This is because Pandoc doesn’t necessarily know how to format your content as it is converted from Markdown to something else. It will follow basic rules, but nothing more.

This is where CSS comes into play.

At the root of your project, create a styles.css file with the following style information:

html {
    font-size: 100%;
    -webkit-text-size-adjust: 100%;
    -ms-text-size-adjust: 100%;
}

body {
    font-family: "Helvetica Neue", Helvetica, Arial, "Lucida Grande", serif;
    margin: auto;
    text-align: justify;
    font-size: 16px;
    line-height: 1.7;
}

h1 { text-align: left; }
h2 { text-align: left; }
h3 { text-align: left; }
h4 { text-align: left; }
h5 { text-align: left; }
h6 { text-align: left; }

h1.title {
    margin-top: 0;
    text-align: center;
}

p.author {
    text-align: center;
}

ol.toc {
    padding: 0;
    margin: 1em 0;
    padding: 0 0 0 2em;
}

ul.toc ul, ol.toc ol {
    margin: .3em 0;
}

li { margin: 0; padding: 0 5px; }

code {
    font-family: monospace;
    background-color: rgb(247, 247, 247);
}

pre {
    font-family: monospace;;
    padding: 16px;
    overflow: auto;
    font-size: 80%;
    line-height: 1.45;
    border-radius: 3px;
    background-color: rgb(247, 247, 247);
}

The above CSS is what I used in my two eBooks. When it comes to how your book looks, you’re in full control via CSS, just like you’d be when it comes to a website.

To make use of the CSS information in your build, you can change the build command to the following:

pandoc -o dist/book.epub metadata.txt *.md --css styles.css --table-of-contents

There are quite a few other options that you can use when it comes to building your eBook, but for the most part, the above files and structure information should be sufficient.

Conclusion

When I first tried to write an eBook, I went down the path of trying to use Apple Pages. While standard document applications are great for non-technical books, having to worry about code formatting and similar is a real pain. Instead, if you’re a fan of Markdown like I am, you can use Pandoc to easily convert your writing to a publishing format.

Pandoc isn’t restricted to accepting Markdown and it isn’t restricted to outputting only EPUB formatted files. The software is quite rich in functionality and has proven to be quite useful beyond eBooks. For example, I like to write my blog posts in Markdown, but not every CMS accepts Markdown. Instead, I can output my Markdown to HTML and it will work fine.

Nic Raboy

Nic Raboy

Nic Raboy is an advocate of modern web and mobile development technologies. He has experience in C#, JavaScript, Golang and a variety of frameworks such as Angular, NativeScript, and Unity. Nic writes about his development experiences related to making web and mobile development easier to understand.