Skip to main content

mdweaver

mdweaver

Weave markdown files into beautifully formatted PDFs and EPUBs.

mdweaver is a command-line tool that converts your Markdown documentation into professional-looking PDF and EPUB files. It handles syntax highlighting, recursive file discovery, common rendering issues, and sensible default exclusions automatically.

Features

  • Multiple Formats: Generate PDF, EPUB, or both simultaneously.
  • Recursive Processing: Convert a single file or an entire directory of documentation.
  • Default Exclusions: Skips common “noise” directories by default:
    • .git, .venv / venv, node_modules, __pycache__, .pytest_cache, output
  • Syntax Highlighting: Includes Pygments support (Monokai theme) for code blocks.
  • Smart Preprocessing: Automatically fixes common Markdown issues like:
    • Escaping generic type parameters (e.g., Result<T, E>).
    • Correcting list spacing for proper rendering.
  • Customization:
    • Add watermarks to PDFs (e.g., "DRAFT").
    • Add branded page headers (e.g., "belderbos.dev · Python · Rust · AI").
    • Override the default styles with a custom CSS file.
    • Start a new PDF page at each horizontal rule (---) with --page-break-on-hr.
    • Set custom document titles and author metadata.
    • Exclude additional paths via glob patterns.
  • Clean Typography: Uses optimized CSS for print (A4) and e-reader layouts.

Prerequisites

For PDF generation, mdweaver relies on WeasyPrint, which requires system libraries (Pango, Cairo, etc.) to be installed. EPUB generation works without these dependencies.

macOS:

brew install pango

Linux (Debian/Ubuntu):

sudo apt install libpango-1.0-0 libpangoft2-1.0-0

See the WeasyPrint documentation for other platforms: https://doc.courtbouillon.org/weasyprint/stable/first_steps.html

Installation

This project is managed with uv.

# Install dependencies
uv sync

Or using pip:

pip install mdweaver

macOS (Homebrew / Apple Silicon) – WeasyPrint dylib lookup

If import weasyprint fails with a libgobject-2.0-0 / gobject missing error on macOS, install the native deps with Homebrew and expose Homebrew’s lib directory to the dynamic loader:

brew install glib pango cairo gdk-pixbuf libffi
export DYLD_FALLBACK_LIBRARY_PATH="$(brew --prefix)/lib:${DYLD_FALLBACK_LIBRARY_PATH}"
uv run python -c "import weasyprint; print(weasyprint.__version__)"

You can add the export DYLD_FALLBACK_LIBRARY_PATH=... line to your shell config (typically ~/.zshrc on macOS; or ~/.bashrc) to make it persistent across sessions.

CLI Usage

The basic syntax is mdweaver <input> [options].

Examples

Convert a single file:

mdweaver document.md

Convert a directory (recursively), with defaults excluded:

mdweaver ./docs

Exclude additional paths (repeatable):

mdweaver ./docs --exclude "**/dist/**" --exclude "**/build/**"

Generate EPUB with metadata:

mdweaver ./content -f epub -t "My Book" -a "Author Name"

Generate PDF with a watermark:

mdweaver ./content -f pdf -w "DRAFT" -o ./build

Generate PDF with a branded page header:

mdweaver document.md --header "belderbos.dev · Python · Rust · AI"

Generate PDF with custom CSS:

mdweaver document.md --css my-theme.css

Generate both formats:

mdweaver ./content -f both

Options

  • input: Markdown file or directory to process.
  • -o, --output: Output directory (default: ./output).
  • -f, --format: Output format: pdf, epub, or both (default: pdf).
  • -t, --title: Document title (default: derived from filename/path).
  • -a, --author: Author name (for EPUB metadata).
  • -w, --watermark: Watermark text to display diagonally across PDF pages.
  • --css: Path to a custom CSS file to use instead of the default styles.
  • --header: Text to display in the page header on every PDF page.
  • --page-break-on-hr: Start a new page at each horizontal rule (---) instead of drawing a line (PDF only).
  • --exclude: Glob pattern to exclude (repeatable), e.g. --exclude "**/dist/**".

Default excludes

When scanning directories recursively, mdweaver excludes these patterns by default:

  • **/.git/**
  • **/.venv/**
  • **/venv/**
  • **/node_modules/**
  • **/__pycache__/**
  • **/.pytest_cache/**
  • **/output/**

You can add more exclusions using --exclude.

Project Structure

mdweaver/
├── src/mdweaver/
│   ├── __init__.py
│   └── generate_pdf.py   # Core logic
├── tests/
│   ├── conftest.py
│   └── test_mdweaver.py
├── pyproject.toml        # Dependencies and metadata
└── README.md

Development

Running Tests

uv run pytest

Note: You might see a skipped test for PDF generation if the system dependencies (WeasyPrint libs) are not installed.

Metadata

Release files for mdweaver 0.4.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 mdweaver 0.4.0
File Size Uploaded
mdweaver-0.4.0.tar.gz 8.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for mdweaver 0.4.0
File Interpreter ABI Platform
mdweaver-0.4.0-py3-none-any.whl Python 3 none any Details

Total release size: 18.0 kB

Release files / mdweaver-0.4.0.tar.gz

Download URL mdweaver-0.4.0.tar.gz
Size 8.3 kB
Tags Source
SHA-256 checksum
How to use checksums
181ed2b157120c9cb21542092201a7827081b13b795d7dad4426b9c279dd0869
BLAKE2b-256 checksum
How to use checksums
76660ccd02d496cf589be88bb027bf0539fee8289d2ead312675639f4016ee6a
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 3, 2026.

Transparency log

Release files / mdweaver-0.4.0-py3-none-any.whl

Download URL mdweaver-0.4.0-py3-none-any.whl
Size 9.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
1117d978aeadf96ddcd344d32a63516715464e26106232d0788e8b4caaf95ca8
BLAKE2b-256 checksum
How to use checksums
797d5b8f09af531ed7c53f0deff68b8beeefa3da16f257453f42852bafaf05ca
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 3, 2026.

Transparency log

Release history Release notifications | RSS feed

0.4.1

2 release files

This release

0.4.0 This release

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.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