Say you want to write your very own software or coding book. The first option to proceed is, of course, a text processor like LibreOffice Writer. Don’t use that; that’s not hacky enough for you. You may use instead use a more complex toolchain, like LaTeX. If you are as lazy as me, you probably don’t want to learn how to layout a book using LaTeX. So… what’s left?

Here’s the best and easiest way: use Markdown. Of course, it’s not as powerful as LaTeX, but it’s fast, easy and lightweight.

Where do we start?

If you don’t know Markdown, I recommend you to read this tutorial. Since we’re not serving the book as is (some scattered .md files) we need something to transform those source .md files into a convenient format like .pdf or .pub. Please, greet your new friend Pandoc.

Installing

Please, check this page for more information. On ubuntu, it can be installed as the pandoc package:

sudo apt-get install pandoc

Easy peasy lemon squeezy.

Also, we’ll be using make to build the output files, so don’t forget to install it too:

sudo apt-get install make

Folder structure

Before creating scattered files like a maniac, let’s create a folder tree structure to keep files organized. For example:

my-book/         # Root directory.
|- build/        # Folder used to store builded (output) files.
|- chapters/     # Markdowns files; one for each chapter.
|- images/       # Images folder.
|  |- cover.png  # Cover page for epub.
|- metadata.yml  # Metadata content (title, author...).
|- Makefile      # Makefile used for building our books.

Simple, isn’t it? Don’t worry about the files’ content; I’ll explain each file on the following sections.

You can find the template used on this post in this GitHub repository.

Setup generic data

First, we need a title and an author, don’t we? That’s the purpose of metadata.yml. Here’s a example:

---
title: My book title
author: Daniel Herzog
rights:  Creative Commons Attribution 4.0 International
language: en-US
tags: [book, my-book, etc]
abstract: |
  Your summary text.
---

You get the idea, right? You can find the list of all available keys on this page.

Creating chapters

Creating a new chapter is as simple as creating a new markdown file in the chapters/ folder; you’ll end up with something like this:

chapters/01-introduction.md
chapters/02-installation.md
chapters/03-usage.md
chapters/04-references.md

Pandoc and Make will join them automatically ordered by name; that’s why the numeric prefixes are being used.

All you need to specify for each chapter is at least a title:

# Introduction

This is the first paragraph of the introduction chapter.

## First

This is the first subsection.

## Second

This is the second subsection.

Each title (#) will represent a chapter, while each subtitle (##) will represent a chapter’s section. You can use as many levels of sections as markdown supports (I guess the limit is 5 or 6).

Imagine you want to reference a chapter from another; when the link is clicked, it will redirect you to that section. It can be achieved with anchor links:

// chapters/01-introduction.md
# Introduction

For more information, check the [Usage] chapter.

// chapters/02-installation.md
# Usage

...

Just use the chapter’s title name. If you want to rename the reference, use this syntax:

For more information, check [this](#usage) chapter.

Anchor names should be downcased, and spaces, colons, semicolons… should be replaced with hyphens. Instead of Chapter title: A new era, you have: #chapter-title-a-new-era.

It’s the same as chapters’ links:

# Introduction

## First

For more information, check the [Second] section.

## Second

...

Or, renamed:

For more information, check [this](#second) section.

Same rules apply here as above.

Inserting objects

Text. That’s cool. What about images and tables?

Insert an image

Use Markdown syntax to insert an image with a caption:

![A cool seagull.](images/seagull.png)

Pandoc will automatically convert the image into a figure (image + caption).

If you want to resize the image, you may use this syntax, available in Pando 1.16:

![A cool seagull.](images/seagull.png){ width=50% height=50% }

Also, to reference an image, use LaTeX labels:

Please, admire the gloriousnes of Figure \ref{seagull_image}.

![A cool seagull.\label{seagull_image}](images/seagull.png)

Insert a table

Just insert a Markdown table, and use the Table: Your table description syntax to add a caption:

| Index | Name |
| ----- | ---- |
| 0     | AAA  |
| 1     | BBB  |
| ...   | ...  |

Table: This is an example table.

If you want to reference a table, use LaTeX labels:

Please, check Table /ref{example_table}.

| Index | Name |
| ----- | ---- |
| 0     | AAA  |
| 1     | BBB  |
| ...   | ...  |

Table: This is an example table.\label{example_table}

Insert an equation

Wrap a LaTeX math equation between $ delimiters for inline (tiny) formulas:

This, $\mu = \sum_{i=0}^{N} \frac{x_i}{N}$, the mean equation, ...

Pandoc will transform them automatically into images using online services.

If you want to center the equation instead of inlining it, use double $$ delimiters:

$$\mu = \sum_{i=0}^{N} \frac{x_i}{N}$$

Here’s an online equation editor.

Output

We’ll be using a Makefile to automatize the building process. Instead of using the pandoc cli util, we’re going to use some make commands. The Makefile looks like this:

BUILD = build
OUTPUT_FILENAME = book
METADATA = metadata.yml
CHAPTERS = chapters/*.md
TOC = --toc --toc-depth=2
COVER_IMAGE = images/cover.png
LATEX_CLASS = report
MATH_FORMULAS = --webtex

all: book

book: epub html pdf

clean:
	rm -r $(BUILD)

epub: $(BUILD)/epub/$(OUTPUT_FILENAME).epub

html: $(BUILD)/html/$(OUTPUT_FILENAME).html

pdf: $(BUILD)/pdf/$(OUTPUT_FILENAME).pdf

$(BUILD)/epub/$(OUTPUT_FILENAME).epub: $(METADATA) $(CHAPTERS)
	mkdir -p $(BUILD)/epub
	pandoc $(TOC) -S $(MATH_FORMULAS) --epub-metadata=$(METADATA) --epub-cover-image=$(COVER_IMAGE) -o $@ $^

$(BUILD)/html/$(OUTPUT_FILENAME).html: $(CHAPTERS)
	mkdir -p $(BUILD)/html
	pandoc $(TOC) $(MATH_FORMULAS) --standalone --to=html5 -o $@ $^

$(BUILD)/pdf/$(OUTPUT_FILENAME).pdf: $(METADATA) $(CHAPTERS)
	mkdir -p $(BUILD)/pdf
	pandoc $(TOC) $(MATH_FORMULAS) -V documentclass=$(LATEX_CLASS) -o $@ $^

Don’t worry! If you’re not familiarized with make, you don’t need to actually understand how that works.

Export to PDF

Use this command:

make pdf

The generated file will be placed in build/pdf.

Please, note that PDF file generation requires some extra dependencies (~ 800 MB):

sudo apt-get install texlive-latex-base texlive-fonts-recommended texlive-latex-extra 

Export to EPUB

Use this command:

make epub

The generated file will be placed in build/epub.

Export to HTML

Use this command:

make html

The generated file(s) will be placed in build/html.

Extra configuration

If you want to configure the output, you’ll probably have to look the Pandoc Manual for further information about pdf (LaTeX) generation, custom styles, etc.

References

Happy coding!