Skip to main content

Generate PDF databooks from AsciiDoc or Markdown chapters with Jinja2 templating

Project description

databook-generator

Company Logo

PyPI version Python versions License: MIT

Generate polished PDF databooks from AsciiDoc or Markdown chapter files, with full Jinja2 templating throughout — including inside SVG diagrams.

Define your parameters once in a config.json file. Every parameter automatically becomes a variable you can reference inside your chapter content and your SVG images.


Features

  • AsciiDoc (.adoc) chapters rendered via asciidoctor-pdf
  • Markdown (.md) chapters converted to AsciiDoc via pandoc, then rendered to PDF with the same pipeline
  • Jinja2 templating in .adoc, .md, and .svg files — any key in config.json becomes a template variable
  • Logo support — drop logo.svg or logo.png in your images/ folder; it appears on the title page and in the top-right corner of every page
  • Per-page footer with document title and page numbers
  • Auto-discovery of asciidoctor-pdf binary across Homebrew, gem user-install, rbenv, and RVM
  • Clean intermediate file handling — no leftover artefacts unless you ask for them

Requirements

Python

Python 3.10 or newer.

asciidoctor-pdf (required for all PDFs)

asciidoctor-pdf is a Ruby gem and must be installed separately.

macOS

# If you have the system Ruby (not recommended — no write permission):
gem install asciidoctor-pdf --user-install

# Recommended: install Ruby via Homebrew first
brew install ruby
$(brew --prefix ruby)/bin/gem install asciidoctor-pdf

# Add Homebrew gem bin to your PATH permanently (add to ~/.zshrc or ~/.bashrc):
export PATH="$(brew --prefix ruby)/bin:$PATH"
export PATH="$($(brew --prefix ruby)/bin/gem environment gemdir)/bin:$PATH"

Linux (Debian / Ubuntu)

sudo apt update
sudo apt install ruby-full build-essential
gem install asciidoctor-pdf

Linux (Fedora / RHEL / CentOS)

sudo dnf install ruby ruby-devel
gem install asciidoctor-pdf

Windows

  1. Download and install Ruby from rubyinstaller.org (include the MSYS2 toolchain when prompted).
  2. Open a new Command Prompt or PowerShell:
gem install asciidoctor-pdf

Verify installation

asciidoctor-pdf --version
# If not found, locate the gem bin directory:
gem environment gemdir
# Then add <gemdir>/bin to your PATH

pandoc (required only for Markdown chapters)

pandoc is only needed when your chapters are .md files.

macOS

brew install pandoc

Linux (Debian / Ubuntu)

sudo apt install pandoc

Linux (Fedora / RHEL)

sudo dnf install pandoc

Windows

winget install --id JohnMacFarlane.Pandoc
# Or download the installer from https://pandoc.org/installing.html

Verify installation

pandoc --version

Installation

From PyPI

pip install databook-generator

With Markdown support

pip install "databook-generator[markdown]"

From source

git clone https://github.com/rohaansch/databook-generator.git
cd databook-generator
pip install -e .                   # AsciiDoc chapters only
pip install -e ".[markdown]"       # Include Markdown support

Quick Start

1. Create your working directory

my-databook/
├── config.json
├── chapters/
│   ├── introduction.adoc   (or introduction.md)
│   └── chapter2.adoc       (or chapter2.md)
└── images/
    ├── logo.svg            (optional — auto-detected)
    └── my_diagram.svg

2. Write your config

{
    "title": "My Databook",
    "version": "1.0",
    "author": "Your Name",
    "date": "April 2026",
    "product_name": "Widget Pro",
    "chapters": [
        "introduction",
        "chapter2"
    ]
}

3. Run

cd my-databook/
databook-generator -config config.json

The PDF is written to my-databook/My_Databook.pdf.


CLI Reference

databook-generator -config CONFIG [options]

Required:
  -config FILE        Path to the JSON config file

Optional:
  -images DIR         Images directory (default: ./images)
  -chapters DIR       Chapters directory (default: ./chapters)
  -output FILE        Output PDF path (default: <title>.pdf in CWD)
  --keep-intermediates  Keep rendered .adoc and theme files for debugging
  --version           Show version and exit
  -h, --help          Show help

Config File Reference

config.json drives both the document structure and Jinja2 template variables.

Key Required Description
title Yes Document title — used on the title page, footer, and output filename
chapters Yes Ordered list of chapter names (without extension)
author No Author name displayed on the title page
Any other key No Automatically available as a Jinja2 variable in chapters and SVGs

Example

{
    "title": "PDK Extraction Specification",
    "version": "2.1",
    "author": "PDK Team",
    "date": "April 2026",
    "pdk_name": "p1278",
    "pdk_revision": "pdk785",
    "dot_process": "dot3",
    "support_email": "pdk-support@example.com",
    "feature_flags": {
        "include_legacy_notes": false,
        "include_dvb_section": true
    },
    "chapters": [
        "introduction",
        "poly_endcap",
        "dvb_proximity"
    ]
}

Jinja2 Templating

This is the core power feature of databook-generator. Every key you define in config.json is injected as a Jinja2 variable into your chapter files and SVG images at render time.

How it works

When you run databook-generator, it:

  1. Loads your config.json
  2. Passes every key (except "chapters") as a Jinja2 variable
  3. Renders each chapter file as a Jinja2 template
  4. Renders any SVG files that contain Jinja2 syntax
  5. Assembles and generates the final PDF

Variable substitution

Use {{ variable_name }} anywhere in your chapter or SVG:

# In config.json:
"pdk_name": "p1278",
"pdk_revision": "pdk785"

# In a chapter file (.adoc or .md):
This document covers the {{ pdk_name }} PDK, revision {{ pdk_revision }}.

Renders to:

This document covers the p1278 PDK, revision pdk785.

Conditional content

Use {% if %} / {% else %} / {% endif %} to include or exclude sections:

# config.json:
"feature_flags": { "include_legacy_notes": false }

# chapter.adoc:
{% if feature_flags.include_legacy_notes %}
NOTE: This section contains legacy notes for pre-{{ pdk_revision }} users.
...
{% endif %}

If include_legacy_notes is false, that entire block is omitted from the PDF.

Loops

Use {% for %} to generate repeated content from a list:

# config.json:
"layer_stack": ["M1", "M2", "M3", "M4", "M5"]

# chapter.adoc:
The following metal layers are defined in {{ pdk_name }}:

{% for layer in layer_stack %}
* {{ layer }}
{% endfor %}

Nested values

Access nested config keys using dot notation:

# config.json:
"timing": { "setup_margin": "50ps", "hold_margin": "20ps" }

# chapter.md:
Setup margin: **{{ timing.setup_margin }}**
Hold margin: **{{ timing.hold_margin }}**

SVG templating

SVG files in your images/ directory are also Jinja2 templates. Any SVG containing {{ or {% is rendered before embedding in the PDF.

<!-- images/process_node.svg -->
<text x="300" y="50">{{ pdk_name }}  {{ dot_process }}</text>
<text x="300" y="70">Rev: {{ pdk_revision }}</text>

This is useful for diagram titles, labels, and revision stamps that should always match the config — no need to manually update SVG text when values change.

Undefined variables

If a template references a variable not present in config.json, it silently renders as an empty string (no errors). This lets you write reusable chapter templates that gracefully degrade for configs that don't define every variable.


Chapter Formats

AsciiDoc (.adoc)

AsciiDoc is a rich markup format with native support for tables, cross-references, callouts, and admonitions. It is the recommended format for complex technical documents.

== Introduction

This spec covers *{{ pdk_name }}* revision *{{ pdk_revision }}*.

[cols="1,2", options="header"]
|===
| Field | Value
| PDK | {{ pdk_name }}
| Revision | {{ pdk_revision }}
|===

[NOTE]
====
All measurements are in nanometers.
====

<<<

The <<< at the end of a chapter inserts a page break.

Markdown (.md)

Markdown chapters use standard GitHub-Flavoured Markdown (GFM). Under the hood they are converted to AsciiDoc via pandoc before PDF generation, so the same logo, theme, and footer apply.

## Introduction

This report covers **{{ product_name }}** on the **{{ process_node }}** node.

| Field | Value |
|---|---|
| Product | {{ product_name }} |
| Node | {{ process_node }} |

{% if include_appendix %}
> See the appendix for raw measurement data.
{% endif %}

Format rules

  • All chapters in a run must use the same format — either all .adoc or all .md.
  • Do not mix .adoc and .md in the same chapters list. The tool will exit with an error if mixed files are detected.
  • The extension is not included in config.json; the tool discovers it automatically.

Logo

Place one or more logo files in your images/ directory. No configuration is needed — detection is automatic. SVG is recommended for crisp rendering at all sizes.

Two-logo mode (recommended)

Use separate files optimised for each context:

File Where it appears Recommended size
main_logo.svg / main_logo.png Centred on the title page at 45% page width Wide, high-resolution
header_logo.svg / header_logo.png Top-right of every page header at 22% page width Horizontal / compact

Single-logo mode (fallback)

If dedicated files are not found, logo.svg / logo.png is used for both roles automatically.

Priority order

Title page  → main_logo.svg/png   → logo.svg/png
Header      → header_logo.svg/png → logo.svg/png

SVG logo templating

Logo SVG files can contain Jinja2 directives just like chapter files. For example, to stamp a version number on the logo:

<!-- images/header_logo.svg -->
<text x="200" y="60">Rev {{ version }}</text>

Directory Layout

The expected layout when running from a project directory:

my-databook/
├── config.json          Required
├── chapters/            Default chapter directory (override with -chapters)
│   ├── intro.adoc       or intro.md
│   └── section2.adoc    or section2.md
└── images/              Default images directory (override with -images)
    ├── logo.svg          Auto-detected logo
    └── diagram.svg       Referenced from chapters as image::diagram.svg[]

Override defaults:

databook-generator \
  -config /path/to/config.json \
  -chapters /path/to/my/chapters \
  -images /path/to/my/images \
  -output /path/to/output/report.pdf

Syntax Highlighting

Code blocks in chapters use Rouge for syntax highlighting. Install it for coloured output:

gem install rouge

Examples

The example/ directory contains two complete working examples:

AsciiDoc example

cd example/adoc_example/
databook-generator -config config.json

Demonstrates:

  • Jinja2 variable substitution and conditionals in .adoc
  • An SVG diagram (poly_endcap.svg) with Jinja2 labels rendered at build time
  • Logo on every page

Markdown example

cd example/markdown_example/
databook-generator -config config.json

Demonstrates:

  • Jinja2 variable substitution and conditionals in .md
  • GFM tables and code fences
  • Chart SVGs referenced from Markdown

Releasing to PyPI

Setup (one time)

  1. Create a PyPI account
  2. Enable Trusted Publishing in your PyPI project settings, pointing to this repository and the publish.yml workflow

Release process

# Bump version in:
#   databook_generator/__init__.py  (VERSION)
#   pyproject.toml                  (version field)
#   CHANGELOG.md                    (add entry)

git add .
git commit -m "Release v1.1.0"
git tag v1.1.0
git push origin main --tags

The GitHub Actions workflow (.github/workflows/publish.yml) automatically builds and publishes to PyPI when a v*.*.* tag is pushed.


Contributing

Pull requests are welcome. For major changes, open an issue first.

  1. Fork the repo
  2. Create a feature branch (git checkout -b feature/my-feature)
  3. Make your changes and add tests
  4. Push and open a PR against main

License

MIT — © 2024 Rohan Chadhury

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

databook_generator-1.0.0.tar.gz (167.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

databook_generator-1.0.0-py3-none-any.whl (15.1 kB view details)

Uploaded Python 3

File details

Details for the file databook_generator-1.0.0.tar.gz.

File metadata

  • Download URL: databook_generator-1.0.0.tar.gz
  • Upload date:
  • Size: 167.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for databook_generator-1.0.0.tar.gz
Algorithm Hash digest
SHA256 87bc6827722b9ef8f64df48e546bc544ee9410471041f8762a974fafad3ea3d3
MD5 52e1a022ff5ac727113688cad78697b5
BLAKE2b-256 96d93bf4c4545626dd72cbb7c298d68bc10b672d2e5eb5d5bc054bb3188680f3

See more details on using hashes here.

File details

Details for the file databook_generator-1.0.0-py3-none-any.whl.

File metadata

File hashes

Hashes for databook_generator-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 a5bbc2a1f15f1647fb00fb70cdee2ee9e59ef46ab719d617625dd74e0c03d84c
MD5 5d265cfe46996cc7fd16aea5a1bf3839
BLAKE2b-256 40d9201e2afe0aebe41b86652b82a6a3f1e0ef6156e776652aa3ccf2ab898398

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page