How to Build the Curriculum Book Series Using `scripts/build_book.py`

The scripts/build_book.py script in the rohitg00/ai-engineering-from-scratch repository orchestrates the compilation of markdown lessons into professional EPUB and PDF books by processing volume definitions from book/volumes.json and invoking Pandoc.

This guide explains how to build the curriculum book series using scripts/build_book.py, covering the complete pipeline from lesson discovery to final artifact generation. The script automates the assembly of phase-based lesson content, handles multilingual translations, and produces both digital and print-ready formats.

Prerequisites and Environment Setup

Before executing the build script, ensure your environment meets the tooling requirements. The script depends on external binaries for document conversion.

Pandoc is mandatory for all build operations. The script calls Pandoc directly to convert assembled markdown into EPUB format at scripts/build_book.py lines 129–138.

For PDF generation, you must install a LaTeX distribution providing xelatex, as the script uses XeLaTeX engines to render PDFs with Unicode and custom font support (lines 147–176). The script also requires fc-list (fontconfig) for the pick_font() function to detect system-installed fonts.

Optionally, install the Mermaid CLI (mmdc) to render ```mermaid ` blocks into embedded SVG diagrams rather than placeholder boxes.

Understanding the Build Pipeline

The build process consists of six distinct phases orchestrated by the main execution block. Each phase is implemented as a specific function in scripts/build_book.py.

  1. Argument Parsing – Processes --volume, --pdf, --assemble-only, and --lang flags to set the BOOK_LANG environment and target volume (lines 19–28).
  2. Phase Validation – The check_phases() function verifies that every phase listed in a volume definition exists in the filesystem and contains valid lesson content (lines 107–116).
  3. Markdown Assembly – The assemble(vol) function walks each phase, reads lesson files (prioritizing i18n/<lang>/ translations over docs/en.md), rewrites asset paths, and concatenates content into a single markdown file (core loop at lines 93–100).
  4. Metadata Generation – The metadata(vol) function writes a YAML front-matter file containing the book title, author, and series information for Pandoc consumption.
  5. Rendering – The render(vol, md, chapters, pdf) function executes Pandoc commands to generate EPUBs and optionally PDFs using the book/titlepage.tex LaTeX template.
  6. Output – Final artifacts are written to dist/book/ with naming convention aiefs-vol<NUM>-<slug>.epub and .pdf.

Configuration and Volume Definitions

The script relies on book/volumes.json to determine which phases comprise each volume. This JSON file maps volume slugs to their respective lesson phases.

{
  "volumes": [
    {
      "slug": "fundamentals",
      "number": 1,
      "title": "AI Engineering Fundamentals",
      "phases": ["phase-01-intro", "phase-02-basics"]
    }
  ]
}

The script reads this configuration at startup via CONFIG = json.loads((ROOT / "book" / "volumes.json").read_text(...)). The lesson_dirs(phase) function then discovers individual lessons within each phase directory using the LESSON_DIR_RE regex pattern, ensuring only directories containing docs/en.md (or translated equivalents) are included.

Assembling Lesson Content

During the assembly phase, the script performs several content transformations to ensure offline usability:

  • Asset Path Rewriting – Updates image references to point to the repository’s assets folder.
  • Interactive Enhancement Injection – Replaces special fenced blocks like ```figure and ```mermaid with "continue-online" boxes that link readers to the live web edition at SITE.
  • Mermaid Rendering – If mmdc is available, Mermaid diagrams are pre-rendered to SVG and embedded directly; otherwise, placeholder boxes are inserted.

The assemble() function handles language selection by checking for the existence of i18n/<BOOK_LANG>/phases/<phase>/<lesson>/docs/<lang>.md before falling back to the English source. This allows the script to build localized versions of the curriculum when translations exist.

Command-Line Usage

Build operations are controlled via command-line arguments processed by argparse in the script’s main block.

Build all volumes (EPUB only):

python3 scripts/build_book.py

Build a specific volume by slug:

python3 scripts/build_book.py --volume fundamentals

Build with PDF output (left-to-right languages only):

python3 scripts/build_book.py --volume fundamentals --pdf

Assemble markdown without rendering:

python3 scripts/build_book.py --assemble-only

Build in a specific language:

python3 scripts/build_book.py --lang es --volume fundamentals

The --lang flag sets the BOOK_LANG variable, directing the script to prefer content from i18n/<lang>/ paths when available.

Output Artifacts and File Structure

After successful execution, the script produces files in three locations:

  • Assembled Markdown: book/_build/<volume>.md – The concatenated, transformed markdown source used as Pandoc input.
  • EPUB Files: dist/book/aiefs-vol<NUM>-<slug>.epub – The primary e-book format.
  • PDF Files: dist/book/aiefs-vol<NUM>-<slug>.pdf – Generated only when --pdf is specified and the language supports left-to-right rendering.

The script creates the dist/book/ directory automatically (lines 38–45) if it does not exist.

PDF Generation and Font Handling

When --pdf is requested, the script performs additional font detection via pick_font(). This function queries system fonts using fc-list to select appropriate serif, monospaced, or CJK typefaces based on the target language. The selected fonts are passed to the xelatex command via the book/titlepage.tex template, which handles the title page layout with edition numbers and chapter counts.

PDF generation is explicitly skipped for right-to-left languages or when xelatex is unavailable, ensuring the build process fails gracefully.

Summary

  • scripts/build_book.py automates the entire book-building pipeline for the AI Engineering from Scratch curriculum.
  • Configuration is defined in book/volumes.json, mapping volumes to specific lesson phases.
  • The script supports multilingual builds via the --lang flag and i18n/ directory structure.
  • Pandoc is required for EPUB generation; XeLaTeX and system fonts are required for PDF output.
  • Use --assemble-only to debug markdown content before final rendering.
  • Output files are written to dist/book/ with standardized naming conventions.

Frequently Asked Questions

What dependencies are required to run the build script?

The script requires Pandoc installed and available in your system PATH to generate EPUB files. For PDF generation, you need a LaTeX distribution providing the xelatex binary, along with fontconfig (for the fc-list command) to enable font detection. The optional mmdc CLI enables rendering of Mermaid diagrams to SVG.

How do I build only a specific volume instead of the entire series?

Pass the --volume argument followed by the volume slug as defined in book/volumes.json. For example, python3 scripts/build_book.py --volume fundamentals processes only the phases associated with that volume, significantly reducing build time.

Why does PDF generation fail or get skipped for my language?

PDF generation is restricted to left-to-right languages. The script checks the language direction and will skip PDF rendering if the script detects a right-to-left script. Additionally, PDF generation requires xelatex and appropriate system fonts; if these are missing, the script will build the EPUB but skip the PDF step.

Where can I find the assembled markdown source before Pandoc converts it?

The concatenated markdown file is written to book/_build/<volume>.md during the assembly phase. Use the --assemble-only flag to generate this file without invoking Pandoc, allowing you to inspect how lesson content, image paths, and special blocks are transformed before final rendering.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →