Skip to content

How Reliable Is MarkItDown for PDF-to-Markdown Conversion? What Works, What Breaks

Purpose

I was building a RAG pipeline and needed to turn a folder of PDFs into Markdown. Before I trusted Microsoft MarkItDown with the job, I wanted one answer: how reliable is its PDF-to-Markdown conversion?

Short answer: MarkItDown handles clean, text-heavy PDFs well. It gets unreliable with complex tables, equations, images, multi-column layouts, and scanned PDFs. It is optimized for LLM-friendly extraction, not visual fidelity.

MarkItDown PDF conversion side-by-side comparison

Environment

  • MarkItDown 0.1.7 installed with pip install "markitdown[pdf]"
  • Python 3.12
  • macOS
  • CLI: markitdown; Python API: MarkItDown().convert()

A note on versions: PDF parsing behavior can change between MarkItDown releases. The results below are for 0.1.7, so re-check the version you actually deploy before trusting it in production.

What happened?

This is a representative test, not a formal benchmark: I ran MarkItDown 0.1.7 on one PDF per category — plain text, headings, tables, equations, a two-column paper, a scanned document, and a chart-heavy report — with the same command for each:

convert-pdf.sh
pip install "markitdown[pdf]"
markitdown path-to-file.pdf -o document.md

Then I read each output and checked three things: what survived, what got lost or distorted, and whether an LLM could still use the result.

How the base PDF converter works

Before looking at the results, it helps to know what happens under the hood. The base PdfConverter in MarkItDown 0.1.7:

  • extracts text with pdfplumber per page and pdfminer for whole-document prose
  • joins the page text with double newlines
  • emits no page-break markers, no page numbers, and no layout structure
  • attempts to detect simple table or form-like structures via pdfplumber and emits some of them as Markdown tables — but merged cells, multi-row headers, and wide or nested layouts usually still lose their row/column relationships
  • has no equation extraction for PDFs (the only math support is the DOCX pre-processor)
  • does not reliably keep embedded images as usable references — the base path is text extraction, so chart and figure content does not come through as data or semantics

So the base converter is a text extractor. It is not a document renderer.

pdf-conversion-flow.txt
PDF input
|
v
pdfplumber / pdfminer text extraction
|
v
Text + best-effort table detection
|
v
Markdown (headings often plain text, simple tables as Markdown tables, complex layout flattened)

PDF Category Walkthrough

PDF typeWhat survivesWhat is lost / distortedUsable by LLM/RAG?
Simple text PDFAll text, reading orderNothing importantYes
Headings/listsText; headings may stay as plain textHeading hierarchy, list indentationYes (with cleanup)
Simple tableOften a usable Markdown tableMerged cells / wide layouts can lose alignmentMostly, verify
Complex tableText valuesRow/column relationshipsNo, verify or use a layout-aware parser
Equations/formulasRarely, often garbledMath semanticsNo
Two-column academic paperLinearized textInterleaved columns break reading flowRisky, needs inspection
Scanned PDFLittle/nothing (base converter)All content without the OCR pluginNo without OCR
Charts/images reportLittle chart meaningChart values, trends, relationshipsNo for facts, use a vision/multimodal parser

Simple text PDF

This is the best case. All text survives in order. The output is clean Markdown that an LLM can read directly.

Headings and lists

Heading inference is partial. In my test, the PDF heading hierarchy was not reliably rebuilt — headings sometimes came through as plain text on their own line rather than as ##-level titles. Lists mostly survive, but indentation can collapse when the source spacing is unusual. For RAG this is often recoverable, since chunk boundaries and page metadata can compensate for the missing hierarchy, but don’t assume the headings will be there.

Simple table

Simple, well-formed tables can come through as actual Markdown tables: the base converter uses pdfplumber to detect table or form-like structures. My simple table produced output close to this:

simple-table-output.md
| Quarter | Metric | Amount |
| --- | --- | --- |
| Q1 2026 | Revenue | 1.2M |
| Q1 2026 | Expenses | 0.8M |
| Q2 2026 | Revenue | 1.5M |
| Q2 2026 | Expenses | 0.9M |

MarkItDown output for a table PDF

That is usable. But the detection only goes so far: as soon as a table uses merged cells, multi-row headers, or unusual spacing, the structure can collapse back into reading-order text. If you rely on the table, verify the output before sending it to an LLM.

Complex table

With merged cells, multi-row headers, or wide columns, the detected structure degrades quickly. The flat text loses the relationship between rows and columns, and the correlations the table was built to express disappear. If the table carries the meaning, treat the output as unverified — and probably reach for a layout-aware parser instead.

Equations and formulas

Equations rarely survive. Math either disappears or turns into garbled text. This is the category I would not trust:

equation-output.md
E = mc2

MarkItDown output for an equations PDF showing missing or garbled math

The base converter has no PDF equation path. The only math support in MarkItDown is the DOCX pre-processor, which converts OMML to LaTeX — there is no PDF equivalent.

Two-column academic paper

Papers use two columns, and this is one of MarkItDown’s weakest cases for PDFs. The base converter linearizes the page in reading order, so the columns interleave: all the words are extracted, but the sentences are reassembled in the wrong order. A wrong reading order is not a cosmetic issue — it directly affects chunking, retrieval, and how well an LLM can follow an argument. My output looked like this:

two-column-flattened.txt
Introduction Neural networks have become
We propose a new architecture that reduces
Results show the model outperforms the
Conclusion Future work will explore
a core tool in NLP. This paper introduces
training time by 40% on standard benchmarks.
the baseline on three public datasets.
larger-scale experiments with the new design.

MarkItDown linearized output of a two-column academic paper

The words are all there, but the reading order is broken. An LLM might still extract isolated facts, but you must inspect the output before trusting it — and for retrieval, interleaved columns can silently corrupt chunk semantics.

Scanned PDF

A scanned PDF contains images of pages, not text. The base converter finds almost nothing:

scanned-pdf-output.md
(empty - no extractable text found)

MarkItDown output for a scanned PDF showing almost no content

This is a different capability from the base path: text extraction reads embedded text, while OCR reads rendered pixels. If you need to process scans, you have to add the separate markitdown-ocr plugin, which is LLM-backed:

scan-ocr.sh
pip install markitdown-ocr
scan-ocr.py
from markitdown import MarkItDown
from markitdown_ocr import OcrEngine
md = MarkItDown(ocr_engine=OcrEngine())
result = md.convert("scanned.pdf")
print(result.text_content)

The plugin renders each page and runs full-page OCR through an LLM-backed OCR engine, so it needs an LLM client configured (per the OCR plugin README linked in the references below). Without the plugin, the base converter has no OCR path for scanned documents — the two are separate capabilities, not interchangeable.

Charts and images report

Charts and figures are where the text-only assumption shows most clearly. Even when an image is embedded or referenced, the text path cannot describe what is inside it — the trend, the values, the relationship. My output carried little more than the figure titles, and sometimes not even that, depending on how the PDF stores the figures:

chart-report-output.md
Figure 1: Q1 Revenue Chart
Figure 2: Market Share Pie

MarkItDown output for a charts report showing only figure titles

If the report’s facts live inside the charts, this output does not carry them. That is a job for an OCR/vision-based or multimodal parser, not the base text converter.

Why “Ugly Markdown” Is Still Fine for an LLM

There is an important distinction: Markdown quality for LLM consumption is not the same as document reproduction quality.

A conversion can look messy to a human yet still be perfectly usable by an LLM. The opposite also happens: a silently dropped table or chart changes factual meaning. So judge the output by what the LLM needs, not by how it looks on a screen.

The Real Question: Is the Lost Information Important?

Almost every conversion loses something. The question that decides whether MarkItDown is the right tool is what exactly got lost — and whether the loss matters for the downstream task:

What is lostHow much it matters
Whitespace and exact spacingUsually fine
Fonts and visual layoutUsually fine for RAG
Heading hierarchyOften recoverable
Table relationshipsDangerous
Equation semanticsDangerous
Chart values and trendsDangerous
Reading order (e.g., multi-column)Dangerous

The first three are mostly cosmetic or recoverable. The last four change meaning — and when meaning changes, the Markdown looks fine but answers the question (or retrieves the chunk) incorrectly. That is the failure mode to guard against.

When I Would Not Use MarkItDown

I would skip MarkItDown’s base PDF path for:

  • Financial statements — table accuracy is critical, and lost row/column relationships change meaning
  • Scientific papers with equations — formulas disappear or change
  • Scanned contracts — no OCR in the base converter
  • Visually structured reports — layout carries information
  • Multi-column research papers — reading order breaks retrieval and comprehension
  • Any document where table, chart, or equation accuracy is critical

Alternatives Worth Knowing

For the hard cases, I look at layout-aware tools:

  • Docling — layout-aware PDF parsing that rebuilds tables and structure
  • PyMuPDF4LLM — layout-aware extraction designed for LLM/RAG input
  • OCR and multimodal/vision document parsers — for scanned and image-heavy documents

I am not going to turn this post into a full MarkItDown vs Docling vs PyMuPDF4LLM comparison — that deserves its own article. What I have seen so far is that each handles the cases MarkItDown misses, at the cost of more setup. I’ll link a dedicated side-by-side here when it is published.

How to Decide

My decision rule is simple:

decision-rule.txt
Clean, text-heavy PDF -> MarkItDown first (fast, simple)
Tables / layout / math -> inspect output, or use a layout-aware parser
Scanned / image-heavy -> OCR plugin or a vision/multimodal parser

Summary

In this post, I tested Microsoft MarkItDown 0.1.7’s PDF-to-Markdown conversion across real document types. The key point: it is a solid choice for clean, text-heavy PDFs, but you must verify output — or switch tools — for tables with merged cells, equations, scans, multi-column papers, and chart-heavy documents. The deciding factor is whether the lost information matters: lost whitespace and fonts are fine for RAG; lost table relationships, equation semantics, chart values, and reading order are not. Use MarkItDown first for simple documents; for complex PDFs, inspect the output or reach for a layout-aware parser, OCR plugin, or vision-based parser.

Final Words + More Resources

My intention with this article was to help others share my knowledge and experience. If you want to contact me, you can contact by email: Email me

Here are also the most important links from this article along with some further resources that will help you in this scope:

Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!

Comments