Skip to main content

Biblion

Turn plain markdown into a typeset PDF book — with real rendered diagrams — locally, and for free on every run.

Cover page A page with a rendered figure and caption A d2 architecture diagram

Every page above was produced from plain markdown by biblion build.


Contents


Why

Asking an AI to produce a beautiful PDF is expensive. It spends thousands of tokens on layout, spacing, colours and page structure, and you pay that cost again every time you want a change.

Asking an AI for a markdown file is cheap. But run that markdown through a generic online converter and you get something that looks like a printed email: no cover, no contents page, no callouts, and diagrams left as raw mermaid source in a grey box.

Biblion takes the cheap half and makes it look like the expensive half:

AI writes content-only markdown  →  biblion build  →  typeset PDF
   (paid once, in tokens)           (free, local, repeatable)

You spend tokens on information. Biblion owns presentation — cover page, contents with real page numbers, running headers, numbered figures, callout boxes, syntax highlighting, page-break rules, and diagram rendering. Change the theme and rebuild; you never pay tokens again.

Contents page with page numbers List of figures

Contents and Figures pages, both with real page numbers. Neither is written by hand.

Install

pip install biblion-pdf

The distribution is biblion-pdf; the command and the import are both biblion. (The bare name on PyPI belongs to an unrelated Django app.)

Then check what your machine can do:

biblion doctor

System libraries for WeasyPrint

The pip package is not enough on its own — WeasyPrint needs Pango at runtime.

Platform Command
Linux sudo apt install libpango-1.0-0 libpangoft2-1.0-0 libffi-dev
macOS brew install pango libffi
Windows Install the GTK3 runtime

On macOS you also need to point the loader at Homebrew's libraries, or WeasyPrint imports fine and then fails with cannot load library 'libgobject-2.0-0':

export DYLD_FALLBACK_LIBRARY_PATH="$(brew --prefix)/lib"

Add that to your shell profile to make it stick. biblion doctor detects this and prints the fix for your platform.

Diagram renderers (optional)

Biblion works without these — you just won't get diagrams.

Tool Needed for Install
mermaid-cli ```mermaid blocks npm install -g @mermaid-js/mermaid-cli
d2 ```d2 blocks d2lang.com/tour/install, or drop d2/d2.exe in your project folder
a Chromium browser rasterising both you almost certainly already have Chrome or Edge

Biblion finds a browser you already have (Edge on Windows, Chrome elsewhere) and uses it for both renderers: it points mermaid-cli at it, and screenshots d2's SVG output with it. Neither puppeteer nor d2 has to download its own ~150MB Chromium. Set BIBLION_BROWSER to override the choice.

A caveat on macOS

Headless Chrome screenshotting is known to fail on macOS CI runners — every d2 screenshot times out. Biblion notices on the first diagram, says so, and falls back to rsvg-convert for the rest of the build.

That fallback works, but rsvg-convert does not honour the fonts d2 embeds in its SVG, so diagram labels lose their bold and italic and come out flat. Everything else — layout, colours, arrows — is correct.

So on macOS, install the fallback:

brew install librsvg

If your Mac renders d2 through the browser without complaint, you will see no fallback message and your diagrams keep their proper typography. Biblion tries both headless modes before giving up.

Quickstart

biblion init my-book --title "My Book"
cd my-book
biblion build

init scaffolds this:

my-book/
  book.toml                 settings
  modules/
    01_introduction.md      your content

build writes output/My_Book.pdf.

Add more chapters as modules/02_*.md, modules/03_*.md, … They are merged in filename order, so zero-pad the numbers.

Writing the markdown

Ordinary markdown, plus two extras. Don't write HTML or CSS — Biblion overrides presentation, so any styling you write is wasted effort.

Structure

  • # — starts a new page. Use one per chapter.
  • ##, ### — sections and subsections.
  • Paragraphs, **bold**, *italic*, `code`, - and 1. lists, > blockquotes.
  • GitHub pipe tables. Keep them under about six columns; the page is A4.
  • Fenced code blocks with a language tag — that drives syntax highlighting.

Don't write a table of contents. Biblion generates one with real page numbers.

Callout boxes

Admonition syntax. The body must be indented four spaces.

!!! deepdive "Why this exists"
    A language model is a brain in a jar. It needs hands.

Available types: deepdive, interview, workhelp, note, tip.

Diagrams

This is where the token saving is largest. Don't describe a diagram in prose and don't draw it in ASCII — write about thirty tokens of diagram source and Biblion renders a real figure.

Use ```mermaid for flows, sequences and state machines:

```mermaid
flowchart LR
    A["Source code"] -->|docker build| B["Image"]
```

Use ```d2 for architecture and anything where nesting matters:

```d2
cluster: "Kubernetes cluster" {
  svc: Service
  pod: Pod
  svc -> pod
}
client: Client { shape: person }
client -> cluster.svc
```

Rules of thumb:

  • Quote labels containing spaces or punctuation: A["Like this"].
  • <br/> for line breaks in mermaid labels; \n in d2 labels.
  • Around twelve nodes maximum. Two clear diagrams beat one crowded one.
  • Don't set colours or styles — the theme handles it.
  • Don't think about direction. Biblion re-lays out anything too wide for the page (see auto-fit).

Captions

Add caption="..." to the opening fence and the diagram becomes a numbered figure:

```d2 caption="How a request reaches a pod."
client -> ingress -> pod
```

Biblion numbers it per chapter (Figure 2.3), keeps the caption in the same unbreakable block as the diagram so the two never split across a page, and lists it on a Figures page with a real page number.

Uncaptioned diagrams are left alone: not numbered, not listed. If a book has no captions at all, no Figures page is generated.

Themes

Two ship with Biblion. Pick one with --theme NAME or theme = "..." in book.toml.

Theme For Looks like
textbook (default) course notes, study material, tutorials Serif body, generous margins, navy cover panel, dark code blocks
report API docs, specifications, technical reports Sans body, tight margins, flat typographic title page, light bordered code blocks

report fits roughly 20% more on a page — the same book renders in 91 pages instead of 113 — which suits something consulted rather than read straight through.

biblion build --theme report

The same page in the textbook theme The same page in the report theme

The same page, same markdown: textbook on the left, report on the right.

Point --css path/to/your.css at your own stylesheet to replace the theme entirely. Start by copying one of the shipped themes; biblion doctor will not check a custom stylesheet for you, and the generated HTML expects the classes both themes style.

Configuration

biblion build reads book.toml from the project folder, so a rebuild is one word. Every setting can be overridden on the command line.

title    = "Introduction to Containers"
subtitle = "Course 8 of the IBM RAG and Agentic AI Certificate"
author   = "Compiled for Shivam"
eyebrow  = "IBM PROFESSIONAL CERTIFICATE · COURSE 8"

input  = "modules"
output = "output/Containers.pdf"

toc_depth = 3
strict    = false

A [book] section is accepted too, if you prefer it. Unknown keys are a hard error, so a typo tells you instead of being silently ignored.

All settings

Key Default Meaning
input modules if it exists, else . Folder of .md files, merged in filename order
output output/<Title>.pdf Where to write the PDF
title folder name Cover title, also the PDF title
subtitle empty Under the cover title
author empty Cover footer line
eyebrow empty Small uppercase line above the cover title
theme textbook Named theme shipped with Biblion
css empty Path to your own stylesheet, replacing the theme
toc true Include the contents page
toc_depth 3 Deepest heading level listed (1 = # only)
cover true Include the cover page
figure_list true Include the Figures page
diagram_theme "0" d2 theme id — see d2 themes
diagram_width 1400 Render width in px; higher is crisper and slower
diagram_background white Background passed to mermaid
autofit true Re-lay-out diagrams too wide for the page
per_module false Also write one PDF per source file
strict false Exit non-zero if any diagram fails to render
allow_downloads false Let d2 fetch its own Chromium
puppeteer_config empty Explicit puppeteer config for mermaid-cli
cache_dir <output dir>/_diagram_cache Where rendered diagrams are cached

Command reference

biblion build [project]

Builds the PDF. project defaults to the current directory.

Flag Meaning
--input, --output Override the input folder / output path
--title, --subtitle, --author, --eyebrow Cover text
--theme NAME, --css PATH Choose a theme or your own stylesheet
--toc-depth N Deepest heading level in the contents
--no-toc, --no-cover, --no-figure-list Drop front matter
--per-module Also write one PDF per source file, titled from each file's own #
--strict Exit non-zero if any diagram fails — use this in CI
--no-autofit Render diagrams exactly as authored
--diagram-theme, --diagram-width Diagram rendering options
--allow-downloads Permit d2's one-time Chromium download
--puppeteer-config PATH Point mermaid-cli at a specific browser config

Flags always win over book.toml; anything you don't pass keeps its configured value.

biblion doctor [project]

Reports which renderers are available, where they were found, and the exact install command for anything missing. Run this first when something isn't working.

biblion init [project] [--title T] [--force]

Scaffolds book.toml and a modules/ folder with a sample chapter.

biblion prompt

Prints the markdown contract to paste into any AI chat.

biblion skill [--install] [--project DIR] [--force]

Prints, or installs, the Claude Code skill.

Using Biblion with an AI

This is the point of the tool, so it ships as a first-class path.

Claude Code — install the skill once:

biblion skill --install              # into ~/.claude/skills/
biblion skill --install --project .  # or into one repo

Claude Code will then reach for Biblion whenever you ask for a PDF, book, report or study notes, writing content-only markdown and shelling out to biblion build instead of hand-building a document.

Any other assistant — paste the contract into the chat first:

biblion prompt

It tells the model what to write, what not to write, and how to emit diagrams and captions.

What Biblion does to your pages

Things you get without asking, and the reason the output doesn't look like a converted markdown file.

Diagrams are re-laid out to fit the page

A ten-node flowchart LR is an 11:1 strip. Squeezed into a portrait text column it's about 1.5cm tall with 3pt labels — technically rendered, practically unreadable.

Because direction is presentation, and presentation is Biblion's job, wide diagrams are re-rendered the other way round. Biblion measures both versions and keeps whichever puts physically larger text on the page — so it will also decline to flip a diagram when flipping would make it worse. Anything still wide breaks out to the full page width.

Turn it off with --no-autofit.

Running headers

Every page after the front matter carries the current chapter's name in the top margin, so a reader landing on page 47 knows where they are. It updates at each # and carries across continuation pages.

Figures stay with their captions

A caption lives inside its figure's unbreakable block, so a caption can never be orphaned onto the page after its diagram.

Failed diagrams are loud

If a renderer is missing or errors, you get a red dashed UNRENDERED box containing the source — not something that looks like an ordinary code block. A book cannot quietly ship with its diagrams missing. Use --strict to turn that into a failed build.

Diagrams are cached

Cached on a hash of their source, so only changed diagrams re-render. The first build of a large book is slow; later ones are not.

Environment variables

Variable Default Purpose
BIBLION_BROWSER auto-detected Path to the Chrome/Edge/Chromium to use
BIBLION_HOME ~/.biblion Where Biblion keeps its cache and binaries
BIBLION_BROWSER_TIMEOUT 90 Seconds before a browser screenshot is abandoned
BIBLION_RENDER_TIMEOUT 120 Seconds before a renderer call is abandoned
BIBLION_D2, BIBLION_MMDC, … auto-detected BIBLION_<TOOL> pins a specific binary

Troubleshooting

biblion doctor says a renderer is missing. It prints the install command for your platform. Biblion looks for binaries in your project folder, on PATH, in ~/.biblion/bin, in npm's global directory and in ~/.local/bin — so dropping d2.exe next to your book is enough.

cannot load library 'libgobject-2.0-0' on macOS. Homebrew's libraries aren't on the loader path: export DYLD_FALLBACK_LIBRARY_PATH="$(brew --prefix)/lib".

A diagram failed to render. The build prints the reason next to the diagram, and again in the summary. Most often it's invalid diagram source — the message quotes the parse error from mermaid or d2.

d2 says it needs to install Chromium. It only asks when Biblion found no browser. Install Chrome or Edge, set BIBLION_BROWSER, or pass --allow-downloads to accept the download.

Diagram labels lost their bold and italic. The browser rasteriser failed and Biblion fell back to rsvg-convert, which ignores d2's embedded fonts. The build says so when it happens. See the macOS caveat.

A diagram is unreadably small. It's probably very wide. Auto-fit will have tried the other orientation already; splitting it into two diagrams almost always reads better than shrinking one.

Nothing appears to happen on a large book. Diagram rendering is the slow part, and each diagram is reported as it renders. The second build is much faster thanks to the cache.

Development

git clone https://github.com/ShivamMalge/Biblion
cd Biblion
pip install -e ".[dev]"
pytest
biblion/
  cli.py               build / doctor / init / prompt / skill
  config.py            book.toml handling
  diagrams.py          mermaid + d2 rendering, caching, auto-fit
  document.py          markdown -> HTML, cover, contents, figures
  tools.py             finding binaries and a browser
  themes/textbook.css  the stylesheet that does the actual work
  authoring_prompt.md  the contract `biblion prompt` prints
  skill/SKILL.md       the Claude Code skill `biblion skill` installs
examples/diagram-tour  a worked example exercising both renderers
scripts/screenshots.py regenerates the images in this README

Build the worked example with biblion build examples/diagram-tour --strict.

CI runs the unit tests on Linux, macOS and Windows, and builds examples/diagram-tour end to end with --strict on Linux and macOS, so a broken renderer fails the build rather than shipping a book full of red boxes. The example is not built on Windows in CI because WeasyPrint there needs the GTK3 runtime, which has no clean unattended installer.

Changelog

See CHANGELOG.md.

License

MIT — see LICENSE.

Metadata

Release files for biblion-pdf 0.3.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for biblion-pdf 0.3.0
File Size Uploaded
biblion_pdf-0.3.0.tar.gz 54.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for biblion-pdf 0.3.0
File Interpreter ABI Platform
biblion_pdf-0.3.0-py3-none-any.whl Python 3 none any Details

Total release size: 100.4 kB

Release files / biblion_pdf-0.3.0.tar.gz

Download URL biblion_pdf-0.3.0.tar.gz
Size 54.7 kB
Tags Source
SHA-256 checksum
How to use checksums
ccfd21e6eae71e4cdc4faf3bcac542855d0cf4c742c072ff2ff215beb2d06a9c
BLAKE2b-256 checksum
How to use checksums
f7e52cec35b7e73237915eb7e5e4e6127e2c768882fd02ac8ff12944e2d45d02
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 2, 2026.

Transparency log

Release files / biblion_pdf-0.3.0-py3-none-any.whl

Download URL biblion_pdf-0.3.0-py3-none-any.whl
Size 45.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
3eb0861a1692e47844c4a37cbf4f291a9c2a3724fe8f88e66c4e2973ee18453c
BLAKE2b-256 checksum
How to use checksums
4ba81d451f8c4afc2a0e8aaa25901fb80187c10d0f9e8c891ec876ff06f34dc2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 2, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.3.0 This release

2 release files

0.2.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page