Skip to main content

Convert PDF documents to Markdown using Claude's native PDF API

Project description

pdf2md-claude

CI PyPI Python License: MIT

Convert PDF documents to high-quality Markdown using Claude's native PDF API. Handles large documents via chunked conversion with context passing, deterministic merging, and output validation. Preserves tables, formulas, figures, and document structure.

Installation

Requires Python 3.11+.

pip install pdf2md-claude

Or install from source:

pip install git+https://github.com/hacker-cb/pdf2md-claude.git

Quick Start

# Set API key
export ANTHROPIC_API_KEY="your-key-here"

# Convert a single PDF (output: document.md next to the PDF)
pdf2md-claude document.pdf

# Convert multiple PDFs
pdf2md-claude doc1.pdf doc2.pdf

# Convert all PDFs in a directory (shell glob)
pdf2md-claude *.pdf
pdf2md-claude docs/*.pdf

# Custom output directory
pdf2md-claude *.pdf -o output/

# Also works via python -m
python -m pdf2md_claude document.pdf

Output

By default, Markdown files are written next to the source PDF:

Input Output
docs/document.pdf docs/document.md
docs/document.pdf --max-pages 5 docs/document_first5.md

With -o DIR, all output goes to the specified directory.

Conversion Pipeline

Chunked conversion with context passing, deterministic merging, and validation:

  1. Split PDF into disjoint chunks
  2. Convert each chunk with context from the previous chunk's tail
  3. Merge chunks by page markers (deterministic, no LLM)
  4. Merge continued tables across page boundaries (deterministic, no LLM)
  5. Extract and inject images from bounding-box markers (deterministic, no LLM)
  6. Validate output (page markers, tables, heading gaps, binary sequences, fabrication detection)

CLI Options

pdf2md-claude [OPTIONS] PDF [PDF ...]

Positional:
  PDF                  One or more PDF files to convert (supports shell globs)

Options:
  -o, --output-dir DIR Output directory (default: same directory as each PDF)
  -v, --verbose        Enable verbose logging
  -f, --force          Force reconversion even if output exists
  --max-pages N        Convert only first N pages (useful for debugging)
  --cache              Enable prompt caching (1h TTL, reduces re-run cost)
  --pages-per-chunk N  Pages per conversion chunk (default: 10)
  --no-images          Skip image extraction from bounding-box markers
  --remerge            Re-merge from cached chunks (no API calls needed)

Run without arguments to display help.

Environment

Variable Description
ANTHROPIC_API_KEY Anthropic API key (required)

File Structure

pdf2md-claude/
├── pdf2md_claude/              # Main package
│   ├── __init__.py             # Package exports (lazy imports)
│   ├── __main__.py             # python -m pdf2md_claude entry point
│   ├── cli.py                  # CLI argument parsing and orchestration
│   ├── client.py               # Anthropic API client setup
│   ├── converter.py            # Core PDF→Markdown conversion logic
│   ├── images.py               # Image extraction, rendering, and injection (pymupdf)
│   ├── markers.py              # Centralized marker definitions (MarkerDef)
│   ├── merger.py               # Deterministic page-marker merge + table continuation merging
│   ├── models.py               # Model configurations, pricing, usage tracking
│   ├── pipeline.py             # Single-document orchestration (convert → merge → validate → write)
│   ├── prompt.py               # Prompts for Claude PDF conversion
│   ├── validator.py            # Content validation (page markers, tables, fabrication, etc.)
│   └── workdir.py              # Chunk persistence, resume, and work directory management
├── tests/                      # Unit tests
│   ├── __init__.py
│   ├── test_converter.py
│   ├── test_images.py
│   ├── test_markers.py
│   ├── test_table_merger.py
│   ├── test_validator.py
│   └── test_workdir.py
├── scripts/
│   └── setup-dev.sh            # Dev environment setup (.venv + hooks)
├── .githooks/
│   └── pre-commit              # Runs tests before commit
├── pyproject.toml              # Project metadata and dependencies
├── .gitignore
└── README.md

Development

Setup

One command sets up everything (.venv, dependencies, git hooks):

git clone https://github.com/hacker-cb/pdf2md-claude.git
cd pdf2md-claude
bash scripts/setup-dev.sh

To recreate the .venv from scratch:

bash scripts/setup-dev.sh --force

Running Tests

pytest tests/ -v

Debugging

Enable verbose logging:

pdf2md-claude -v document.pdf

Use --cache to avoid re-paying for PDF content on repeated runs during prompt/pipeline development:

pdf2md-claude --cache document.pdf --max-pages 5

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

pdf2md_claude-0.1.0.tar.gz (65.4 kB view details)

Uploaded Source

Built Distribution

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

pdf2md_claude-0.1.0-py3-none-any.whl (50.3 kB view details)

Uploaded Python 3

File details

Details for the file pdf2md_claude-0.1.0.tar.gz.

File metadata

  • Download URL: pdf2md_claude-0.1.0.tar.gz
  • Upload date:
  • Size: 65.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for pdf2md_claude-0.1.0.tar.gz
Algorithm Hash digest
SHA256 013f07bf538d76328e48c4374e51aa282805fea2970926515c43e6625814025d
MD5 96c45d1be1ca89795180ad59b9c172aa
BLAKE2b-256 f925c1b40bc0df826c54f808a9f0eada5d602e8ae0e734b4709e3b7783f112a3

See more details on using hashes here.

Provenance

The following attestation bundles were made for pdf2md_claude-0.1.0.tar.gz:

Publisher: publish.yml on hacker-cb/pdf2md-claude

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

File details

Details for the file pdf2md_claude-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: pdf2md_claude-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 50.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for pdf2md_claude-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 fe87a436c14f29c2a1b9047009d8443f9c3ff2bc6d19ae560897285ff8ea74fd
MD5 f8af4097ce7cc4cf7cbdc52dd22e4201
BLAKE2b-256 ae1abadc6be7688fa5a8f8a26e1173b7c6f9906a26f042634fd5925cecd2c3f7

See more details on using hashes here.

Provenance

The following attestation bundles were made for pdf2md_claude-0.1.0-py3-none-any.whl:

Publisher: publish.yml on hacker-cb/pdf2md-claude

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