# How to Generate EPUB and PDF Books from Lesson Sources Using `build_book.py`

> Generate EPUB and PDF books from markdown lessons with build_book.py. This script from ai-engineering-from-scratch compiles content into professional e-book formats.

- Repository: [Rohit Ghumare/ai-engineering-from-scratch](https://github.com/rohitg00/ai-engineering-from-scratch)
- Tags: how-to-guide
- Published: 2026-08-31

---

**The [`build_book.py`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/build_book.py) script in the `rohitg00/ai-engineering-from-scratch` repository compiles modular markdown lessons from `phases/` and `certifications/` directories into professionally formatted EPUB and PDF e-books using Jinja2 templates, `ebooklib`, and `weasyprint`.**

The `ai-engineering-from-scratch` curriculum is designed as a collection of discrete markdown lessons, but is distributed as cohesive e-book files. This transformation is handled by [`scripts/build_book.py`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/scripts/build_book.py), a Python utility that orchestrates the conversion pipeline from source markdown to publication-ready formats through its `main()` entry point. Understanding this build system allows you to regenerate course materials whenever content is updated or create custom subsets of the curriculum.

## The Build Pipeline Architecture

The script executes a six-stage pipeline to convert raw lesson files into distributable e-books. Each stage handles a specific transformation, ensuring that the final `book.epub` and `book.pdf` files maintain consistent styling and navigation.

### Stage 1: Source Discovery

According to the source code in [`scripts/build_book.py`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/scripts/build_book.py), the build process begins by scanning the repository's structured content directories. The script recursively walks through `phases/` and `certifications/` directories, locating lesson definitions in [`docs/en.md`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/docs/en.md) files. This discovery phase respects the repository's organizational convention where each learning module resides in its own subdirectory with standardized documentation paths.

### Stage 2: Markdown Rendering

Once collected, the raw markdown content is converted to HTML using Python's `markdown` library. The [`build_book.py`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/build_book.py) implementation processes each [`docs/en.md`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/docs/en.md) file with extensions for table of contents generation and fenced code blocks, preserving the front-matter metadata (such as title, type, and supported languages) while converting the instructional content to semantic HTML suitable for book formatting.

### Stage 3: Template Application

The rendered HTML is then injected into a Jinja2 template located at [`scripts/templates/book.html`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/scripts/templates/book.html). This template defines the book's structural elements including the cover page, table of contents hierarchy, and chapter layouts. The [`build_book.py`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/build_book.py) script passes lesson-specific variables—such as `chapter_title` and `body` content—to the Jinja2 `Environment`, which produces a complete HTML document ready for multi-format export.

### Stage 4: EPUB Assembly

For EPUB generation, the script utilizes the `ebooklib` library to create a standards-compliant EPUB container. The implementation in [`scripts/build_book.py`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/scripts/build_book.py) constructs an `epub.EpubBook` instance, sets identifiers and metadata using methods like `book.set_identifier("ai-engineering")` and `book.set_title("AI Engineering from Scratch")`, bundles CSS stylesheets, and writes the final archive to `outputs/book.epub`.

### Stage 5: PDF Conversion

Simultaneously, the same rendered HTML is processed by `weasyprint` to generate paginated PDF output. The `HTML(string=full_html).write_pdf()` method creates `outputs/book.pdf` with styling that matches the EPUB version, ensuring visual consistency across both digital and print-ready formats.

## Command-Line Usage

The [`build_book.py`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/build_book.py) script provides a flexible CLI for customizing the build process without modifying source code. You can invoke the script from the repository root to generate both formats or specific subsets of the curriculum.

### Basic Execution

To generate the complete book with all phases and certifications, run:

```bash
python -m scripts.build_book \
    --output-dir outputs

```

This command processes all available lesson sources and writes `book.epub` and `book.pdf` to the specified `outputs/` directory.

### Filtering Content and Formats

For targeted builds, the script accepts several key arguments:

- **`--include-phases`** – Comma-separated phase numbers (e.g., `01-05`) to restrict content to specific curriculum stages
- **`--include-certifications`** – Specific certification tracks (e.g., `claude`) to append to the build
- **`--no-epub`** – Boolean flag to skip EPUB generation and produce only PDF
- **`--no-pdf`** – Boolean flag to skip PDF generation and produce only EPUB

### Example: Custom Curriculum Build

```bash
python -m scripts.build_book \
    --output-dir outputs \
    --include-phases 01-15 \
    --include-certifications claude \
    --no-pdf

```

This invocation generates only an EPUB containing phases 1 through 15 plus the Claude certification track, excluding the PDF output.

## Internal Implementation Deep Dive

The core logic inside [`scripts/build_book.py`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/scripts/build_book.py) follows this programmatic pattern. While you typically interact with the CLI, understanding the internal API helps when extending the build system:

```python
from markdown import markdown
from jinja2 import Environment, FileSystemLoader
from ebooklib import epub
from weasyprint import HTML
from pathlib import Path

# 1. Load lesson markdown

md_text = Path("phases/01-math-foundations/01-text-processing/docs/en.md").read_text()
html_body = markdown(md_text, extensions=["toc", "fenced_code"])

# 2. Render with Jinja2 template

env = Environment(loader=FileSystemLoader("scripts/templates"))
template = env.get_template("book.html")
full_html = template.render(chapter_title="Text Processing", body=html_body)

# 3. Build EPUB

book = epub.EpubBook()
book.set_identifier("ai-engineering")
book.set_title("AI Engineering from Scratch")
book.add_item(epub.EpubHtml(content=full_html, file_name="chapter1.html"))
epub.write_epub("outputs/book.epub", book)

# 4. Build PDF

HTML(string=full_html).write_pdf("outputs/book.pdf")

```

## Required Dependencies

The build system requires three key Python packages installed in your environment:

- **`markdown`** – Parses lesson markdown into HTML with TOC and code block support
- **`ebooklib`** – Constructs the EPUB container and handles metadata
- **`weasyprint`** – Converts HTML/CSS to PDF with proper pagination
- **`jinja2`** – Powers the template rendering engine

Install these via pip before running the build script:

```bash
pip install markdown ebooklib weasyprint jinja2

```

## Summary

- **[`scripts/build_book.py`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/scripts/build_book.py)** serves as the central orchestrator for converting the `ai-engineering-from-scratch` curriculum from modular markdown into unified e-books
- The build pipeline stages include source discovery from `phases/` and `certifications/`, markdown-to-HTML conversion via the `markdown` library, Jinja2 templating using [`scripts/templates/book.html`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/scripts/templates/book.html), and parallel generation of EPUB (via `ebooklib`) and PDF (via `weasyprint`) formats
- Output files are written to the `outputs/` directory as `book.epub` and `book.pdf`
- Command-line flags allow filtering by phase numbers (`--include-phases`) and certification tracks (`--include-certifications`), with options to disable specific output formats using `--no-epub` or `--no-pdf`

## Frequently Asked Questions

### How do I add new lessons to the book generation process?

Place your new lesson content in a subdirectory under `phases/` or `certifications/` following the existing structure: create a `docs/` folder containing an [`en.md`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/en.md) file with your markdown content. The [`build_book.py`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/build_book.py) script automatically discovers these files during the source collection phase, requiring no changes to the build configuration.

### Can I generate only the PDF or only the EPUB format?

Yes. Pass the `--no-epub` flag to skip EPUB generation and produce only the PDF, or use `--no-pdf` to generate only the EPUB file. These boolean flags allow you to reduce build time when you need only one output format.

### What template engine does the build script use?

The build system uses **Jinja2** for HTML template rendering. The main template lives at [`scripts/templates/book.html`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/scripts/templates/book.html) and receives variables including `chapter_title` and `body` (the HTML-rendered markdown content). You can customize the book's visual layout by modifying this template and the associated CSS styles referenced during the EPUB and PDF generation phases.

### Where are the generated book files saved?

By default, the script writes `book.epub` and `book.pdf` to the `outputs/` directory relative to the repository root. You can specify a different destination using the `--output-dir` command-line argument followed by your preferred path.