Skip to main content

Weave markdown files into beautifully formatted PDFs and EPUBs

Project description

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

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

mdweaver-0.3.0.tar.gz (7.9 kB view details)

Uploaded Source

Built Distribution

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

mdweaver-0.3.0-py3-none-any.whl (9.3 kB view details)

Uploaded Python 3

File details

Details for the file mdweaver-0.3.0.tar.gz.

File metadata

  • Download URL: mdweaver-0.3.0.tar.gz
  • Upload date:
  • Size: 7.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for mdweaver-0.3.0.tar.gz
Algorithm Hash digest
SHA256 0a51920a8b18840c12d2b0376427415964c25ecdc70889985b90da089903ae60
MD5 45f6b4c3be9a9703e62535f5664e6073
BLAKE2b-256 d41100ee32d109d6d1bd36c445355be2ef6d22d34611920adced15b779fd8c51

See more details on using hashes here.

Provenance

The following attestation bundles were made for mdweaver-0.3.0.tar.gz:

Publisher: release.yml on bbelderbos/mdweaver

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file mdweaver-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: mdweaver-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 9.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for mdweaver-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 50a9fe3198c6b94bbb34639aef8250ab7b7bf6aa69b958e585bce894dc820196
MD5 a6ed8b1526d4a581c071606923092152
BLAKE2b-256 1acf274716f1fe458443761db6f90249aa8a41a27fce2b46ca64f5241508b44f

See more details on using hashes here.

Provenance

The following attestation bundles were made for mdweaver-0.3.0-py3-none-any.whl:

Publisher: release.yml on bbelderbos/mdweaver

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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