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.
- Escaping generic type parameters (e.g.,
- 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.
- Add watermarks to PDFs (e.g.,
- 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, orboth(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.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| mdweaver-0.4.1.tar.gz | 8.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| mdweaver-0.4.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 18.0 kB
Release files / mdweaver-0.4.1.tar.gz
| Download URL | mdweaver-0.4.1.tar.gz |
|---|---|
| Size | 8.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
be9ce5d828c862b6eb4b0c9eb8d0a897eed1fc72aa78ea5a34c10d48dfcd603b
|
|
BLAKE2b-256 checksum How to use checksums |
7534f9ab312a282850dfaefeb1829aa3d98d9eaaaa7e089385d18c4ab2fa08df
|
| 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 logRelease files / mdweaver-0.4.1-py3-none-any.whl
| Download URL | mdweaver-0.4.1-py3-none-any.whl |
|---|---|
| Size | 9.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
de413397c988a0f322d97d2b94bbc727835d55b67f7736019b3166ce5e8e6525
|
|
BLAKE2b-256 checksum How to use checksums |
b51f3da32b96bc636109130bfb4d0cc56537efb2a8005b6f1d1fb53a414875de
|
| 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