PDF to Markdown Converter

Choose a PDF and this tool reads its text layer in your browser, then rebuilds it as Markdown: bigger type becomes headings, bullets become lists, and link areas become real links. Pick a page range, check the result, and copy it or save a .md file. Scanned pages need OCR first.

What converts well and what does not
PDF contentResultNotes
Headings set in larger typeGoodUp to three heading levels by font size
Body paragraphsGoodLine breaks inside a paragraph are joined
Bulleted and numbered listsGoodCommon bullet characters and 1. or 1) numbering
Links with a clickable areaGoodOnly when the PDF stores the link
TablesApproximateCells come out as text in reading order
Scanned pagesNo textRun OCR first; there is no text layer to read

Updated

Markdown is the easiest format to paste into an AI tool, a docs site or a README, because it keeps structure without layout noise. A PDF stores positioned glyphs rather than paragraphs, so the converter has to guess the structure back. It uses PDF.js, Mozilla's open-source PDF engine, to read every text run with its size and position, then groups runs into lines, lines into blocks, and labels each block.

Convert a PDF to Markdown

Choose a PDF to begin. It is read on this device with PDF.js; nothing is uploaded.

Doing the same with PDF.js in your own project

PDF.js is released under the Apache 2.0 licence. The calls below are the ones this tool builds on.

Read text runs with size and position

Each item carries its string, a transform matrix whose last two numbers are x and y, and a height that tracks the font size.

import * as pdfjs from "pdfjs-dist";
pdfjs.GlobalWorkerOptions.workerSrc = new URL("pdfjs-dist/build/pdf.worker.min.mjs", import.meta.url).toString();

const pdf = await pdfjs.getDocument({ data: await file.arrayBuffer() }).promise;
const page = await pdf.getPage(1);
const { items } = await page.getTextContent();
for (const it of items) {
  const [, , , , x, y] = it.transform;
  console.log(Math.round(it.height), Math.round(x), Math.round(y), it.str);
}

Find stored links on a page

Link annotations give a rectangle and a URL; text runs inside that rectangle become the link text.

const links = (await page.getAnnotations())
  .filter((a) => a.subtype === "Link" && a.url)
  .map((a) => ({ url: a.url, rect: a.rect }));

How the structure is rebuilt

First the tool finds the most common type size across the selected pages and treats it as body text. Any line set noticeably larger becomes a heading, and the largest sizes get the fewest # marks.

Lines that sit close together merge into one paragraph, and a word broken with a hyphen at a line end is joined again. A bigger vertical gap starts a new paragraph. Lines that begin with a bullet or a number followed by a dot or bracket turn into list items.

When to use something heavier

Academic papers with equations, invoices built from tables and slide decks exported to PDF all lose structure in any text-layer converter. For those, a layout-aware tool or OCR model that looks at the rendered page will do better, at the cost of running on a server.

For reports, manuals, articles and contracts, the text layer is usually enough and stays private on your device.

How it works

  1. Choose a PDF or drop it on the box. It is read by your browser only.
  2. Set the first and last page if you only need part of the document.
  3. Press Convert. Headings are picked from type that is clearly larger than the body text.
  4. Check the Markdown in the output box, then copy it or download it as a .md file.

Tips

  • If headings come out as plain text, the PDF probably uses bold body-size type for them; add the # marks by hand.
  • Multi-column layouts can interleave lines from both columns. Convert a single page first to check the reading order.
  • Strip page headers, footers and page numbers before feeding the text to an AI tool; they repeat on every page and waste tokens.
  • Count the result with our token counter before pasting a long document into a prompt.

Frequently asked questions

Is my PDF uploaded?

No. PDF.js runs inside this page and in a background worker on your device. The file is never sent to a server, which makes the tool safe for contracts and internal documents.

Why is the output empty?

The PDF is most likely a scan or a photo of pages, which holds images rather than text. Run it through OCR software first, such as the text recognition built into many scanner apps, then convert the result.

Does it keep tables?

Only roughly. PDFs do not mark table cells, so each row usually arrives as a line of text with the cells separated by spaces. Rebuild important tables by hand with our Markdown table generator.

Are images and bold text kept?

Images are skipped, and bold or italic styling is not carried over, because the text layer does not reliably say which runs are emphasised. Headings, lists, paragraphs and stored links are kept.

Why convert a PDF to Markdown for AI tools?

Plain Markdown is compact, and the headings help a model see how the document is organised. It also lets you cut the parts you do not need before pasting, which keeps prompts shorter.

Related: HTML to Markdown converter, Markdown cheat sheet, llms.txt generator, Token counter, Markdown to PDF.

Start for free or see all free tools. We.Inc is free to start, with no card needed. AI building is on paid plans from $20 a month.

More in Free Tools

Product

Who It's For

Features

Resources

Company

View Sitemap