Introduce ordered list support

This commit is contained in:
jpirnay
2026-03-31 21:10:22 +02:00
parent aa085425af
commit 0ad2ac71c7
2 changed files with 27 additions and 1 deletions
@@ -554,6 +554,12 @@ void XMLCALL ChapterHtmlSlimParser::startElement(void* userData, const XML_Char*
}
}
// Track ul/ol nesting so li markers can be numbered or bulleted accordingly
if (strcmp(name, "ul") == 0 || strcmp(name, "ol") == 0) {
self->listStack.push_back({self->depth, strcmp(name, "ol") == 0, 0});
// fall through to depth increment
}
const float emSize = static_cast<float>(self->renderer.getFontAscenderSize(self->fontId));
const auto userAlignmentBlockStyle = BlockStyle::fromCssStyle(
cssStyle, emSize, static_cast<CssTextAlign>(self->paragraphAlignment), self->viewportWidth);
@@ -581,7 +587,14 @@ void XMLCALL ChapterHtmlSlimParser::startElement(void* userData, const XML_Char*
self->updateEffectiveInlineStyle();
if (strcmp(name, "li") == 0) {
self->currentTextBlock->addWord("\xe2\x80\xa2", EpdFontFamily::REGULAR);
char marker[12];
if (!self->listStack.empty() && self->listStack.back().isOrdered) {
self->listStack.back().counter += 1;
snprintf(marker, sizeof(marker), "%d.", self->listStack.back().counter);
} else {
strncpy(marker, "\xe2\x80\xa2", sizeof(marker));
}
self->currentTextBlock->addWord(marker, EpdFontFamily::REGULAR);
}
}
} else if (matches(name, UNDERLINE_TAGS, NUM_UNDERLINE_TAGS)) {
@@ -893,6 +906,11 @@ void XMLCALL ChapterHtmlSlimParser::endElement(void* userData, const XML_Char* n
self->depth -= 1;
// Pop list entries whose ul/ol is now out of scope
while (!self->listStack.empty() && self->listStack.back().depth >= self->depth) {
self->listStack.pop_back();
}
// Closing a footnote link — create entry from collected text and href
if (self->insideFootnoteLink && self->depth == self->footnoteLinkDepth) {
if (self->currentFootnoteLinkText[0] != '\0' && self->currentFootnoteLinkHref[0] != '\0') {
@@ -70,6 +70,14 @@ class ChapterHtmlSlimParser {
int tableRowIndex = 0;
int tableColIndex = 0;
// List nesting tracking for ul/ol markers
struct ListEntry {
int depth;
bool isOrdered;
int counter;
};
std::vector<ListEntry> listStack;
// Anchor-to-page mapping: tracks which page each HTML id attribute lands on
int completedPageCount = 0;
std::vector<std::pair<std::string, uint16_t>> anchorData;