Add paragraph index LUT for accurate KOReader position sync

Store per-page paragraph indices in section cache to enable precise
XPath-to-page and page-to-XPath mapping without reparsing XHTML.

Forward path (upload): generates XPath directly from paragraph LUT
instead of byte-offset estimation, eliminating drift in chapters
with non-uniform content density.

Reverse path (download): resolves incoming KOReader XPath p[N] to
the exact page via paragraph LUT lookup.

Paragraph counter counts all <p> elements including display:none
to match ChapterXPathIndexer and crengine's standard XPath counting.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
jpirnay
2026-03-22 12:29:26 +01:00
co-authored by Claude Opus 4.6
parent dccb82642d
commit b625b8bd26
17 changed files with 354 additions and 43 deletions
+10
View File
@@ -42,4 +42,14 @@ class Section {
// Look up the page number for an anchor id from the section cache file.
std::optional<uint16_t> getPageForAnchor(const std::string& anchor) const;
// Look up the page number for a paragraph index (1-based, from XPath p[N]).
// Uses the per-page paragraph index LUT stored in the section cache.
// Returns nullopt if the paragraph LUT is not available (old cache format).
std::optional<uint16_t> getPageForParagraphIndex(uint16_t pIndex) const;
// Look up the paragraph index for a given page number.
// Returns the 1-based paragraph index of the last <p> element on or before the page.
// Returns nullopt if the paragraph LUT is not available (old cache format).
std::optional<uint16_t> getParagraphIndexForPage(uint16_t page) const;
};