Converting PDF to Markdown in Python
Four libraries, what each is good at, and the licence question people usually find out about too late.
The quickest working version
pymupdf4llm is a thin wrapper over PyMuPDF that outputs Markdown
directly, and for most text PDFs it is all you need:
pip install pymupdf4llm
import pymupdf4llm
md = pymupdf4llm.to_markdown("report.pdf")
pathlib.Path("report.md").write_text(md)
It detects headings from font size, reconstructs tables, and handles multi-column layouts reasonably well. On a three-page document expect around 0.1 seconds.
The licence catch
PyMuPDF is AGPL-licensed. For internal scripts and personal work that is fine. If you ship it inside a product you distribute, or run it as a network service, the AGPL's terms reach further than most people expect — check before you build on it commercially. A paid commercial licence is available from Artifex.
When to reach for something else
| Library | Use it when | Cost |
|---|---|---|
pymupdf4llm | Text PDFs, speed matters, you want tables | Fast; AGPL |
marker | Academic papers, equations, high fidelity | Slow; downloads ML models |
docling | Complex layouts, careful reading order | Heavy dependencies |
pdfplumber | You want the raw words and coordinates | No Markdown output; you build it |
Scanned PDFs
None of these read a scan, because a scan has no text layer to extract. You
need OCR first — Tesseract via pytesseract, or PyMuPDF's built-in
OCR support, which shells out to Tesseract too. Detect the case rather than
returning an empty file:
doc = pymupdf.open(path)
chars = sum(len(p.get_text().strip()) for p in doc)
if chars < doc.page_count * 40:
... # it's a scan — OCR required
Things worth doing to the output
Raw extraction is rarely what you want to hand to a model or a wiki:
- Strip running headers and footers. A line appearing at the top or bottom of most pages is boilerplate. Keep the first occurrence so you never lose the document's only copy of its title.
- Strip page numbers — including combined forms like
Page 4 of 32, which a naive digits-only rule misses. - Repair mojibake. Broken font encodings turn en-dashes into replacement characters; a small substitution table fixes most of it.
Just need one file converted, not a script?
Convert it in your browserQuestions people ask
What is the best Python library to convert PDF to Markdown?
pymupdf4llm for most text PDFs — it outputs Markdown directly, detects headings and reconstructs tables, and is fast. Use Marker or Docling for academic papers and complex layouts, and pdfplumber when you want raw words and coordinates to build your own output.
Is PyMuPDF free for commercial use?
PyMuPDF is AGPL-licensed. That is fine for internal tools and personal scripts, but distributing it inside a product, or exposing it as a network service, triggers AGPL obligations. Artifex sells a commercial licence for those cases.
How do I convert a scanned PDF to Markdown in Python?
You cannot extract text from a scan because there is no text layer — run OCR first with Tesseract, via pytesseract or PyMuPDF's OCR support, then convert the result. Check for the case by counting characters per page before converting.