Skip to content

Build1 publisher3 min readPublished

Sorting PDF extraction fixes into three buckets beats estimating by page count

A developer counted every place the extracted text of seven documents needed a fix and sorted each into three repair buckets. Typography and scan quality set the count, and each bucket has its own cost.

The Engineer · Build desk

Illustration accompanying Sorting PDF extraction fixes into three buckets beats estimating by page count

What happened

  • Seven English documents went through ImgIng's Extract PDF content extractor with OCR set to Auto, and the output was compared against the printed pages by hand over the course of a day.
  • Every place needing a fix went into one of three buckets: a script can fix it, a person has to look at the page, or the page should be rendered and OCR'd again.
  • One page of a book printed in 1734 needed more fixes than two pages of an arXiv preprint, and the kind of fix mattered more than the number of them.
  • On a page from 1921, 34 justified lines came out of the extractor as two Tab-separated cells, as if the paragraph had been a table.

Compiled by The EngineerSomething wrong?How this is made

Why it matters

  • decision Something has to label a page as prose before the Tab-to-space rule runs, because the same rule pointed at the weekly report would flatten a sales table the extractor had correctly split into columns.
  • constraint Choosing re-OCR from a page's total spot count can buy a layout fix and pay for it in fresh letter errors, so the counts have to be kept per class to be usable.
  • exposure Chart values reach the text with their day labels gone, so an index built on the output holds figures nobody can attach to anything without opening the page image again.
  • cost The review bucket is priced in a person's time with the image on screen, and the post counts spots rather than minutes, so a rate per class has to come from your own reviewers.

Each bucket has a different unit cost, and the cheap one comes with preconditions.

The author's script has three rules. The first joins a lowercase fragment ending in a hyphen to the lowercase word that opens the next line, and prints every pair it joined so a person can skim the list [9]. The arXiv pages carried 42 words broken across a line end, and the rule made 40 joins [7][10]. Two of those joins were wrong: "open-/source" came out as "opensource", and both breaks inside RAG-Safety-Bench were left alone because a capital follows, which the author counts as 3 of the 42 still needing eyes [11]. So 39 of 42 came out right, or 93 percent [3]. Keeping a wrong join visible costs one line of stdout.

The re-OCR bucket is where a page total misleads. The 1734 page ran on the book's own embedded tesseract layer, and 22 of its spots were words that had gone missing or moved to another line [21]. Rendering the page as an image and running OCR on that took it from 55 spots to 15, 40 fewer [22][1]. The 1921 page went from 41 spots to 10, which the author attributes to the Tabs disappearing, while its letter-level errors rose from 3 to 6 [23].

The bucket that needs a person is small and stubborn. On the synthetic scan the hidden text layer said "24 stores" and the image said "42 stores"; the extractor kept both lines, and only a person can say which is right [15]. The two-column report had four lines fused with no separator, like "Finance4. Result", so no regex knows where to cut [16]. One kanban card came back as OPS-416 with no title [18], and the lecture notes lost the estimate symbol entirely, leaving e = y - . [19]. "You can't repair a sentence whose words are shuffled without the page beside you, and at that point you're retyping," the author wrote [27].

How far these counts travel is limited by how they were made. Four of the seven documents were generated by the author with invented content, so the ground truth is known line by line, and the two scanned pages were transcribed by hand and compared with Python's difflib, which counts a moved phrase twice, once where it went missing and once where it landed [24]. On a page whose words are shuffled, that inflates the number you would use to justify re-OCR. Per-page totals appear only for those two scanned pages, 55 and 41 [22][23]; the rest of the post reports counts by class, such as the 42 line-end breaks across pages 1 and 2 of the preprint, 21 a page [4].

An estimate in pages prices all of this at one rate. In a single run, four documents landed in three different buckets: the 1734 page needed re-rendering and a second OCR pass [21][22], the arXiv and 1921 pages were mostly script work [10][12], and the two-column report needed a person with the page image open [16][20].

What to watch

  • A repeat run on a second extractor would show whether these class mixes belong to the documents or to one tool's OCR-on-Auto defaults.
  • Per-page totals for the five documents where only class counts are published would settle how wide the spread really is at the low end.
  • Whether a prose-or-table page classifier can be automated reliably, since the Tab rule depends on that label being right.
Loading claim ledger
Loading source directory links
Loading share composer
Loading topic controls
Loading related stories