Skip to main content

documint2md

Convert PDF, DOCX, CSV, and image files to Markdown from the command line or from Python.

documint2md installs the doc2md CLI and the doc2md Python package. It is designed for scripts, agents, and documentation pipelines that need predictable Markdown output and clear machine-readable status.

Install

python -m pip install documint2md

Optional extras:

python -m pip install "documint2md[markdown]"       # GFM Markdown formatting
python -m pip install "documint2md[pymupdf4llm]"    # alternate PDF Markdown engine
python -m pip install "documint2md[universal-lite]" # MarkItDown for extra formats
python -m pip install "documint2md[docling]"        # Docling structured conversion
python -m pip install "documint2md[ocr]"            # image and scanned-PDF OCR
python -m pip install "documint2md[all]"            # all published optional features

Python 3.11 or newer is required.

Command Line

Convert one file and write <input stem>.md beside it:

doc2md report.pdf
doc2md notes.docx
doc2md table.csv
doc2md scan.png

Choose an output path:

doc2md report.pdf -o report.md

Write Markdown to stdout:

doc2md report.pdf -o -

Preview without writing a file:

doc2md report.pdf --preview

Run several inputs non-interactively:

doc2md docs/*.pdf --yes

Open the interactive picker:

doc2md

Add selectable OCR text while keeping a scanned PDF's visible pages:

doc2md doctor ocr-pdf
doc2md ocr-pdf scan.pdf
doc2md ocr-pdf incoming/ -o searchable/ --yes

This feature uses a separately installed OCRmyPDF 15.2+ executable and Tesseract language data; it is not part of the PaddleOCR Python extra. The source is never overwritten, and the default result is scan.searchable.pdf using English and Spanish (eng+spa).

Merge a folder of photographed or scanned pages into one Markdown file:

doc2md ocr-folder ./scan --dry-run
doc2md ocr-folder ./scan -o book.md --cache-dir ./ocrcache

Pages are ordered by natural filename sort by default (--order exif|mtime are also available), downscaled to a 2000px long side before OCR for both speed and accuracy (--ocr-max-side), and --cache-dir makes long runs resumable. A single bad image is skipped and reported rather than discarding the run, but the command still exits 4 so a partial result is never mistaken for a clean one.

Add --page-numbers to recover each page's printed page number from margin geometry and insert it as a comment, and --scan-report FILE to write JSON describing scan-only defects (missing pages, unreadable captures, conflicting folios) without changing the exit code.

Correct OCR output with a deterministic, verified harness rather than a truncated guess:

doc2md split book.md -o chunks/ --per 15
# correct each chunk_NN.md into chunk_NN.corrected.md, then:
doc2md merge chunks/ -o corrected.md --audit audit.json

merge verifies every block is present, in order, and not shrunk beyond --max-word-loss, exiting 4 on failure, and writes a numeric audit of digits added or removed per block. doc2md lint FILE counts residual OCR-damage heuristics (repeated words, stray letters, rn-for-m, etc.), useful for comparing a document before and after correction. doc2md itself has no LLM in the loop; the correction step is performed by whatever agent or person runs the pipeline.

Agent and Automation Usage

Use --json when another program needs a structured result. Diagnostics still go to stderr, and stdout stays reserved for JSON in this mode.

doc2md report.pdf --json
doc2md report.pdf --dry-run --json

Useful automation flags:

doc2md report.pdf --quiet
doc2md report.pdf --debug
doc2md report.pdf --stats
doc2md doctor engines --json
doc2md doctor ocr-pdf --json

Exit codes:

  • 0: success
  • 2: usage or argument error
  • 3: unsupported format
  • 4: conversion failed
  • 5: output write failed

Output behavior:

  • By default, report.pdf writes report.md in the same directory.
  • -o <file> writes UTF-8 Markdown with \n newlines.
  • -o - writes Markdown to stdout.
  • Errors and diagnostics go to stderr.

Formats and Engines

Default conversions:

  • PDF: text extraction with pdfminer.six
  • DOCX: Mammoth HTML to Markdown
  • CSV: Pandas to Markdown table
  • Images: OCR when the ocr extra is installed

Force a format:

doc2md input.bin --format pdf
doc2md input.bin --format docx
doc2md input.bin --format csv
doc2md input.bin --format image

Use optional engines:

doc2md report.pdf --engine pymupdf4llm
doc2md slides.pptx --format any --engine markitdown
doc2md document.docx --format any --engine docling

Check installed optional engines:

doc2md doctor engines
doc2md doctor engines --json

Markdown Formatting

Every CLI conversion can post-process Markdown:

doc2md table.csv --md-style normalize
doc2md table.csv --md-style gfm
doc2md table.csv --md-style none
  • normalize is the default. It normalizes newlines, strips trailing whitespace, caps blank lines, and ends non-empty output with one trailing newline.
  • gfm formats GitHub Flavored Markdown and requires documint2md[markdown].
  • none leaves converter output unchanged after conversion.

OCR

Install OCR support:

python -m pip install "documint2md[ocr]"

Convert an image:

doc2md scan.png --ocr-lang en

Use OCR for scanned or low-text PDFs:

doc2md scan.pdf --ocr-mode auto --ocr-lang en
doc2md scan.pdf --ocr-mode always --ocr-layout heuristic --md-style gfm

Common OCR options:

doc2md scan.pdf --ocr-device cpu
doc2md scan.pdf --ocr-device gpu:0
doc2md scan.pdf --ocr-render-scale 2.0
doc2md scan.pdf --ocr-min-score 0.5
doc2md scan.pdf --ocr-debug-json debug.json
doc2md scan.png --ocr-debug-image debug.png

The first OCR run may download model files for the OCR backend. Subsequent runs are normally faster.

Python API

from doc2md import (
    any_to_markdown,
    csv_to_markdown,
    docx_to_markdown,
    image_to_markdown,
    pdf_to_markdown,
)

markdown = pdf_to_markdown("report.pdf")

Each public converter accepts str or PathLike input and returns str.

from doc2md import ConversionError, UnsupportedFormatError, pdf_to_markdown

try:
    markdown = pdf_to_markdown("report.pdf")
except UnsupportedFormatError as exc:
    print(f"Unsupported input: {exc}")
except ConversionError as exc:
    print(f"Conversion failed: {exc}")

Profiles

Store reusable defaults in doc2md.toml:

[profiles.fast_pdf]
format = "pdf"
engine = "pdfminer"
md_style = "normalize"

[profiles.ocr_pdf]
format = "pdf"
ocr_mode = "auto"
ocr_lang = "en"
ocr_layout = "heuristic"
md_style = "gfm"

Run with a profile:

doc2md report.pdf --profile fast_pdf
doc2md scan.pdf --profile ocr_pdf

Notes for Reliable Automation

  • Pin the package version in production, for example documint2md==2.1.0.
  • Use --json for structured status and -o - only when stdout should contain Markdown.
  • Use --yes for batch conversions in non-interactive jobs.
  • Use --md-style normalize or --md-style gfm when exact Markdown formatting matters.
  • Run doc2md doctor engines --json in setup checks to confirm optional engines are installed.

Links

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

documint2md-2.3.0.tar.gz (126.1 kB view details)

Uploaded Source

Built Distribution

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

documint2md-2.3.0-py3-none-any.whl (85.2 kB view details)

Uploaded Python 3

File details

Details for the file documint2md-2.3.0.tar.gz.

File metadata

  • Download URL: documint2md-2.3.0.tar.gz
  • Upload date:
  • Size: 126.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for documint2md-2.3.0.tar.gz
Algorithm Hash digest
SHA256 63fbede217cf294a65c69b32d71ea266f9e7e5325599d328aeeaa16ccacfa8f8
MD5 0f4d2641abb02ad68adb4ed364bdb65a
BLAKE2b-256 246f515153373cdecb2e700a07b6b4dad5c615f1841dda20e8c319b2635e67d7

See more details on using hashes here.

File details

Details for the file documint2md-2.3.0-py3-none-any.whl.

File metadata

  • Download URL: documint2md-2.3.0-py3-none-any.whl
  • Upload date:
  • Size: 85.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for documint2md-2.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 169f12ceda5eb60cae1d8f84c4f17ab5350a2b7d21b0dd4054af7455ec1059c8
MD5 6a0fa5bdd54b817ac39f71d26dce84bc
BLAKE2b-256 d8eaee837cc145f7b8f1f8b4ba8618248ece99c509fc58c1874fe6d0bfdfd163

See more details on using hashes here.

Release history Release notifications | RSS feed

2.4.0

2 files

This release

2.3.0 This release

2 files

2.1.0

2 files

2.0.2

2 files

2.0.1

2 files

2.0.0

2 files

1.0.1

2 files

1.0.0

2 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