Quickstart

Convert a file

from doc2mark import load

result = load("report.pdf")
print(result.content)                  # the document as Markdown
print(result.metadata.format)          # DocumentFormat.PDF
print(result.metadata.page_count)      # 2

load() builds a UnifiedDocumentLoader, converts one file and returns a ProcessedDocument. The format comes from the file extension (see Supported formats). Nothing is sent anywhere: text, tables and structure are read from the file itself, OCR runs only when you ask for it, and so does the optional judge (unless the DOC2MARK_JUDGE environment variable turns it on, see Optional judge (TypeSafe / Jev)).

To convert many files, create the loader once and reuse it:

from doc2mark import UnifiedDocumentLoader

loader = UnifiedDocumentLoader()
for name in ["report.pdf", "report.docx", "slides.pptx", "data.csv"]:
    result = loader.load(name)
    print(name, len(result.content), "characters")

UnifiedDocumentLoader() sets up the OpenAI OCR provider by default, but it only needs the doc2mark[ocr] extra and OPENAI_API_KEY when a document is actually OCR’d; text-only conversions work without either. UnifiedDocumentLoader(ocr_provider=None) turns OCR off completely.

What you get back

from doc2mark import load

result = load("report.pdf")
for item in result.json_content[:4]:
    print(item["type"], item.get("level"), item["page"], item["content"][:40])

content is the Markdown. json_content lists the same content as typed items in reading order (text:title, text:section, text:normal, table, …), each with its page; it is what the chunker reads. metadata carries the file name, format, size, page count and format-specific fields, and metadata.extra reports what happened during the conversion (OCR routing, OCR problems, token usage). The result: ProcessedDocument describes every field.

Output formats

import json
from doc2mark import load

markdown = load("report.pdf").content                        # the default
as_json = load("report.pdf", output_format="json").content   # a JSON string
print(sorted(json.loads(as_json)))
plain = load("report.pdf", output_format="text").content     # Markdown markers removed

The JSON string is result.to_dict() serialised: content (the Markdown), metadata, images, tables, sections and json_content. The CLI’s --format json writes the same payload. "text" removes heading markers, bold, italics, links and code marks from the Markdown; tables stay as they are.

Reading scans and pictures (OCR)

Pass an OCR provider and ocr_images=True. Tesseract runs locally (doc2mark[ocr] plus the tesseract program, see Installation):

from doc2mark import UnifiedDocumentLoader

loader = UnifiedDocumentLoader(ocr_provider="tesseract")
result = loader.load("scan.pdf", ocr_images=True)
print(result.content)
print(result.metadata.extra["ocr_routing"])   # {'document_route': 'image', 'overrides': []}

The LLM providers read tables, forms and handwriting much better and return structured results (OCR):

from doc2mark import UnifiedDocumentLoader

loader = UnifiedDocumentLoader(ocr_provider="openai")      # reads OPENAI_API_KEY
result = loader.load("scan.pdf", ocr_images=True)

ocr_images=True implies extract_images=True. doc2mark then decides page by page what needs OCR: pages with a usable text layer keep their text, scanned or garbled pages are OCR’d from a render, and pictures are OCR’d when they carry something to read (When pages and pictures are OCR’d).

A folder of documents

from doc2mark import UnifiedDocumentLoader

loader = UnifiedDocumentLoader(ocr_provider=None)
results = loader.batch_process("documents", output_dir="converted", max_workers=4)
for path, info in results.items():
    print(info["status"], path)

Every supported file under documents/ (recursively) is converted and written to converted/ as .md, keeping the folder structure. See Loading documents for the result dictionaries, explicit file lists and progress callbacks.

From the command line

doc2mark report.pdf -o report.md
doc2mark scan.pdf --ocr tesseract --ocr-images -o scan.md
doc2mark documents/ -r -o converted/ --skip-errors

Command line lists every option.

Next steps