Research CommonsResearch Commons
docparser/PDF backends & OCR

PDF backends & OCR

Choose a PDF conversion backend, OCR scanned pages, and extract real tables with docparser.

PDFs are the hardest format to parse well, so docparser makes the PDF path configurable: a built-in PyMuPDF reader by default, with pluggable higher-fidelity backends, optional OCR, and optional table extraction.

Built-in backend (default)

Out of the box ([pdf] extra), PDFs are parsed with PyMuPDF:

  • Page-by-page text extraction in reading order via the blocks API.
  • Best-effort heading detection from font size (≥120% of the body-text median promotes a line to a heading; bold flag tracked).
  • Embedded raster images extracted via doc.extract_image(xref).

Pluggable backends

Route conversion through a higher-fidelity engine with backend= (library) or --pdf-backend (CLI). Their Markdown is normalized into the same block schema, and images are still extracted via PyMuPDF.

BackendExtraLicenseNotes
builtin[pdf]MITPyMuPDF reader (default).
pymupdf4llm[pymupdf4llm]AGPL/commercialPyMuPDF4LLM Markdown conversion.
docling[docling]MITIBM Docling.
marker[marker]GPL-3.0Datalab Marker.
from docparser import parse_pdf, WorkspaceLayout
 
layout = WorkspaceLayout.under(".")
payload = parse_pdf("paper.pdf", layout, backend="docling")
Mind the license

pymupdf4llm (AGPL/commercial) and marker (GPL-3.0) carry stronger licenses than the MIT core. Use builtin or docling if you need to keep an MIT-only dependency footprint.

OCR (scanned PDFs)

For scanned or low-text pages, enable OCR with the [ocr] extra (rapidocr-onnxruntime):

docparser parse paper.pdf --ocr auto --no-vlm
  • ocr="off" — no OCR (default).
  • ocr="auto" — OCR pages that look scanned / low-text.
  • ocr="force" — OCR every page.

OCR'd blocks carry "ocr": true in the JSON so you can tell recognized text apart from extracted text.

Table extraction

With the [tables] extra (pdfplumber), emit real table blocks instead of flattened text:

docparser parse paper.pdf --pdf-tables --no-vlm
payload = parse_pdf("paper.pdf", layout, extract_tables=True)

Putting it together

docparser parse paper.pdf --pdf-backend docling --ocr auto --pdf-tables --no-vlm

Next