Review comments

This commit is contained in:
jpirnay
2026-02-28 05:31:12 +01:00
parent 5764e22b82
commit 8c08c19ca6
3 changed files with 20 additions and 8 deletions
+16 -4
View File
@@ -20,6 +20,7 @@ namespace {
struct XPathAnchor {
size_t textOffset = 0;
std::string xpath;
std::string xpathNoIndex; // precomputed removeIndices(xpath)
};
struct StackNode {
@@ -129,8 +130,7 @@ struct ParserState {
bool found = false;
for (const auto& anchor : anchors) {
const std::string normalizedAnchor = normalizeXPath(anchor.xpath);
const std::string anchorPath = ignoreIndices ? removeIndices(normalizedAnchor) : normalizedAnchor;
const std::string& anchorPath = ignoreIndices ? anchor.xpathNoIndex : anchor.xpath;
if (anchorPath == probe) {
const int depth = pathDepth(anchorPath);
if (!found || depth > bestDepth || (depth == bestDepth && anchor.textOffset < bestOffset)) {
@@ -221,12 +221,13 @@ struct ParserState {
}
if (!stack.back().hasTextAnchor) {
anchors.push_back({totalTextBytes, currentXPath()});
const std::string xpath = currentXPath();
anchors.push_back({totalTextBytes, xpath, removeIndices(xpath)});
stack.back().hasTextAnchor = true;
} else if (anchors.empty() || totalTextBytes - anchors.back().textOffset >= 192) {
const std::string xpath = currentXPath();
if (anchors.empty() || anchors.back().xpath != xpath) {
anchors.push_back({totalTextBytes, xpath});
anchors.push_back({totalTextBytes, xpath, removeIndices(xpath)});
}
}
}
@@ -358,6 +359,17 @@ void XMLCALL onCharacterData(void* userData, const XML_Char* text, const int len
}
void XMLCALL onDefaultHandlerExpand(void* userData, const XML_Char* text, const int len) {
// The default handler fires for comments, PIs, DOCTYPE, and entity references.
// Only forward entity references (&..;) to avoid skewing text offsets with
// non-visible markup.
if (len < 3 || text[0] != '&' || text[len - 1] != ';') {
return;
}
for (int i = 1; i < len - 1; ++i) {
if (text[i] == '<' || text[i] == '>') {
return;
}
}
auto* state = static_cast<ParserState*>(userData);
state->onCharacterData(text, len);
}
+2 -2
View File
@@ -24,7 +24,7 @@ KOReaderPosition ProgressMapper::toKOReader(const std::shared_ptr<Epub>& epub, c
// to a synthetic chapter-level path if parsing fails.
result.xpath = ChapterXPathIndexer::findXPathForProgress(epub, pos.spineIndex, intraSpineProgress);
if (result.xpath.empty()) {
result.xpath = generateXPath(pos.spineIndex, pos.pageNumber, pos.totalPages);
result.xpath = generateXPath(pos.spineIndex);
}
// Get chapter info for logging
@@ -150,7 +150,7 @@ CrossPointPosition ProgressMapper::toCrossPoint(const std::shared_ptr<Epub>& epu
return result;
}
std::string ProgressMapper::generateXPath(int spineIndex, int pageNumber, int totalPages) {
std::string ProgressMapper::generateXPath(int spineIndex) {
// Fallback path when element-level XPath extraction is unavailable.
// KOReader uses 1-based XPath predicates; spineIndex is 0-based internally.
return "/body/DocFragment[" + std::to_string(spineIndex + 1) + "]/body";
+2 -2
View File
@@ -68,7 +68,7 @@ class ProgressMapper {
private:
/**
* Generate XPath for KOReader compatibility.
* Fallback format: /body/DocFragment[spineIndex]/body
* Fallback format: /body/DocFragment[spineIndex + 1]/body
*/
static std::string generateXPath(int spineIndex, int pageNumber, int totalPages);
static std::string generateXPath(int spineIndex);
};