Answer: Open a PDF and this tool pulls out its text layer in your browser, without uploading it, and exports .txt or .md. Pick pages with specs like 1-3, 5 or odd. Scanned PDFs have no text layer and come out empty, so OCR them first.
Extract the text layer, export .txt or .md — nothing uploaded
## Quarterly Report, body The quick brown fox jumps over the lazy dog near the riverbank., closing 2026 results were strong. — 18 words, paragraph breaks kept, hyphenated line-ends rejoined. Pick pages (1-3, 5, odd, even) and export .txt or .md. One catch: scanned PDFs have no text layer, so they need OCR first.| PDF type | Text layer? | Extraction result |
|---|---|---|
| Exported from Word, LaTeX, InDesign | Yes, real text | Clean text, correct reading order, headings detectable by font size |
| "Print to PDF" from a browser or app | Yes, real text | Clean text; occasional odd line breaks in multi-column layouts |
| Scanned, then OCR'd | Text overlay on image | Mostly right; stray characters where the OCR guessed |
| Plain scan / photo PDF | No — image only | Empty output; needs OCR before extraction can work |
| Password-protected | Encrypted | Refused until you unlock the file with its password |
Every PDF that isn't a raw scan stores its visible words as text objects: strings plus placement matrices. pdf.js walks those objects page by page and hands the tool each fragment with its x/y position and font size. The pipeline then rebuilds reading order: fragments on the same baseline join into a line (sorted left to right), lines group into paragraphs using the file's own spacing — a gap noticeably larger than the page's typical line spacing starts a new paragraph — and, in Markdown mode, lines set in type at least 15% larger than the body become headings.
The pages box accepts all, odd, even, single pages like 7, and ranges like 1-3, mixed freely: 1-3, 5, 9-7 extracts pages 1, 2, 3, 5, 7, 8, 9 (reversed ranges flip automatically). Out-of-range numbers are rejected with the page count, so typos don't silently drop content.
Take a one-page report with a 22pt title "Quarterly Report", two body lines at 12pt set 18 points apart ("The quick brown fox jumps over" / "the lazy dog near the riverbank."), and a closing line 36 points below the second. The pipeline sees three body baselines plus one title: the 22pt line is 1.83× body size, so Markdown mode emits ## Quarterly Report. The 18pt gap matches the page's line spacing, so the two body lines reflow into one sentence; the 36pt gap is exactly twice the spacing, so a paragraph break lands before "2026 results were strong." The output is 18 words in three blocks, and with de-hyphenation on, a line ending "quarte-" followed by "rly results" rejoins into "quarterly results" with no space.
Plain mode runs the same paragraph rebuild but skips the heading markers and puts a single line break between blocks instead of a blank line. It doesn't keep one line per PDF line: wrapped body lines still join into sentences. For logs and invoices that's usually what you want, since a search for a phrase won't miss it because it happened to wrap.
The rebuild works from position and font size alone, so it does well on ordinary documents and makes predictable mistakes on unusual ones. We ran the page's own extraction code in Node.js against small test layouts. Each row below is real output from the default settings (plain text, hyphens rejoined), not a description of what should happen:
| What's in the PDF | What you get | Why |
|---|---|---|
| Two wrapped body lines, then a wider gap and a new paragraph | One joined sentence, a line break, then the next paragraph | Gaps up to 1.4× the page's usual line spacing join; wider gaps split |
| Two columns side by side | Left column line one Right column line one Left column line two… | Text within 2 points of the same height is treated as one line, across the whole page width |
| A table row: Item / Qty / Price | Item Qty Price Widget 4 $9.50 | Cells become words separated by spaces; column structure isn't kept |
| "co-" at a line end, "operate" on the next | cooperate | Any line ending in a hyphen is rejoined without a space |
| "well-" at a line end, "known" on the next | wellknown | Same rule; it can't tell a real compound from a word break |
| "2024-" at a line end, "2025" on the next | 20242025 | Same rule; switch "Line-end hyphens" to Keep for number-heavy files |
| A word stored one letter at a time | H e l l o | Each separately placed piece of text is joined with a space |
| A footnote number raised 4 points above the line | 1 Revenue grew 12% | It sorts as a higher line, so it lands at the start |
| Heading 15%+ larger than body text (Markdown mode) | ### Section title, or ## at 1.6× and up | Size is the only signal used |
| Bold heading at body size (Markdown mode) | A plain paragraph | Bold isn't read, only size |
| A scanned page with no text layer | Nothing | There's no text to read; OCR it first |
The two failures people hit most are columns and hyphens. For a two-column paper, extract it anyway and use it for searching or word counts, but don't expect readable prose without editing. For spreadsheets, price lists or anything full of ranges like 2024-2025, set line-end hyphens to "Keep as-is". You'll get co- operate in prose, but no numbers get glued together.
| Setting | Plain text (.txt) | Markdown (.md) |
|---|---|---|
| Headings | Kept as ordinary lines | ## or ### added by size |
| Between paragraphs | One line break | A blank line |
| Wrapped lines inside a paragraph | Joined | Joined |
| Page markers (when on) | --- Page 1 --- | <!-- page 1 -->, invisible when rendered |
| Best for | Pasting into email, search, word counts | Notes apps, wikis, feeding text to an AI tool |
One detail on page markers: they count the pages you extracted, in order, not the original page numbers. Extract pages 5 and 9 and the markers read Page 1 and Page 2. If you need to cite the source page, extract one page at a time or note the range you used.
Page specs are always output in document order. 9-7, odd on a 10-page file reads pages 1, 3, 5, 7, 8 and 9, top to bottom. A range past the end, such as 1-12 on a 10-page file, is rejected with "Page out of range 1-10" rather than silently trimmed, and anything that isn't a number, range or keyword, like 1to3, gets "Cannot read page spec".
Once you have the text, the word counter gives you a count and reading time, and Compare PDFs will show what changed between two versions. If the output came back empty, the file is a scan. Run it through OCR PDF first, then extract.
Open the PDF in a browser-based extractor and export. This tool reads the PDF's text layer with pdf.js on your own machine — pick pages if you only need a section, then copy the result or download it as .txt or .md. No account, no upload, no watermark.
A scan is usually just a photograph of the page with no text layer, and text extraction only reads real text. If the extraction returns nothing or gibberish, the document needs OCR first — optical character recognition turns the page image into text before anything can be extracted.
Reading order and paragraphs survive; fonts, columns, and exact layout do not. Markdown mode goes furthest — lines noticeably larger than the body text become ## and ### headings, hyphenated line breaks rejoin, and paragraph gaps are preserved from the spacing in the file.
Yes. Type a page spec like 1-3, 5 or use the shortcuts all, odd, and even. The extractor reads only those pages, which matters for long reports where you want chapter 2 and not 180 pages of appendices.
Extraction follows the PDF's internal text objects, which usually match visual order but don't have to — some generators emit text in drawing order rather than reading order. Multi-column layouts are the classic case. Reading a few lines tells you which kind of file you have.
No artificial limit. Because processing happens locally, the ceiling is your device's memory — reports of a few hundred pages extract in seconds. Password-protected files must be unlocked first, since the text layer can't be read while encrypted.
The extractor joins text that sits at the same height into one line across the full page width, so line one of the left column is followed by line one of the right column. The words are all there, and searchable, but the prose needs editing before it reads properly.
Glued words come from hyphen rejoining. Any line ending in a hyphen joins the next line with no space, so well-known split across lines becomes wellknown. Set line-end hyphens to Keep as-is to stop it. Spaced-out letters such as H e l l o mean the PDF stores each letter as a separate piece of text, and the extractor puts a space between pieces.