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
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).
Links between chapters
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
.
Links between sections
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!