Convert PDF, Word, PowerPoint, HTML, email & 40+ formats to clean Markdown — and back. Built for LLMs, RAG & Python pipelines, with a built-in MCP server.
Обзор
all2md is a Python library command-line tool for turning many document formats into structured, LLM-friendly Markdown — and converting Markdown back into rich formats like DOCX, PDF, and HTML. Built on an AST-based pipeline, it's designed for RAG ingestion, LLM preprocessing, batch automation, and embedding document conversion directly into Python applications. That's it. For more formats, install only the extras you need — all2md[docx,html,xlsx] — or all2md[all] for everything. Every file command supports stdin/stdout via -, so you can pipe and chain: - for RAG, search, and preprocessing pipelines. - — convert to Markdown and back to rich formats (DOCX, PDF, PPTX, HTML, EPUB, …). - designed for embedding in apps and pipelines, not just CLI usage. - — batch conversion, preview, grep, semantic search, diff, and chunking. - — the core has no dependencies; install only the extras you need. - — add custom formats and AST transforms via a simple entry-point plugin system.
README
all2md
Convert PDFs, Office files, HTML, emails, spreadsheets, and 40+ other formats into clean, LLM-ready Markdown — and back again.
all2md is a Python library and command-line tool for turning many document formats into structured, LLM-friendly Markdown — and converting Markdown back into rich formats like DOCX, PDF, and HTML. Built on an AST-based pipeline, it’s designed for RAG ingestion, LLM preprocessing, batch automation, and embedding document conversion directly into Python applications.
📦 PyPI · 📖 Documentation · 💡 Examples
Quick start
# Install with PDF support (add more extras as you need them)
pip install "all2md[pdf]"
# Convert any document to Markdown (prints to stdout)
all2md report.pdf > report.md
# Go the other way — Markdown back to a rich format
all2md notes.md --out notes.docx
In Python:
from all2md import to_markdown
markdown = to_markdown("report.pdf")
That’s it. For more formats, install only the extras you need — all2md[docx,html,xlsx] — or all2md[all] for everything.
Common use cases
# Convert a PDF to Markdown for RAG / LLM ingestion
all2md paper.pdf > paper.md
# Batch-convert a directory (recursively) into a folder of Markdown
all2md ./docs --recursive --output-dir ./markdown
# Grep across mixed document types like they were plain text
all2md grep "revenue" reports/*.pdf
# Chunk a document for a RAG pipeline (JSONL with section + page provenance)
all2md chunk handbook.pdf --strategy semantic --max-tokens 512 --overlap 64
# Preview any document in your browser
all2md view proposal.docx
# Turn Markdown (e.g. an LLM's output) back into DOCX, PDF, or PPTX
all2md answer.md --out answer.docx
Every file command supports stdin/stdout via -, so you can pipe and chain:
curl -s https://example.com/doc.pdf | all2md - | grep "important"
Why all2md?
- Clean, LLM-friendly Markdown for RAG, search, and preprocessing pipelines.
- Bidirectional — convert to Markdown and back to rich formats (DOCX, PDF, PPTX, HTML, EPUB, …).
- Python-native API designed for embedding in apps and pipelines, not just CLI usage.
- A genuinely powerful CLI — batch conversion, preview, grep, semantic search, diff, and chunking.
- Lightweight by default — the core has no dependencies; install only the extras you need.
- Extensible — add custom formats and AST transforms via a simple entry-point plugin system.
Reach for all2md when you want a Python-first, automation-friendly document workflow with first-class LLM integration. Reach for Pandoc when you need maximum publishing breadth or advanced scholarly output (citations, bibliographies). They complement each other well.
Who is this for?
- LLM / RAG builders — convert source documents into chunkable Markdown with section and page provenance, ready for retrieval.
- CLI / automation users — batch-process mixed document collections, watch directories, and pipe conversions into any workflow.
- Python developers — embed document parsing and conversion directly into applications with a clean, typed API.
- Knowledge & documentation workflows — move content between formats and into portable Markdown, or generate static sites.
Example output
A PDF research paper in, structured Markdown out — headings, prose, and tables preserved:
# Efficient Retrieval Methods
## Abstract
We study retrieval-augmented generation across a range of...
## 1 Introduction
Retrieval-augmented generation (RAG) combines a retriever with...
| Model | Accuracy | Latency |
|-------|---------:|--------:|
| A | 91.2% | 40 ms |
| B | 93.8% | 65 ms |
Tables, multi-column layouts, and scanned pages (via OCR) are handled by the advanced PDF parser. See all2md report to score how much to trust any given conversion.
Word documents come out as Word shows them: tracked changes resolved by policy (--docx-revisions accept|reject|mark), comment threads with their anchors and replies, footnote and endnote bodies, field results, content controls, merged cells, and the list numbers and labels Word actually prints.
Supported formats
all2md uses a modular system — dependencies are only required for the formats you actually process.
- Documents: PDF, DOCX, PPTX, ODT, ODP, RTF, EPUB, FB2, CHM
- Web & markup: HTML, MHTML, Markdown, reStructuredText, AsciiDoc, Org-Mode, LaTeX, MediaWiki, Textile, DokuWiki, BBCode
- Data & spreadsheets: XLSX, ODS, CSV/TSV, JSON, YAML, TOML, INI, OpenAPI/Swagger
- Email: EML, MBOX, Outlook (MSG/PST/OST), Evernote (ENEX)
- Notebooks & code: Jupyter (IPYNB), plus nearly 200 source-code and config file types
- Archives: ZIP, TAR, TGZ, 7Z, RAR, and more
- Custom output: any text format via Jinja2 templates (DocBook XML, YAML, ANSI, …)
Run all2md list-formats to see everything on your install, or browse the full formats matrix.
Installation
The core library has no dependencies — install support for formats as you need them.
CLI (system-wide, no Python setup to manage):
uv tool install "all2md[all]"
Python library:
pip install "all2md[pdf,docx,html]"
Minimal (core only):
pip install all2md
Check what format support you have installed:
all2md check-deps
Command-line usage
The essentials:
all2md document.pdf # convert to Markdown on stdout
all2md report.docx --out report.md # write to a file
all2md notes.md --out notes.docx # Markdown → rich format (bidirectional)
all2md ./docs -r --output-dir ./out # recursively batch-convert a directory
all2md document.pdf --rich # render in the terminal (fancy `cat`)
all2md view document.pdf --theme docs # HTML preview in the browser
all2md grep "search term" documents/*.pdf # grep through any document format
Python API
The to_markdown() function is the easiest way to get started; convert() handles conversions between any two formats.
from all2md import to_markdown, convert
# Convert a file to Markdown
markdown = to_markdown("document.pdf")
# Fine-tune with typed options or plain keyword arguments
markdown = to_markdown("report.pdf", pages="1-3,5", flavor="gfm")
# Bidirectional conversion between any two supported formats
convert("input.md", "output.docx", target_format="docx")
convert("page.html", "page.pdf", target_format="pdf")
Chunking for RAG — convert and split in one call, keeping provenance most chunkers throw away:
import all2md
chunks = all2md.chunk("report.pdf", strategy="semantic", max_tokens=512, overlap=64)
for c in chunks:
print(c.chunk_id, c.section_heading, c.page, c.token_count)
record = c.to_dict() # flat dict — the same object emitted as JSONL by the CLI
AI integrations
all2md is built to sit inside LLM and agent workflows.
- RAG-native chunking —
all2md chunk(andall2md.chunk()) split any document into retrieval-ready chunks, each carrying its section heading/level and source page span so answers can cite where they came from. 11 strategies (semantic/heading/section/token/sentence/paragraph/word/line/char/code/auto); keep tables and code blocks whole; strip noisy elements. - MCP server — a built-in Model Context Protocol server lets AI assistants like Claude read, convert, search, diff, and outline documents directly. No wrapper scripts needed.
- Agent skills — pre-built skill files that teach AI coding assistants (Claude Code, Cursor, Windsurf, …) how to use all2md. Install with
all2md install-skills, or get the same guidance without installing anything viaall2md llm-help [topic].
CI quality gate
Most document tooling in CI answers “did it run?”. all2md ships a GitHub Action that answers “is the output still as good as it was?” — it scores every matched document and fails the build when fidelity degrades:
- uses: thomas-villani/[email protected]
with:
paths: docs/**/*.md
roundtrip-fail-under: 97
Measure your real floor before picking a threshold — all2md roundtrip docs/*.md --fail-under 1 prints it. Documents that convert well score 99–100, so a threshold that sounds strict (80, say) can have twenty points of dead headroom and never fire. The action warns you when that happens.
It also refuses to pass quietly: no matching files, no threshold set, or a document that cannot be converted at all are all failures rather than silent greens. The same gate works without the Action, in any CI system — see the full documentation.
Advanced features
Built on an AST-based pipeline (parse → transform → render), all2md offers capabilities that direct format-to-format converters can’t:
- Advanced PDF parsing — table recovery that goes beyond ruling lines (booktabs-style and fully borderless tables via word-gutter analysis, rotated tables read in their own frame), figure/caption binding, multi-column layout analysis, heading reconstruction (wrapped titles rejoined, adjacent headings kept apart), optional ML layout classification (
pdf_layoutextra), header/footer removal, and OCR for scanned pages (Tesseract or binary-free EasyOCR) — powered by PyMuPDF, measured against external ground truth (see below). - Conversion quality tooling —
all2md reportgives a reference-free confidence “quality card” for any document (usable as a CI gate);all2md roundtripscores how much structure survives aconvert → parse-backround trip;all2md optimizeauto-tunes converter settings for a difficult document. - Document diff — a
diffcommand that works like Unixdiffbut across any document formats, with text-based symmetric comparison. - Custom output via templates — render the AST to any text format (DocBook XML, YAML, ANSI, custom markup) using Jinja2 templates, no Python required.
- Static site generation — turn document collections into ready-to-deploy Hugo, Jekyll, MkDocs, Zola, or Eleventy sites.
- Extensible plugin system — add custom converters (
all2md.convertersentry point) and transforms (all2md.transformsentry point). See examples/plugins/. - Security-conscious — SSRF protection when fetching remote resources, archive validation (ZIP bombs, path traversal), and sandboxed HTML rendering.
How good is the conversion, measured?
all2md’s conversion quality is measured, not asserted — against three independent ground truths, each published beside a control that shows what the measurement looks like when it should fail:
- Born-digital PDFs (
benchmarks/pmc/): 66 publisher PDFs from PubMed Central scored against the JATS XML deposited beside them. Text recall, structural recovery of headings and tables, and an invented-text rate — with the corpus pinned by committed SHA-256 digests. - Scanned pages (
benchmarks/omnidocbench/): 981 raster pages against human annotation, exercising the OCR path the born-digital corpus never touches. - Round-trip fidelity (
benchmarks/roundtrip/): Markdown → format → Markdown must survive at fidelity 100 for the repository’s own docs, gated on every pull request.
Current figures, their controls, and — just as important — what each lane structurally cannot see are documented in Conversion Fidelity.
How does it compare to other converters? A fourth lane (benchmarks/comparison/) scores pymupdf4llm and Docling with the same instruments, on a corpus held out from the born-digital lane, with every tool’s output re-parsed through one normalization path. In the reading of 2026-08-29 — taken on a freshly drawn, sealed holdout against a corrected ground truth — all2md has by far the lowest invented-text rate (0.55%, vs 6.26% for pymupdf4llm, whose defaults now auto-OCR born-digital pages, and 2.05% for Docling), is the fastest of the three, and leads recall of what is attainable (97.3% to 97.1% and 96.2%), while Docling leads table cell preservation by 6.2 points (79.3% to 73.1%). The first reading on that holdout had put the table gap at 16.7 points; 7.1 of those were a ground-truth artifact that hid a whole class of table from every tool, and 4.1 were closed by row-grouping fixes since. What remains is diagnosed in the lane as a row-count difference — a learned table model against geometry rules — rather than a rule all2md is missing. Full results, ground rules, and the caveats that bound them are in that lane’s README and dated results-*.json snapshots.
Frequently asked questions
How is all2md different from Pandoc? all2md is Python-native, with a focus on programmatic use, LLM integration, and extensibility. Pandoc is more comprehensive for scholarly documents but is Haskell-based and CLI-focused. Use all2md for Python projects and AI workflows; use Pandoc for academic publishing — they complement each other well.
Can I convert back from Markdown to Word/PDF?
Yes — all2md is bidirectional. Use convert("input.md", "output.docx", target_format="docx"), or the CLI: all2md input.md --out output.pdf.
What’s the best format for feeding documents to LLMs?
Markdown with the gfm (GitHub Flavored Markdown) flavor — structured, consistent, and well-understood by LLMs. Use to_markdown(file, flavor="gfm").
Does all2md work with scanned PDFs?
Yes. Install OCR support (pip install "all2md[pdf,ocr]") and use --pdf-ocr-enabled (or OCROptions(enabled=True)). The default Tesseract engine needs the Tesseract binary; the binary-free EasyOCR engine is available via all2md[pdf,ocr-easyocr] and --pdf-ocr-engine easyocr.
Can I customize the output beyond Markdown? Yes — use Jinja2 templates to render any text-based format. See examples/templates/ for DocBook XML, YAML, ANSI terminal output, and more.
How do I add support for a new file format?
Create a parser class, define a ConverterMetadata object, and register it via the all2md.converters entry point in your pyproject.toml. See examples/plugins/ for a complete example.
How do I handle large document batches efficiently?
Use parallel processing: all2md ./docs -r --output-dir ./output -p 8, or --watch for incremental processing as files arrive.
Getting help
- Documentation: Read the full docs on ReadTheDocs
- Examples: Browse the examples/ directory, organized by use case
- Issues: Report bugs or request features on GitHub Issues
Contributing
Contributions are welcome — bug reports, feature requests, documentation improvements, and code. Ways to help: report bugs, improve docs, add support for new formats via the plugin system, create new AST transforms, or fix bugs in existing converters.
For contributors evaluating parser changes, all2md ships benchmark harnesses: benchmarks/pmc/ (born-digital PDF fidelity against publisher JATS ground truth), benchmarks/omnidocbench/ (scanned pages against human annotation), benchmarks/roundtrip/ (Markdown → AST → Markdown fidelity, the CI gate), benchmarks/corpus/ (conversion timing across public corpora), and benchmarks/comparison/ (third-party converters scored with the same instruments on a held-out corpus). See Conversion Fidelity and the Performance Tuning docs for details.
See CONTRIBUTING.md for development setup and guidelines.
License
This project is licensed under the MIT License. See the LICENSE file for details.
Установка
uvx --from all2md[allКонфигурация
{
"mcpServers": {
"all2md": {
"command": "all2md-mcp",
"args": ["--temp", "--enable-from-md"]
}
}
}