> Source: https://txtfetch.com/fixes/columns-out-of-order > Plain-text twin — every page on txtfetch.com has one. https://txtfetch.com/text --- # My two-column PDF extracted with both columns mixed together. Every word from the page is usually still present, just not in the order a human reader would encounter it. That's a reading-order failure, and it's worse than missing text because it reads as plausible. looks-like ``` Revenue grew 34% year over year, driven by The board approved a new enterprise pricing tier and a hiring plan targeting engineering and sales ``` Two unrelated sentences from the left and right columns, spliced together mid-thought because both sit at the same height on the page. why-it-happens A two-column PDF page is drawn as two separate vertical blocks of text. But the underlying content stream doesn't necessarily record "block" as a concept. It records individual text-showing operations at (x, y) positions. An extractor that reads those operations in file order can interleave line one of the left column with line one of the right column. So can one that sorts primarily by vertical position with nothing reliable to break ties. That happens because both lines sit at roughly the same height on the page. The result reads as one long line that's actually two unrelated sentences spliced together mid-thought. This is genuinely worse than getting no text at all, because it looks plausible enough to pass a casual review before it's embedded. This is fundamentally a reading-order problem, not a missing-data problem. Every word from the page is usually present in the output somewhere, just not in the order a human reader would encounter them. confirm-it - Paste extracted text into the chunk previewer. A single line over 300 characters with no sentence-ending punctuation is flagged as a likely interleaved-column collapse. [Scan for collapsed long lines](https://txtfetch.com/tools/chunk-preview) fix-it-yourself Re-extract with layout-aware column detection pdftotext's -layout mode detects column boundaries from horizontal gaps. It preserves left-to-right, top-to-bottom reading order within each detected column. bash ``` pdftotext -layout input.pdf output.txt ``` Bucket words into columns yourself for persistent cases pdfplumber exposes each text object's bounding box directly. You can group words by horizontal position into columns, then sort each column top to bottom, when the built-in reflow still gets it wrong. python ``` import pdfplumber with pdfplumber.open("input.pdf") as pdf: for page in pdf.pages: words = page.extract_words() # bucket by word["x0"] into columns, then sort each column by word["top"] ``` what-txtfetch-does The default extraction runs Apache Tika's PDF parser (PDFBox underneath), which does layout-aware text extraction rather than raw stream order. That recovers correct reading order on most ordinary multi-column documents. But it isn't guaranteed on an unusual or irregular column structure. When it does get a document's columns wrong, pass ?quality=premium. Every page then routes through a vision-language model instead of Tika's text pass. That model reads the page the way a person does, rather than inferring order from glyph coordinates. Two caveats are worth knowing up front, both real. Premium always routes async, even for a one-page PDF, so expect a 202 response and a job\_id to poll rather than a synchronous body. If a cost or size guardrail trips, or the model call fails, the request safely falls back to the Tika baseline instead of erroring. That fallback is flagged as metadata.tier\_downgraded: true, with a downgrade\_reason. The gap between the two is measured, not asserted, though on a deliberately small slice. On the multi-column PDF in our benchmark corpus, reading-order fidelity goes from 50.0% at the standard tier to 100% at the premium tier. That premium figure covers only the 3 hardest documents in the corpus, not the whole 10-document set. See /benchmarks for the full methodology, the per-category breakdown, and the corpus caveats. what-it-costs-you-downstream Two columns spliced into one line get packed into the same chunk in the wrong order. A chunker has no way to know they're unrelated, so the resulting embedding represents neither column's actual meaning. An answer synthesized from that chunk risks blending two unrelated claims into one confident-sounding but wrong sentence. faq **Is column-scrambled text a missing-data problem?**: Usually not. Every word is typically still present in the output, just in the wrong order. The extractor read across columns instead of down one column at a time. That distinction matters for how you fix it: reordering, not re-extracting from scratch, is usually all that's needed. **Does layout-aware extraction always get column order right?**: It gets most ordinary two- and three-column layouts right by detecting horizontal gaps between columns. Unusual layouts, like overlapping text boxes, sidebars, or pull quotes breaking the column grid, can still confuse it. That's when a library like pdfplumber that exposes raw word positions becomes worth reaching for. **Can I pass a parameter to txtfetch to fix column order?**: Yes. Pass ?quality=premium and every page routes through a vision-language model instead of Tika's coordinate-based text pass. That's the case multi-column layouts benefit from most. Premium always routes async, so you get a 202 response and a job_id to poll instead of a synchronous response. It falls back to the Tika baseline (flagged metadata.tier_downgraded: true) if a guardrail trips. There's no plan-level gate; every plan can request it. **Should I use ?format=markdown or ?format=json for a multi-column document?**: They solve a different problem. Format controls the SHAPE of the response: GFM markdown, or a typed element tree with per-element page and offset. Quality controls which engine reads the page instead. Both ship on the standard tier. If the underlying reading order is wrong, a different output shape won't fix it. Reach for ?quality=premium for that, optionally alongside the format you want. related-reading - [Docs: the premium quality tier →](https://txtfetch.com/docs#premium-quality) - [Measured reading-order accuracy →](https://txtfetch.com/benchmarks) - [Tables losing structure →](https://txtfetch.com/fixes/tables-lose-structure) - [Chunk previewer →](https://txtfetch.com/tools/chunk-preview) - [See the actual text: a two-column report, raw vs. corrected →](https://txtfetch.com/diff#pdf-complex-financial-report) Layout & structure - [PDF or scanned tables flatten into unreadable space-separated text →](https://txtfetch.com/fixes/tables-lose-structure) - [the same header, footer, or page number shows up in every chunk →](https://txtfetch.com/fixes/headers-and-footers-in-every-chunk) - [extracted text is hard-wrapped at the print page's line width →](https://txtfetch.com/fixes/hard-wrapped-lines) - [extracted text is one giant undifferentiated blob with no paragraph breaks →](https://txtfetch.com/fixes/no-paragraph-breaks) - [All fixes →](https://txtfetch.com/fixes) ## Fix the text you already have. The free cleaner repairs this damage in your browser. Nothing leaves the page. [Clean up your text →](https://txtfetch.com/tools/clean-extracted-text) [Get an API key →](https://app.txtfetch.com/signup)