How to Convert PDF to Markdown with Python

Learn how to convert text-based and scanned PDFs into usable Markdown with Python, including extraction, OCR, cleanup, validation, and production tips.

By gettxt.aiPublished Updated

Converting a PDF to Markdown with Python is useful when documents need to move into a knowledge base, documentation site, or retrieval-augmented generation pipeline. PDFs describe visual layout, while Markdown describes structure, so a reliable workflow must account for headings, lists, tables, code, and scanned pages.

1. Decide whether the PDF needs OCR

A digitally generated PDF usually contains selectable characters. A scan may contain only page images. Test a few pages before choosing a parser. If native extraction returns almost no text, route the document through OCR instead of trying to repair an empty result.

For a small prototype, install PyMuPDF:

pip install pymupdf

For scanned PDFs, install an OCR engine such as Tesseract separately, or use a hosted document-extraction API that combines OCR and layout analysis.

2. Extract a Markdown draft

This conservative example extracts a text layer and keeps page boundaries visible for debugging and citations:

from pathlib import Path
import fitz

def pdf_to_markdown(pdf_path: str) -> str:
    document = fitz.open(pdf_path)
    pages = []
    for number, page in enumerate(document, start=1):
        text = page.get_text('text').strip()
        if text:
            pages.append(f'<!-- page {number} -->\n\n{text}')
    if not pages:
        raise ValueError('No text layer found; use OCR for this PDF')
    return '\n\n'.join(pages) + '\n'

Path('output.md').write_text(pdf_to_markdown('input.pdf'), encoding='utf-8')

This is a starting point rather than a complete layout reconstruction. Multi-column PDFs may extract in the wrong order, and tables may appear as plain lines. For structure-sensitive documents, inspect blocks or words and apply layout-aware parsing.

3. Clean the extracted text

PDF extraction can introduce repeated headers, broken words, excessive blank lines, and hyphenation at line endings. Keep cleanup rules conservative. Remove known headers and footers only after checking page numbers; join lines inside paragraphs while preserving blank lines around headings; normalize Unicode whitespace; and protect URLs and fenced code blocks. Convert data to a Markdown table only when column boundaries are reliable.

Do not infer missing text because a paragraph looks incomplete. Record warnings and send low-confidence pages through OCR or human review.

4. Handle scanned PDFs

For a scan, render each page at a suitable resolution, run OCR, and pass the recognized text through the same normalization and validation steps. OCR quality depends on resolution, language, skew, contrast, and source type. Tables, handwriting, and multi-column layouts need dedicated tests.

For a production pipeline, an API can avoid maintaining OCR binaries, language models, and worker capacity. The PDF to Markdown API is an option when you need OCR and structured output without local document-processing infrastructure.

5. Validate before indexing

Before writing Markdown to a repository or vector store, check that the output is non-empty, has a reasonable character count per page, contains the expected title or headings, preserves URLs and code fences, and has the expected table columns. Store the original PDF and extraction metadata alongside the Markdown so results remain reproducible when a parser changes.

Common mistakes

The most frequent mistake is treating every PDF as a text file. Another is assuming that visually aligned text automatically becomes a Markdown table. Indexing raw output without removing repeated navigation also harms retrieval quality. Test a regression corpus containing scans, tables, columns, footnotes, and code instead of relying on one sample file.

Conclusion

A good Python PDF-to-Markdown workflow is conditional. Use native extraction when the text layer is trustworthy, OCR when the document is image-only, layout-aware processing for tables and columns, and validation before publishing or indexing. PyMuPDF is a useful foundation for scripts, while an OCR and document-extraction API can reduce operational work for mixed-document production pipelines.

Related guides