Merge pull request #130 from jpirnay/fix-kosync-upload
fix: Reestablish 1.37 kosync upload behaviour
This commit is contained in:
@@ -38,12 +38,16 @@ via a KOReader contributor mapping spine items to DocFragment numbers.
|
||||
Implemented in `ProgressMapper::toKOReader`.
|
||||
|
||||
1. Compute overall `percentage` from chapter/page.
|
||||
2. If a paragraph index is available from the section cache LUT (`CrossPointPosition::hasParagraphIndex`),
|
||||
generate an XPath directly: `/body/DocFragment[spineIndex + 1]/body/p[paragraphIndex]`.
|
||||
3. Otherwise, attempt byte-offset estimation via `ChapterXPathIndexer::findXPathForProgress`.
|
||||
4. If XPath extraction fails, fallback to synthetic chapter path:
|
||||
2. Generate XPath via byte-offset estimation (`ChapterXPathIndexer::findXPathForProgress`),
|
||||
producing a `…/text()[K].M` anchor proportional to intra-spine progress.
|
||||
3. If XPath extraction fails, fallback to synthetic chapter path:
|
||||
- `/body/DocFragment[spineIndex + 1]/body`
|
||||
|
||||
The paragraph LUT (see below) is intentionally **not** used for upload: snapping to the
|
||||
start of `p[N]` when the user is mid-paragraph causes pulled positions to land at the
|
||||
start of the paragraph (and at the start of the chapter when an opening paragraph spans
|
||||
many pages). The LUT remains in use for the reverse direction.
|
||||
|
||||
### KOReader -> CrossPoint
|
||||
|
||||
Implemented in `ProgressMapper::toCrossPoint`.
|
||||
|
||||
@@ -57,24 +57,11 @@ KOReaderPosition ProgressMapper::toKOReader(const std::shared_ptr<Epub>& epub, c
|
||||
// Calculate overall book progress (0.0-1.0)
|
||||
result.percentage = epub->calculateProgress(pos.spineIndex, intraSpineProgress);
|
||||
|
||||
// Generate XPath for the current position.
|
||||
// When we have a paragraph index from the section LUT, target that specific <p> element
|
||||
// directly — this produces a structurally precise full-ancestry path even for chapters
|
||||
// where paragraphs are nested inside divs/sections. Fall back to the progress-based
|
||||
// scan (which works for any content) when no paragraph index is available.
|
||||
if (pos.hasParagraphIndex && pos.paragraphIndex > 0) {
|
||||
// When a seek hint is set, the LUT entry's paragraphIndex equals pos.paragraphIndex
|
||||
// (both describe the same page). The byte offset now points at the body-child element
|
||||
// that was current at the page break, so re-parsing from there will re-encounter that
|
||||
// paragraph — seed startParagraphCount with paragraphIndex-1 to avoid double counting.
|
||||
const uint16_t startCount =
|
||||
pos.xhtmlSeekHint > 0 && pos.paragraphIndex > 0 ? static_cast<uint16_t>(pos.paragraphIndex - 1) : 0;
|
||||
result.xpath = ChapterXPathIndexer::findXPathForParagraph(epub, pos.spineIndex, pos.paragraphIndex,
|
||||
pos.xhtmlSeekHint, startCount);
|
||||
}
|
||||
if (result.xpath.empty()) {
|
||||
result.xpath = ChapterXPathIndexer::findXPathForProgress(epub, pos.spineIndex, intraSpineProgress);
|
||||
}
|
||||
// Generate XPath for the current position via byte-offset scan. Targeting the
|
||||
// paragraph LUT entry instead would snap to the start of the paragraph the user
|
||||
// is inside, which causes pulled positions to land at the start of the chapter
|
||||
// when an opening paragraph spans many pages.
|
||||
result.xpath = ChapterXPathIndexer::findXPathForProgress(epub, pos.spineIndex, intraSpineProgress);
|
||||
if (result.xpath.empty()) {
|
||||
result.xpath = generateXPath(pos.spineIndex);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user