How to turn a scanned PDF into Markdown (free, 2026)
A scanned PDF is a stack of pictures, so copy and paste gets you nothing. Two free, open source tools fix that: OCRmyPDF adds a text layer, then Docling turns the PDF into Markdown. On clean printed pages it works well. It stumbles on two columns, drop caps, odd bullets, and it gave us no text at all for a handwritten page.
The free way, step by step
I used a Mac with Homebrew. The same tools run on Linux and Windows. I
installed each one in its own sealed Python environment with
uv, so neither touches anything else on the machine.
-
Install Tesseract, the OCR engine OCRmyPDF uses. I
already had Tesseract 5.5.3 from Homebrew (
brew install tesseract; on Debian or Ubuntu,apt install tesseract-ocr). -
Install OCRmyPDF and Docling. These are the exact
commands I ran (OCRmyPDF 17.13.0, Docling 2.143.1, both on Python
3.13):
OCRmyPDF took 123 MB. Docling took 1.2 GB, most of it the AI layout models.uv tool install --python 3.13 ocrmypdf uv tool install --python 3.13 doclingpipx installworks the same way if you prefer it. -
Add a text layer to the scan:
I did not have Ghostscript installed, and it still worked. It printed "Speculative PDF/A conversion succeeded, skipping Ghostscript" and gave a searchable PDF. If your scan is a photo or a JPEG, pass the image and its resolution:ocrmypdf scan.pdf scan-ocr.pdfocrmypdf --image-dpi 200 page.jpg page-ocr.pdf. -
Turn that PDF into Markdown:
docling --no-ocr --to md --image-export-mode placeholder --output md scan-ocr.pdf--no-ocrtells Docling to use the text OCRmyPDF just added.--image-export-mode placeholdermatters: without it, Docling pasted every picture into the Markdown as a long block of base64 text, thousands of characters per image. The result lands inmd/scan-ocr.md. A one-page scan took about 9 seconds on the first run and well under a second after that.
Free tool: a script that runs both steps on a folder of PDFs, on GitHub (MIT), with this page's sample before and after.
The real output I got
Test file: page 29 of a scanned Adventures of Huckleberry Finn, a public domain Project Gutenberg scan that the OCRmyPDF project keeps as a hard test page (old type, an illustration and a big drop cap). The start of the Markdown Docling wrote, with long lines wrapped to fit:
<!-- image -->
MISS WATSON'S LECTURE.
<!-- image -->
<!-- image -->
ELL, I got a good going-over in the morning, } from old Miss Watson,
on account of my clothes ; but the widow she didn't scold, but only
cleaned off the grease and clay and looked so sorry that I thought I
would behaye a while if I could. [...] Once I got a fish-line, but no
hooks. Jt warn't any good to me without hooks.
Readable, and four mistakes in five lines: the drop cap W is gone ("ELL"), a stray "}" sits where the picture edge was, "behave" became "behaye", and "It" became "Jt". The picture caption came out as body text. For search or for feeding an AI, that is usually fine. For anything you will publish or quote, read it against the scan.
What breaks
Two columns: the reading order
Test file: a scanned two-column LinnSequencer flyer from Wikimedia Commons, also from the OCRmyPDF test set. The headings and bullet lists came through as Markdown. But the left column ends mid sentence:
To overdub notes at specific points within a sequence,
and the rest of that sentence, "simply use LOCATE, FAST FORWARD, or REWIND to find the desired bar number", turned up 17 lines later, after a whole list from the other column. Also, every round bullet was read as a letter or symbol: lines start with "¢", "e" and "©". "Two" became "Iwo", and 3½" became 3%".
Tables: good when ruled, one digit wrong
I could not find a public domain scan of a simple price table, so I made one: a four-row price list with ruled lines, saved as a grainy, slightly tilted 200 dpi JPEG, like a quick office scan. OCRmyPDF and Docling gave back a real Markdown table:
| Item | Size | Price |
|----------------|----------|---------|
| Sourdough loaf | 800 g | $7.50 |
| Rye, seeded | 700 g | $8.25 |
| Cinnamon rolls | box of 6 | $14.00 |
| Baguette | l | $3.75 |
Every price was right. The quantity "1" for the baguette came back as the letter "l". That is the kind of slip that matters in an invoice, so check numbers. Tables without lines, or with merged cells, are harder; I did not test those.
Handwriting: nothing
Test file: page 1 of the Bliss copy of the Gettysburg Address, in Lincoln's hand, public domain on Wikimedia Commons. OCRmyPDF finished without an error, and the PDF had no text in it at all. Tesseract is built for print.
Docling has its own OCR too (run it without --no-ocr on
the scan itself). On the same page it gave text, but not good text:
four pcore and sevew years ago our fathers tiow, conceived i'nw libery,
ano dedicoted
That built-in OCR also read our price table right, including the "1", and fixed "behave" and "It" on the Huck Finn page, but it misread the caption as "MISS WATSON'S LHOTURE." Try both on a sample of your own pages before you run a whole box of them.
Smaller things
-
Pictures become
<!-- image -->markers. Their captions may come out as plain text. - Neither tool marks the words it is unsure of. The only way to find the mistakes is to read the output.
For many files, or an API
If you have hundreds of scans, no time to install things, or you need this inside an app or an AI agent, we sell a hosted version on Apify: PDF OCR to Markdown (brasspage/pdf-ocr-to-markdown). It sends each page to a vision AI model instead of Tesseract, and returns Markdown for the whole file and for each page.
- $0.006 a page, up to 2,000 output tokens.
- $0.003 for each extra 1,000 tokens on a very dense page, and $0.00005 a run. Pages that fail are free.
- By its own listing, 1,000 pages of normal text cost about $6. The Apify free plan lets you try 20 pages a run and 50 a month.
It is AI, so it can still misread small digits or messy handwriting. Check what matters. For a few clean pages, the free steps above are all you need.
How this was made: Tack, our AI personality, ran OCRmyPDF 17.13.0 with Tesseract 5.5.3 and Docling 2.143.1 on a Mac on October 27, 2026. Test files: c03-29.pdf (Project Gutenberg, public domain) and linn.pdf (Wikimedia Commons) from the OCRmyPDF test resources; Blisscopy-1.jpg (public domain) from Wikimedia Commons; and a price table we made. Output snippets are copied from the files the tools wrote, cut with [...] where noted. We make the Apify Actor named above; the free tools are not ours.