# Why do footnotes point to the wrong place after PDF to EPUB conversion?

From sending every page to an LLM to using JEV to select suspicious pages: a look at how PDF Craft reviews footnote relationships in scanned books.

![Fine lines connect references in an old book page to footnotes, beside a reflowed reading page](https://pdfcraft.ai/en/images/blog/jev-footnote-review.webp "Conceptual illustration: conversion should preserve the link between body references and footnotes.")

I built PDF Craft to turn scanned book PDFs into Markdown or EPUB that people can actually read, search and organize. Recognizing the words is only part of that job. A number, circled symbol or asterisk in the body must still lead to the right note at the bottom of the original page. Otherwise the text reflows, but an essential reading relationship disappears.

This matters when working with older books, academic sources or a personal collection. A useful conversion should make the book searchable and comfortable on a smaller screen while keeping its references intact. For a practical review of an output file, see the [scanned PDF to EPUB guide](https://pdfcraft.ai/en/blog/scanned-pdf-to-epub/) and the [formula and footnote checklist](https://pdfcraft.ai/en/blog/check-formulas-footnotes-after-ocr/).

## OCR finds characters, not their roles

OCR can identify words on a page without knowing what those words do in a book. Small type near the bottom may be a footnote or simply body text that reached the margin. A raised circled number may be a reference marker or an ordinary list number. A note may be split into two blocks or continue onto the next page.

One wrong decision can produce strange EPUB behavior: a marker with no destination, two notes glued together, a page number inserted into a sentence, or the end of one page joined to the next page's running header. Footnotes have long been one of PDF Craft's hardest problems.

## First attempt: have an LLM read every page

About a year ago, the straightforward answer was to give each page to a large language model. It could often recognize that small text explained the body, interpret stars or Roman numerals as markers, and judge whether a sentence continued across a page break.

That was promising page by page, but painful across a long book. Hundreds of pages meant hundreds of calls, waits and possible retries. Cross-page decisions needed neighboring context, increasing the input further. Most pages were already correct: the expensive model spent much of its time reading a page only to say that nothing needed changing. It was also hard for a user to tell whether a long run was progressing or stuck.

## Build a complete deterministic path first

Later versions moved the main work back to OCR and deterministic rules. That path separates body text from notes, joins natural paragraphs, splits notes into individual citations and matches each body marker to its note. It is fast, repeatable and stable, and it handles most pages well.

But book layouts vary. Notes may sit at the foot of a page or between columns; markers may be digits or symbols; headers, page numbers and ornaments can enter the recognized text. Some decisions require understanding what a sentence means. Rules alone leave a few difficult cases, while an LLM on every page is too slow and costly.

## The change: ask JEV to inspect, not redo

The existing pipeline did not need replacing. It needed a quick quality check that could flag the pages worth a closer look. I placed JEV there and gave it a narrow question: **Can this page's analysis pass unchanged?** It does not rewrite text or explain every citation. It returns a probability used to decide whether the page proceeds or goes to an LLM for repair.

The unit of review is the whole page. If the algorithm misses a note entirely, a check that only visits known citations has nothing to inspect. A page-level judgment can still flag missing references, wrong ownership, unusual cross-page links or page numbers mixed into prose. I would rather send a few extra pages for review than silently pass a bad one: a false alarm costs another model check; a missed error can reach the final EPUB. The threshold still needs broader calibration.

```mermaid
flowchart TB
  accTitle: From page review to constrained repair
  accDescr: OCR and rules process a page first. JEV decides whether it can pass unchanged. Suspicious pages go to an LLM, then a programmatic integrity check. Passing pages continue to chapter assembly; failed repairs are retried.
  A[OCR and rules] --> B{JEV: page trustworthy?}
  B -- Yes --> F[Assemble chapters and output]
  B -- No --> C[LLM repairs current page only]
  C --> D{Integrity check}
  D -- Pass --> F
  D -- Retry --> C
```

## Let the LLM repair a page within strict bounds

For a flagged page, the LLM receives the text structure of three consecutive pages: previous, current and next. It may change only the middle page. Its neighbors provide context for sentences that cross page boundaries. I do not send page images at this stage: OCR already supplies text, positions and layout, and the task is semantic correction rather than another OCR pass.

The model may relabel body text, footnotes and page numbers, correct paragraph continuity and rematch markers to notes. It may not freely rewrite the source or change the page structure. Programmatic checks then require ordered note indices, matching references and notes, consistent links across page boundaries, and marker positions that can be found unambiguously in the specified text. A failed check returns concrete errors so the model can resubmit a complete result. Fewer retries are useful, but not a reason to weaken those checks.

## What a 26-page sample showed

In one test PDF with 26 pages and many notes, JEV selected 6 pages for the LLM. All six first submissions passed the integrity checks, and the 22 body-reference-to-note relationships that had already been correct remained intact.

The actual fixes were modest but important: printed page numbers had been mistaken for body text; one number had become a false bridge between paragraphs; and an introductory sentence had been merged with the indented quotation that followed it. The LLM used meaning and indentation to separate them.

This is one sample observation, not a document-wide accuracy or cost claim. Its lesson for me was that a good repair stage should preserve correct work and stop after fixing problems supported by evidence.

## Spend expensive judgment where it is needed

Deterministic processing handles most of the book. JEV rapidly selects suspicious pages. The LLM deals with the few cases requiring semantic judgment. Programmatic constraints protect the final structure. Repaired pages return to the same chapter assembly and Markdown or EPUB rendering path.

I still need to test more languages, layouts and longer books, especially JEV's missed-error rate and the threshold for LLM review. But the direction is clearer than it was a year ago: there is no need to make an LLM read every page to find a few errors hiding in the margins.

If you are converting a scanned book, start with a short sample containing notes in the [PDF Craft workspace](https://pdfcraft.ai/en/pdf-craft/). Check body markers, complete note text and paragraphs crossing page breaks before committing to the whole book.
