From c4430793e75a0bdee15bbb9ada9ef2a172c80aa4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Launay?= Date: Wed, 17 Dec 2025 13:00:21 +0100 Subject: [PATCH] clang-format-fix --- lib/Epub/Epub.cpp | 20 +-- lib/Epub/Epub.h | 4 +- lib/Epub/Epub/Page.cpp | 5 +- lib/Epub/Epub/Page.h | 8 +- lib/Epub/Epub/Section.cpp | 135 +++++++++--------- .../Epub/parsers/ChapterHtmlSlimParser.cpp | 108 ++++++-------- lib/Epub/Epub/parsers/ChapterHtmlSlimParser.h | 23 ++- .../EpubReaderChapterSelectionScreen.cpp | 4 +- .../EpubReaderChapterSelectionScreen.h | 2 +- src/screens/EpubReaderFootnotesScreen.cpp | 12 +- src/screens/EpubReaderFootnotesScreen.h | 32 ++--- src/screens/EpubReaderMenuScreen.cpp | 7 +- src/screens/EpubReaderMenuScreen.h | 15 +- src/screens/EpubReaderScreen.cpp | 43 ++---- src/screens/EpubReaderScreen.h | 4 +- 15 files changed, 173 insertions(+), 249 deletions(-) diff --git a/lib/Epub/Epub.cpp b/lib/Epub/Epub.cpp index ceb5288..83832a1 100644 --- a/lib/Epub/Epub.cpp +++ b/lib/Epub/Epub.cpp @@ -337,9 +337,7 @@ void Epub::markAsFootnotePage(const std::string& href) { // Extract filename from href (remove #anchor if present) size_t hashPos = href.find('#'); - std::string filename = (hashPos != std::string::npos) - ? href.substr(0, hashPos) - : href; + std::string filename = (hashPos != std::string::npos) ? href.substr(0, hashPos) : href; // Extract just the filename without path size_t lastSlash = filename.find_last_of('/'); @@ -356,7 +354,6 @@ bool Epub::isFootnotePage(const std::string& filename) const { return footnotePages->find(filename) != footnotePages->end(); } - bool Epub::shouldHideFromToc(int spineIndex) const { // Always hide virtual spine items if (isVirtualSpineItem(spineIndex)) { @@ -371,9 +368,7 @@ bool Epub::shouldHideFromToc(int spineIndex) const { // Extract filename from spine item size_t lastSlash = spineItem.find_last_of('/'); - std::string filename = (lastSlash != std::string::npos) - ? spineItem.substr(lastSlash + 1) - : spineItem; + std::string filename = (lastSlash != std::string::npos) ? spineItem.substr(lastSlash + 1) : spineItem; return isFootnotePage(filename); } @@ -387,14 +382,11 @@ int Epub::addVirtualSpineItem(const std::string& path) { virtualSpineItems->push_back(path); int newIndex = spine.size() + virtualSpineItems->size() - 1; - Serial.printf("[%lu] [EPUB] Added virtual spine item: %s (index %d)\n", - millis(), path.c_str(), newIndex); + Serial.printf("[%lu] [EPUB] Added virtual spine item: %s (index %d)\n", millis(), path.c_str(), newIndex); return newIndex; } -bool Epub::isVirtualSpineItem(int spineIndex) const { - return spineIndex >= static_cast(spine.size()); -} +bool Epub::isVirtualSpineItem(int spineIndex) const { return spineIndex >= static_cast(spine.size()); } int Epub::findVirtualSpineIndex(const std::string& filename) const { if (!virtualSpineItems) return -1; @@ -402,9 +394,7 @@ int Epub::findVirtualSpineIndex(const std::string& filename) const { for (size_t i = 0; i < virtualSpineItems->size(); i++) { std::string virtualPath = (*virtualSpineItems)[i]; size_t lastSlash = virtualPath.find_last_of('/'); - std::string virtualFilename = (lastSlash != std::string::npos) - ? virtualPath.substr(lastSlash + 1) - : virtualPath; + std::string virtualFilename = (lastSlash != std::string::npos) ? virtualPath.substr(lastSlash + 1) : virtualPath; if (virtualFilename == filename) { return spine.size() + i; diff --git a/lib/Epub/Epub.h b/lib/Epub/Epub.h index 46b9a29..92913d4 100644 --- a/lib/Epub/Epub.h +++ b/lib/Epub/Epub.h @@ -30,9 +30,7 @@ class Epub { public: explicit Epub(std::string filepath, const std::string& cacheDir) - : filepath(std::move(filepath)), - footnotePages(nullptr), - virtualSpineItems(nullptr) { + : filepath(std::move(filepath)), footnotePages(nullptr), virtualSpineItems(nullptr) { cachePath = cacheDir + "/epub_" + std::to_string(std::hash{}(this->filepath)); } diff --git a/lib/Epub/Epub/Page.cpp b/lib/Epub/Epub/Page.cpp index 946c3fe..52fccfc 100644 --- a/lib/Epub/Epub/Page.cpp +++ b/lib/Epub/Epub/Page.cpp @@ -1,12 +1,11 @@ #include "Page.h" + #include #include constexpr uint8_t PAGE_FILE_VERSION = 6; // Incremented -void PageLine::render(GfxRenderer& renderer, const int fontId) { - block->render(renderer, fontId, xPos, yPos); -} +void PageLine::render(GfxRenderer& renderer, const int fontId) { block->render(renderer, fontId, xPos, yPos); } void PageLine::serialize(std::ostream& os) { serialization::writePod(os, xPos); diff --git a/lib/Epub/Epub/Page.h b/lib/Epub/Epub/Page.h index ae00505..d4657ae 100644 --- a/lib/Epub/Epub/Page.h +++ b/lib/Epub/Epub/Page.h @@ -1,8 +1,8 @@ #pragma once +#include #include #include #include -#include #include "FootnoteEntry.h" #include "blocks/TextBlock.h" @@ -24,7 +24,7 @@ class PageElement { class PageLine final : public PageElement { std::shared_ptr block; -public: + public: PageLine(std::shared_ptr block, const int16_t xPos, const int16_t yPos) : PageElement(xPos, yPos), block(std::move(block)) {} void render(GfxRenderer& renderer, int fontId) override; @@ -33,14 +33,14 @@ public: }; class Page { -private: + private: std::shared_ptr* elements; int elementCapacity; FootnoteEntry* footnotes; int footnoteCapacity; -public: + public: int elementCount; int footnoteCount; diff --git a/lib/Epub/Epub/Section.cpp b/lib/Epub/Epub/Section.cpp index 4cc8285..c4f57e4 100644 --- a/lib/Epub/Epub/Section.cpp +++ b/lib/Epub/Epub/Section.cpp @@ -20,7 +20,7 @@ static bool writeEscapedXml(File& file, const char* text) { static char buffer[2048]; int bufferPos = 0; - while (*text && bufferPos < sizeof(buffer) - 10) { // Leave margin for entities + while (*text && bufferPos < sizeof(buffer) - 10) { // Leave margin for entities unsigned char c = (unsigned char)*text; // Only escape the 5 XML special characters @@ -178,10 +178,10 @@ bool Section::persistPageDataToSD(const int fontId, const float lineCompression, const auto sdPath = "/sd" + localPath; - ChapterHtmlSlimParser visitor(sdPath.c_str(), renderer, fontId, lineCompression, marginTop, marginRight, - marginBottom, marginLeft, extraParagraphSpacing, - [this](std::unique_ptr page) { this->onPageComplete(std::move(page)); }, - cachePath); + ChapterHtmlSlimParser visitor( + sdPath.c_str(), renderer, fontId, lineCompression, marginTop, marginRight, marginBottom, marginLeft, + extraParagraphSpacing, [this](std::unique_ptr page) { this->onPageComplete(std::move(page)); }, + cachePath); bool success = visitor.parseAndBuildPages(); @@ -190,7 +190,8 @@ bool Section::persistPageDataToSD(const int fontId, const float lineCompression, return false; } - writeCacheMetadata(fontId, lineCompression, marginTop, marginRight, marginBottom, marginLeft, extraParagraphSpacing); + writeCacheMetadata(fontId, lineCompression, marginTop, marginRight, marginBottom, marginLeft, + extraParagraphSpacing); return true; } @@ -209,10 +210,9 @@ bool Section::persistPageDataToSD(const int fontId, const float lineCompression, const auto sdTmpHtmlPath = "/sd" + tmpHtmlPath; - ChapterHtmlSlimParser visitor(sdTmpHtmlPath.c_str(), renderer, fontId, lineCompression, marginTop, marginRight, - marginBottom, marginLeft, extraParagraphSpacing, - [this](std::unique_ptr page) { this->onPageComplete(std::move(page)); }, - cachePath); + ChapterHtmlSlimParser visitor( + sdTmpHtmlPath.c_str(), renderer, fontId, lineCompression, marginTop, marginRight, marginBottom, marginLeft, + extraParagraphSpacing, [this](std::unique_ptr page) { this->onPageComplete(std::move(page)); }, cachePath); // Track which inline footnotes AND paragraph notes are actually referenced in this file std::set rewrittenInlineIds; @@ -232,10 +232,9 @@ bool Section::persistPageDataToSD(const int fontId, const float lineCompression, if (underscorePos != std::string::npos && dotPos != std::string::npos) { std::string noteId = href.substr(underscorePos + 1, dotPos - underscorePos - 1); rewrittenInlineIds.insert(noteId); - Serial.printf("[%lu] [SCT] Marked note as rewritten: %s\n", - millis(), noteId.c_str()); + Serial.printf("[%lu] [SCT] Marked note as rewritten: %s\n", millis(), noteId.c_str()); } - }else { + } else { // Normal external footnote epub->markAsFootnotePage(noteref.href); } @@ -254,8 +253,8 @@ bool Section::persistPageDataToSD(const int fontId, const float lineCompression, } // NOW generate inline footnote HTML files ONLY for rewritten ones - Serial.printf("[%lu] [SCT] Found %d inline footnotes, %d were referenced\n", - millis(), visitor.inlineFootnoteCount, rewrittenInlineIds.size()); + Serial.printf("[%lu] [SCT] Found %d inline footnotes, %d were referenced\n", millis(), visitor.inlineFootnoteCount, + rewrittenInlineIds.size()); for (int i = 0; i < visitor.inlineFootnoteCount; i++) { const char* inlineId = visitor.inlineFootnotes[i].id; @@ -263,8 +262,7 @@ bool Section::persistPageDataToSD(const int fontId, const float lineCompression, // Only generate if this inline footnote was actually referenced if (rewrittenInlineIds.find(std::string(inlineId)) == rewrittenInlineIds.end()) { - Serial.printf("[%lu] [SCT] Skipping unreferenced inline footnote: %s\n", - millis(), inlineId); + Serial.printf("[%lu] [SCT] Skipping unreferenced inline footnote: %s\n", millis(), inlineId); continue; } @@ -274,8 +272,7 @@ bool Section::persistPageDataToSD(const int fontId, const float lineCompression, continue; } - Serial.printf("[%lu] [SCT] Processing inline footnote: %s (len=%d)\n", - millis(), inlineId, strlen(inlineText)); + Serial.printf("[%lu] [SCT] Processing inline footnote: %s (len=%d)\n", millis(), inlineId, strlen(inlineText)); char inlineFilename[64]; snprintf(inlineFilename, sizeof(inlineFilename), "inline_%s.html", inlineId); @@ -325,64 +322,64 @@ bool Section::persistPageDataToSD(const int fontId, const float lineCompression, } } -// Generate paragraph note HTML files -Serial.printf("[%lu] [SCT] Found %d paragraph notes\n", millis(), visitor.paragraphNoteCount); + // Generate paragraph note HTML files + Serial.printf("[%lu] [SCT] Found %d paragraph notes\n", millis(), visitor.paragraphNoteCount); -for (int i = 0; i < visitor.paragraphNoteCount; i++) { - const char* pnoteId = visitor.paragraphNotes[i].id; - const char* pnoteText = visitor.paragraphNotes[i].text; + for (int i = 0; i < visitor.paragraphNoteCount; i++) { + const char* pnoteId = visitor.paragraphNotes[i].id; + const char* pnoteText = visitor.paragraphNotes[i].text; - if (!pnoteText || strlen(pnoteText) == 0) { - continue; - } - - // Check if this paragraph note was referenced - if (rewrittenInlineIds.find(std::string(pnoteId)) == rewrittenInlineIds.end()) { - Serial.printf("[%lu] [SCT] Skipping unreferenced paragraph note: %s\n", millis(), pnoteId); - continue; - } - - // Create filename: pnote_rnote1.html - char pnoteFilename[64]; - snprintf(pnoteFilename, sizeof(pnoteFilename), "pnote_%s.html", pnoteId); - - std::string fullPath = epub->getCachePath() + "/" + std::string(pnoteFilename); - - Serial.printf("[%lu] [SCT] Generating paragraph note file: %s\n", millis(), fullPath.c_str()); - - File file = SD.open(fullPath.c_str(), FILE_WRITE, true); - if (file) { - file.println(""); - file.println(""); - file.println(""); - file.println(""); - file.println(""); - file.println("Note"); - file.println(""); - file.println(""); - file.print("

"); - - if (!writeEscapedXml(file, pnoteText)) { - Serial.printf("[%lu] [SCT] Warning: writeEscapedXml may have failed\n", millis()); + if (!pnoteText || strlen(pnoteText) == 0) { + continue; } - file.println("

"); - file.println(""); - file.println(""); - file.close(); + // Check if this paragraph note was referenced + if (rewrittenInlineIds.find(std::string(pnoteId)) == rewrittenInlineIds.end()) { + Serial.printf("[%lu] [SCT] Skipping unreferenced paragraph note: %s\n", millis(), pnoteId); + continue; + } - Serial.printf("[%lu] [SCT] Generated paragraph note file\n", millis()); + // Create filename: pnote_rnote1.html + char pnoteFilename[64]; + snprintf(pnoteFilename, sizeof(pnoteFilename), "pnote_%s.html", pnoteId); - int virtualIndex = epub->addVirtualSpineItem(fullPath); - Serial.printf("[%lu] [SCT] Added virtual spine item at index %d\n", millis(), virtualIndex); + std::string fullPath = epub->getCachePath() + "/" + std::string(pnoteFilename); - char newHref[128]; - snprintf(newHref, sizeof(newHref), "%s#%s", pnoteFilename, pnoteId); - epub->markAsFootnotePage(newHref); + Serial.printf("[%lu] [SCT] Generating paragraph note file: %s\n", millis(), fullPath.c_str()); + + File file = SD.open(fullPath.c_str(), FILE_WRITE, true); + if (file) { + file.println(""); + file.println(""); + file.println(""); + file.println(""); + file.println(""); + file.println("Note"); + file.println(""); + file.println(""); + file.print("

"); + + if (!writeEscapedXml(file, pnoteText)) { + Serial.printf("[%lu] [SCT] Warning: writeEscapedXml may have failed\n", millis()); + } + + file.println("

"); + file.println(""); + file.println(""); + file.close(); + + Serial.printf("[%lu] [SCT] Generated paragraph note file\n", millis()); + + int virtualIndex = epub->addVirtualSpineItem(fullPath); + Serial.printf("[%lu] [SCT] Added virtual spine item at index %d\n", millis(), virtualIndex); + + char newHref[128]; + snprintf(newHref, sizeof(newHref), "%s#%s", pnoteFilename, pnoteId); + epub->markAsFootnotePage(newHref); + } } -} Serial.printf("[%lu] [SCT] Total noterefs found: %d\n", millis(), noterefCount); diff --git a/lib/Epub/Epub/parsers/ChapterHtmlSlimParser.cpp b/lib/Epub/Epub/parsers/ChapterHtmlSlimParser.cpp index a87e1b9..6867219 100644 --- a/lib/Epub/Epub/parsers/ChapterHtmlSlimParser.cpp +++ b/lib/Epub/Epub/parsers/ChapterHtmlSlimParser.cpp @@ -90,7 +90,7 @@ void ChapterHtmlSlimParser::addFootnoteToCurrentPage(const char* number, const c } } - //Check if we have this as a paragraph note + // Check if we have this as a paragraph note if (!foundInline) { for (int i = 0; i < paragraphNoteCount; i++) { if (strcmp(paragraphNotes[i].id, inlineId) == 0) { @@ -120,10 +120,9 @@ void ChapterHtmlSlimParser::addFootnoteToCurrentPage(const char* number, const c currentPageFootnoteCount++; - Serial.printf("[%lu] [ADDFT] Stored as: num=%s, href=%s\n", - millis(), - currentPageFootnotes[currentPageFootnoteCount-1].number, - currentPageFootnotes[currentPageFootnoteCount-1].href); + Serial.printf("[%lu] [ADDFT] Stored as: num=%s, href=%s\n", millis(), + currentPageFootnotes[currentPageFootnoteCount - 1].number, + currentPageFootnotes[currentPageFootnoteCount - 1].href); } void XMLCALL ChapterHtmlSlimParser::startElement(void* userData, const XML_Char* name, const XML_Char** atts) { @@ -173,8 +172,8 @@ void XMLCALL ChapterHtmlSlimParser::startElement(void* userData, const XML_Char* if (epubType && strcmp(epubType, "footnote") == 0 && id) { if (self->isPass1CollectingAsides) { // Pass 1: Collect aside - Serial.printf("[%lu] [ASIDE] Found inline footnote: id=%s (pass1=%d)\n", - millis(), id, self->isPass1CollectingAsides); + Serial.printf("[%lu] [ASIDE] Found inline footnote: id=%s (pass1=%d)\n", millis(), id, + self->isPass1CollectingAsides); self->insideAsideFootnote = true; self->asideDepth = self->depth; @@ -189,8 +188,7 @@ void XMLCALL ChapterHtmlSlimParser::startElement(void* userData, const XML_Char* // Find the inline footnote text for (int i = 0; i < self->inlineFootnoteCount; i++) { - if (strcmp(self->inlineFootnotes[i].id, id) == 0 && - self->inlineFootnotes[i].text) { + if (strcmp(self->inlineFootnotes[i].id, id) == 0 && self->inlineFootnotes[i].text) { // Output the footnote text as normal text const char* text = self->inlineFootnotes[i].text; int textLen = strlen(text); @@ -198,10 +196,9 @@ void XMLCALL ChapterHtmlSlimParser::startElement(void* userData, const XML_Char* // Process it through characterData self->characterData(self, text, textLen); - Serial.printf("[%lu] [ASIDE] Rendered aside text: %.80s...\n", - millis(), text); + Serial.printf("[%lu] [ASIDE] Rendered aside text: %.80s...\n", millis(), text); break; - } + } } // Skip the aside element itself @@ -332,13 +329,13 @@ void XMLCALL ChapterHtmlSlimParser::startElement(void* userData, const XML_Char* void XMLCALL ChapterHtmlSlimParser::characterData(void* userData, const XML_Char* s, const int len) { auto* self = static_cast(userData); - //Collect paragraph note text in Pass 1 + // Collect paragraph note text in Pass 1 if (self->insideParagraphNote && self->isPass1CollectingAsides) { for (int i = 0; i < len; i++) { if (self->currentParagraphNoteTextLen >= self->MAX_PNOTE_BUFFER - 2) { if (self->currentParagraphNoteTextLen == self->MAX_PNOTE_BUFFER - 2) { - Serial.printf("[%lu] [PNOTE] WARNING: Note text truncated at %d chars\n", - millis(), self->MAX_PNOTE_BUFFER - 2); + Serial.printf("[%lu] [PNOTE] WARNING: Note text truncated at %d chars\n", millis(), + self->MAX_PNOTE_BUFFER - 2); } break; } @@ -349,7 +346,7 @@ void XMLCALL ChapterHtmlSlimParser::characterData(void* userData, const XML_Char if (self->currentParagraphNoteTextLen > 0 && self->currentParagraphNoteText[self->currentParagraphNoteTextLen - 1] != ' ') { self->currentParagraphNoteText[self->currentParagraphNoteTextLen++] = ' '; - } + } } else if (c >= 32 || c >= 0x80) { // Accept printable ASCII AND UTF-8 self->currentParagraphNoteText[self->currentParagraphNoteTextLen++] = c; } @@ -367,8 +364,8 @@ void XMLCALL ChapterHtmlSlimParser::characterData(void* userData, const XML_Char for (int i = 0; i < len; i++) { if (self->currentAsideTextLen >= self->MAX_ASIDE_BUFFER - 2) { if (self->currentAsideTextLen == self->MAX_ASIDE_BUFFER - 2) { - Serial.printf("[%lu] [ASIDE] WARNING: Footnote text truncated at %d chars (id=%s)\n", - millis(), self->MAX_ASIDE_BUFFER - 2, self->currentAsideId); + Serial.printf("[%lu] [ASIDE] WARNING: Footnote text truncated at %d chars (id=%s)\n", millis(), + self->MAX_ASIDE_BUFFER - 2, self->currentAsideId); } break; } @@ -376,10 +373,9 @@ void XMLCALL ChapterHtmlSlimParser::characterData(void* userData, const XML_Char unsigned char c = (unsigned char)s[i]; // Cast to unsigned char if (isWhitespace(c)) { - if (self->currentAsideTextLen > 0 && - self->currentAsideText[self->currentAsideTextLen - 1] != ' ') { + if (self->currentAsideTextLen > 0 && self->currentAsideText[self->currentAsideTextLen - 1] != ' ') { self->currentAsideText[self->currentAsideTextLen++] = ' '; - } + } } else if (c >= 32 || c >= 0x80) { // Accept printable ASCII AND UTF-8 bytes self->currentAsideText[self->currentAsideTextLen++] = c; } @@ -443,36 +439,27 @@ void XMLCALL ChapterHtmlSlimParser::characterData(void* userData, const XML_Char void XMLCALL ChapterHtmlSlimParser::endElement(void* userData, const XML_Char* name) { auto* self = static_cast(userData); - //Closing paragraph note in Pass 1 - if (strcmp(name, "p") == 0 && self->insideParagraphNote && - self->depth - 1 == self->paragraphNoteDepth) { - - if (self->isPass1CollectingAsides && - self->currentParagraphNoteTextLen > 0 && - self->paragraphNoteCount < 32 && + // Closing paragraph note in Pass 1 + if (strcmp(name, "p") == 0 && self->insideParagraphNote && self->depth - 1 == self->paragraphNoteDepth) { + if (self->isPass1CollectingAsides && self->currentParagraphNoteTextLen > 0 && self->paragraphNoteCount < 32 && self->currentParagraphNoteId[0] != '\0') { - // Copy ID - strncpy(self->paragraphNotes[self->paragraphNoteCount].id, - self->currentParagraphNoteId, 15); + strncpy(self->paragraphNotes[self->paragraphNoteCount].id, self->currentParagraphNoteId, 15); self->paragraphNotes[self->paragraphNoteCount].id[15] = '\0'; // Allocate memory for text size_t textLen = strlen(self->currentParagraphNoteText); - self->paragraphNotes[self->paragraphNoteCount].text = - static_cast(malloc(textLen + 1)); + self->paragraphNotes[self->paragraphNoteCount].text = static_cast(malloc(textLen + 1)); if (self->paragraphNotes[self->paragraphNoteCount].text) { - strcpy(self->paragraphNotes[self->paragraphNoteCount].text, - self->currentParagraphNoteText); + strcpy(self->paragraphNotes[self->paragraphNoteCount].text, self->currentParagraphNoteText); - Serial.printf("[%lu] [PNOTE] Stored: %s -> %.80s... (allocated %d bytes)\n", - millis(), self->currentParagraphNoteId, - self->currentParagraphNoteText, textLen + 1); + Serial.printf("[%lu] [PNOTE] Stored: %s -> %.80s... (allocated %d bytes)\n", millis(), + self->currentParagraphNoteId, self->currentParagraphNoteText, textLen + 1); self->paragraphNoteCount++; } - } + } self->insideParagraphNote = false; self->depth -= 1; @@ -480,35 +467,27 @@ void XMLCALL ChapterHtmlSlimParser::endElement(void* userData, const XML_Char* n } // Closing aside - handle differently for Pass 1 vs Pass 2 - if (strcmp(name, "aside") == 0 && self->insideAsideFootnote && - self->depth - 1 == self->asideDepth) { - + if (strcmp(name, "aside") == 0 && self->insideAsideFootnote && self->depth - 1 == self->asideDepth) { // Store footnote ONLY in Pass 1 - if (self->isPass1CollectingAsides && - self->currentAsideTextLen > 0 && - self->inlineFootnoteCount < 16) { - + if (self->isPass1CollectingAsides && self->currentAsideTextLen > 0 && self->inlineFootnoteCount < 16) { // Copy ID (max 2 digits) - strncpy(self->inlineFootnotes[self->inlineFootnoteCount].id, - self->currentAsideId, 2); + strncpy(self->inlineFootnotes[self->inlineFootnoteCount].id, self->currentAsideId, 2); self->inlineFootnotes[self->inlineFootnoteCount].id[2] = '\0'; // DYNAMIC ALLOCATION: allocate exactly the needed size + 1 size_t textLen = strlen(self->currentAsideText); - self->inlineFootnotes[self->inlineFootnoteCount].text = - static_cast(malloc(textLen + 1)); + self->inlineFootnotes[self->inlineFootnoteCount].text = static_cast(malloc(textLen + 1)); if (self->inlineFootnotes[self->inlineFootnoteCount].text) { - strcpy(self->inlineFootnotes[self->inlineFootnoteCount].text, - self->currentAsideText); + strcpy(self->inlineFootnotes[self->inlineFootnoteCount].text, self->currentAsideText); - Serial.printf("[%lu] [ASIDE] Stored: %s -> %.80s... (allocated %d bytes)\n", - millis(), self->currentAsideId, self->currentAsideText, textLen + 1); + Serial.printf("[%lu] [ASIDE] Stored: %s -> %.80s... (allocated %d bytes)\n", millis(), self->currentAsideId, + self->currentAsideText, textLen + 1); self->inlineFootnoteCount++; } else { - Serial.printf("[%lu] [ASIDE] ERROR: Failed to allocate %d bytes for footnote %s\n", - millis(), textLen + 1, self->currentAsideId); + Serial.printf("[%lu] [ASIDE] ERROR: Failed to allocate %d bytes for footnote %s\n", millis(), textLen + 1, + self->currentAsideId); } } @@ -529,9 +508,7 @@ void XMLCALL ChapterHtmlSlimParser::endElement(void* userData, const XML_Char* n self->insideNoteref = false; if (self->currentNoterefTextLen > 0) { - Serial.printf("[%lu] [NOTEREF] %s -> %s\n", millis(), - self->currentNoterefText, - self->currentNoterefHref); + Serial.printf("[%lu] [NOTEREF] %s -> %s\n", millis(), self->currentNoterefText, self->currentNoterefHref); // Add footnote first (this does the rewriting) self->addFootnoteToCurrentPage(self->currentNoterefText, self->currentNoterefHref); @@ -668,8 +645,7 @@ bool ChapterHtmlSlimParser::parseAndBuildPages() { done = feof(file); if (XML_ParseBuffer(parser1, static_cast(len), done) == XML_STATUS_ERROR) { - Serial.printf("[%lu] [EHP] Parse error at line %lu:\n%s\n", millis(), - XML_GetCurrentLineNumber(parser1), + Serial.printf("[%lu] [EHP] Parse error at line %lu:\n%s\n", millis(), XML_GetCurrentLineNumber(parser1), XML_ErrorString(XML_GetErrorCode(parser1))); XML_ParserFree(parser1); fclose(file); @@ -680,11 +656,9 @@ bool ChapterHtmlSlimParser::parseAndBuildPages() { XML_ParserFree(parser1); fclose(file); - Serial.printf("[%lu] [PARSER] Pass 1 complete: found %d inline footnotes\n", - millis(), inlineFootnoteCount); + Serial.printf("[%lu] [PARSER] Pass 1 complete: found %d inline footnotes\n", millis(), inlineFootnoteCount); for (int i = 0; i < inlineFootnoteCount; i++) { - Serial.printf("[%lu] [PARSER] - %s: %.80s\n", - millis(), inlineFootnotes[i].id, inlineFootnotes[i].text); + Serial.printf("[%lu] [PARSER] - %s: %.80s\n", millis(), inlineFootnotes[i].id, inlineFootnotes[i].text); } // ============================================================================ @@ -743,8 +717,7 @@ bool ChapterHtmlSlimParser::parseAndBuildPages() { done = feof(file); if (XML_ParseBuffer(parser2, static_cast(len), done) == XML_STATUS_ERROR) { - Serial.printf("[%lu] [EHP] Parse error at line %lu:\n%s\n", millis(), - XML_GetCurrentLineNumber(parser2), + Serial.printf("[%lu] [EHP] Parse error at line %lu:\n%s\n", millis(), XML_GetCurrentLineNumber(parser2), XML_ErrorString(XML_GetErrorCode(parser2))); XML_ParserFree(parser2); fclose(file); @@ -819,4 +792,3 @@ void ChapterHtmlSlimParser::makePages() { currentPageNextY += lineHeight / 2; } } - diff --git a/lib/Epub/Epub/parsers/ChapterHtmlSlimParser.h b/lib/Epub/Epub/parsers/ChapterHtmlSlimParser.h index 0d374ab..a8a3113 100644 --- a/lib/Epub/Epub/parsers/ChapterHtmlSlimParser.h +++ b/lib/Epub/Epub/parsers/ChapterHtmlSlimParser.h @@ -1,14 +1,15 @@ #pragma once #include + #include #include #include #include +#include "../FootnoteEntry.h" #include "../ParsedText.h" #include "../blocks/TextBlock.h" -#include "../FootnoteEntry.h" class Page; class GfxRenderer; @@ -25,19 +26,15 @@ struct InlineFootnote { char id[3]; char* text; - InlineFootnote() : text(nullptr) { - id[0] = '\0'; - } + InlineFootnote() : text(nullptr) { id[0] = '\0'; } }; // Struct to store collected inline footnotes from

struct ParagraphNote { - char id[16]; // ID from - char* text; // Pointer to dynamically allocated text + char id[16]; // ID from + char* text; // Pointer to dynamically allocated text - ParagraphNote() : text(nullptr) { - id[0] = '\0'; - } + ParagraphNote() : text(nullptr) { id[0] = '\0'; } ~ParagraphNote() { if (text) { @@ -88,7 +85,7 @@ class ChapterHtmlSlimParser { int asideDepth = 0; char currentAsideId[3] = {0}; - //Paragraph note tracking + // Paragraph note tracking bool insideParagraphNote = false; int paragraphNoteDepth = 0; char currentParagraphNoteId[16] = {0}; @@ -120,7 +117,7 @@ class ChapterHtmlSlimParser { // inline footnotes InlineFootnote inlineFootnotes[16]; int inlineFootnoteCount = 0; - //paragraph notes + // paragraph notes ParagraphNote paragraphNotes[32]; int paragraphNoteCount = 0; @@ -161,7 +158,5 @@ class ChapterHtmlSlimParser { bool parseAndBuildPages(); void addLineToPage(std::shared_ptr line); - void setNoterefCallback(const std::function& callback) { - noterefCallback = callback; - } + void setNoterefCallback(const std::function& callback) { noterefCallback = callback; } }; \ No newline at end of file diff --git a/src/screens/EpubReaderChapterSelectionScreen.cpp b/src/screens/EpubReaderChapterSelectionScreen.cpp index e5df1ca..d5ebefe 100644 --- a/src/screens/EpubReaderChapterSelectionScreen.cpp +++ b/src/screens/EpubReaderChapterSelectionScreen.cpp @@ -73,8 +73,8 @@ void EpubReaderChapterSelectionScreen::buildFilteredChapterList() { filteredSpineIndices.push_back(i); } - Serial.printf("[%lu] [CHAP] Filtered chapters: %d out of %d\n", - millis(), filteredSpineIndices.size(), epub->getSpineItemsCount()); + Serial.printf("[%lu] [CHAP] Filtered chapters: %d out of %d\n", millis(), filteredSpineIndices.size(), + epub->getSpineItemsCount()); } void EpubReaderChapterSelectionScreen::handleInput() { diff --git a/src/screens/EpubReaderChapterSelectionScreen.h b/src/screens/EpubReaderChapterSelectionScreen.h index 2a9291a..9e0f30d 100644 --- a/src/screens/EpubReaderChapterSelectionScreen.h +++ b/src/screens/EpubReaderChapterSelectionScreen.h @@ -27,7 +27,7 @@ class EpubReaderChapterSelectionScreen final : public Screen { void renderScreen(); void buildFilteredChapterList(); -public: + public: explicit EpubReaderChapterSelectionScreen(GfxRenderer& renderer, InputManager& inputManager, const std::shared_ptr& epub, const int currentSpineIndex, const std::function& onGoBack, diff --git a/src/screens/EpubReaderFootnotesScreen.cpp b/src/screens/EpubReaderFootnotesScreen.cpp index 02d7713..0d80173 100644 --- a/src/screens/EpubReaderFootnotesScreen.cpp +++ b/src/screens/EpubReaderFootnotesScreen.cpp @@ -1,7 +1,9 @@ #include "EpubReaderFootnotesScreen.h" -#include "config.h" + #include +#include "config.h" + void EpubReaderFootnotesScreen::onEnter() { selectedIndex = 0; render(); @@ -20,8 +22,7 @@ void EpubReaderFootnotesScreen::handleInput() { if (inputManager.wasPressed(InputManager::BTN_CONFIRM)) { const FootnoteEntry* entry = footnotes.getEntry(selectedIndex); if (entry) { - Serial.printf("[%lu] [FNS] Selected footnote: %s -> %s\n", - millis(), entry->number, entry->href); + Serial.printf("[%lu] [FNS] Selected footnote: %s -> %s\n", millis(), entry->number, entry->href); // Appeler le callback - EpubReaderScreen gère la navigation onSelectFootnote(entry->href); @@ -83,9 +84,8 @@ void EpubReaderFootnotesScreen::render() { } // Instructions at bottom - renderer.drawText(SMALL_FONT_ID, marginLeft, - GfxRenderer::getScreenHeight() - 40, - "UP/DOWN: Select CONFIRM: Go to footnote BACK: Return"); + renderer.drawText(SMALL_FONT_ID, marginLeft, GfxRenderer::getScreenHeight() - 40, + "UP/DOWN: Select CONFIRM: Go to footnote BACK: Return"); renderer.displayBuffer(); } \ No newline at end of file diff --git a/src/screens/EpubReaderFootnotesScreen.h b/src/screens/EpubReaderFootnotesScreen.h index 6c2e021..13d72f1 100644 --- a/src/screens/EpubReaderFootnotesScreen.h +++ b/src/screens/EpubReaderFootnotesScreen.h @@ -1,16 +1,17 @@ #pragma once -#include "Screen.h" -#include "../../lib/Epub/Epub/FootnoteEntry.h" +#include #include #include -#include + +#include "../../lib/Epub/Epub/FootnoteEntry.h" +#include "Screen.h" class FootnotesData { -private: + private: FootnoteEntry entries[32]; int count; -public: + public: FootnotesData() : count(0) {} void addFootnote(const char* number, const char* href) { @@ -23,13 +24,9 @@ public: } } - void clear() { - count = 0; - } + void clear() { count = 0; } - int getCount() const { - return count; - } + int getCount() const { return count; } const FootnoteEntry* getEntry(int index) const { if (index >= 0 && index < count) { @@ -45,13 +42,10 @@ class EpubReaderFootnotesScreen final : public Screen { const std::function onSelectFootnote; int selectedIndex; -public: - EpubReaderFootnotesScreen( - GfxRenderer& renderer, - InputManager& inputManager, - const FootnotesData& footnotes, - const std::function& onGoBack, - const std::function& onSelectFootnote) + public: + EpubReaderFootnotesScreen(GfxRenderer& renderer, InputManager& inputManager, const FootnotesData& footnotes, + const std::function& onGoBack, + const std::function& onSelectFootnote) : Screen(renderer, inputManager), footnotes(footnotes), onGoBack(onGoBack), @@ -62,6 +56,6 @@ public: void onExit() override; void handleInput() override; -private: + private: void render(); }; \ No newline at end of file diff --git a/src/screens/EpubReaderMenuScreen.cpp b/src/screens/EpubReaderMenuScreen.cpp index 0c992b6..992b943 100644 --- a/src/screens/EpubReaderMenuScreen.cpp +++ b/src/screens/EpubReaderMenuScreen.cpp @@ -2,7 +2,9 @@ // Created by jlaunay on 13/12/2025. // #include "EpubReaderMenuScreen.h" + #include + #include "config.h" constexpr int MENU_ITEMS_COUNT = 2; @@ -74,10 +76,7 @@ void EpubReaderMenuScreen::renderScreen() { const auto pageWidth = renderer.getScreenWidth(); renderer.drawCenteredText(READER_FONT_ID, 10, "Menu", true, BOLD); - const char* menuItems[MENU_ITEMS_COUNT] = { - "Go to chapter", - "View footnotes" - }; + const char* menuItems[MENU_ITEMS_COUNT] = {"Go to chapter", "View footnotes"}; const int startY = 100; const int itemHeight = 40; diff --git a/src/screens/EpubReaderMenuScreen.h b/src/screens/EpubReaderMenuScreen.h index fac8d79..a462b24 100644 --- a/src/screens/EpubReaderMenuScreen.h +++ b/src/screens/EpubReaderMenuScreen.h @@ -12,13 +12,10 @@ #include "Screen.h" class EpubReaderMenuScreen final : public Screen { -public: - enum MenuOption { - CHAPTERS, - FOOTNOTES - }; + public: + enum MenuOption { CHAPTERS, FOOTNOTES }; -private: + private: TaskHandle_t displayTaskHandle = nullptr; SemaphoreHandle_t renderingMutex = nullptr; int selectorIndex = 0; @@ -30,13 +27,11 @@ private: [[noreturn]] void displayTaskLoop(); void renderScreen(); -public: + public: explicit EpubReaderMenuScreen(GfxRenderer& renderer, InputManager& inputManager, const std::function& onGoBack, const std::function& onSelectOption) - : Screen(renderer, inputManager), - onGoBack(onGoBack), - onSelectOption(onSelectOption) {} + : Screen(renderer, inputManager), onGoBack(onGoBack), onSelectOption(onSelectOption) {} void onEnter() override; void onExit() override; diff --git a/src/screens/EpubReaderScreen.cpp b/src/screens/EpubReaderScreen.cpp index 4de9042..70cf4f9 100644 --- a/src/screens/EpubReaderScreen.cpp +++ b/src/screens/EpubReaderScreen.cpp @@ -1,6 +1,5 @@ #include "EpubReaderScreen.h" -#include "EpubReaderFootnotesScreen.h" #include #include #include @@ -8,6 +7,7 @@ #include "Battery.h" #include "CrossPointSettings.h" #include "EpubReaderChapterSelectionScreen.h" +#include "EpubReaderFootnotesScreen.h" #include "EpubReaderMenuScreen.h" #include "config.h" @@ -46,11 +46,8 @@ void EpubReaderScreen::onEnter() { updateRequired = true; xTaskCreate(&EpubReaderScreen::taskTrampoline, "EpubReaderScreenTask", - 24576, //32768 - this, - 1, - &displayTaskHandle - ); + 24576, // 32768 + this, 1, &displayTaskHandle); } void EpubReaderScreen::onExit() { @@ -126,8 +123,7 @@ void EpubReaderScreen::handleInput() { subScreen->onExit(); subScreen.reset(new EpubReaderFootnotesScreen( - this->renderer, - this->inputManager, + this->renderer, this->inputManager, currentPageFootnotes, // Pass collected footnotes (reference) [this] { // onGoBack from footnotes @@ -460,8 +456,7 @@ void EpubReaderScreen::navigateToHref(const char* href, bool savePosition) { savedSpineIndex = currentSpineIndex; savedPageNumber = section->currentPage; isViewingFootnote = true; - Serial.printf("[%lu] [ERS] Saved position: spine %d, page %d\n", - millis(), savedSpineIndex, savedPageNumber); + Serial.printf("[%lu] [ERS] Saved position: spine %d, page %d\n", millis(), savedSpineIndex, savedPageNumber); } // Parse href: "filename.html#anchor" @@ -483,8 +478,7 @@ void EpubReaderScreen::navigateToHref(const char* href, bool savePosition) { filename = filename.substr(lastSlash + 1); } - Serial.printf("[%lu] [ERS] Navigate to: %s (anchor: %s)\n", - millis(), filename.c_str(), anchor.c_str()); + Serial.printf("[%lu] [ERS] Navigate to: %s (anchor: %s)\n", millis(), filename.c_str(), anchor.c_str()); int targetSpineIndex = -1; @@ -492,23 +486,20 @@ void EpubReaderScreen::navigateToHref(const char* href, bool savePosition) { if (!anchor.empty()) { // Try inline footnote first std::string inlineFilename = "inline_" + anchor + ".html"; - Serial.printf("[%lu] [ERS] Looking for inline footnote: %s\n", - millis(), inlineFilename.c_str()); + Serial.printf("[%lu] [ERS] Looking for inline footnote: %s\n", millis(), inlineFilename.c_str()); targetSpineIndex = epub->findVirtualSpineIndex(inlineFilename); // If not found, try paragraph note if (targetSpineIndex == -1) { std::string pnoteFilename = "pnote_" + anchor + ".html"; - Serial.printf("[%lu] [ERS] Looking for paragraph note: %s\n", - millis(), pnoteFilename.c_str()); + Serial.printf("[%lu] [ERS] Looking for paragraph note: %s\n", millis(), pnoteFilename.c_str()); targetSpineIndex = epub->findVirtualSpineIndex(pnoteFilename); } if (targetSpineIndex != -1) { - Serial.printf("[%lu] [ERS] Found note at virtual index: %d\n", - millis(), targetSpineIndex); + Serial.printf("[%lu] [ERS] Found note at virtual index: %d\n", millis(), targetSpineIndex); // Navigate to the note xSemaphoreTake(renderingMutex, portMAX_DELAY); @@ -520,8 +511,7 @@ void EpubReaderScreen::navigateToHref(const char* href, bool savePosition) { updateRequired = true; return; } else { - Serial.printf("[%lu] [ERS] No virtual note found, trying normal navigation\n", - millis()); + Serial.printf("[%lu] [ERS] No virtual note found, trying normal navigation\n", millis()); } } @@ -531,9 +521,7 @@ void EpubReaderScreen::navigateToHref(const char* href, bool savePosition) { std::string spineItem = epub->getSpineItem(i); size_t lastSlash = spineItem.find_last_of('/'); - std::string spineFilename = (lastSlash != std::string::npos) - ? spineItem.substr(lastSlash + 1) - : spineItem; + std::string spineFilename = (lastSlash != std::string::npos) ? spineItem.substr(lastSlash + 1) : spineItem; if (spineFilename == filename) { targetSpineIndex = i; @@ -542,8 +530,7 @@ void EpubReaderScreen::navigateToHref(const char* href, bool savePosition) { } if (targetSpineIndex == -1) { - Serial.printf("[%lu] [ERS] Could not find spine index for: %s\n", - millis(), filename.c_str()); + Serial.printf("[%lu] [ERS] Could not find spine index for: %s\n", millis(), filename.c_str()); return; } @@ -556,15 +543,13 @@ void EpubReaderScreen::navigateToHref(const char* href, bool savePosition) { updateRequired = true; - Serial.printf("[%lu] [ERS] Navigated to spine index: %d\n", - millis(), targetSpineIndex); + Serial.printf("[%lu] [ERS] Navigated to spine index: %d\n", millis(), targetSpineIndex); } // Method to restore saved position void EpubReaderScreen::restoreSavedPosition() { if (savedSpineIndex >= 0 && savedPageNumber >= 0) { - Serial.printf("[%lu] [ERS] Restoring position: spine %d, page %d\n", - millis(), savedSpineIndex, savedPageNumber); + Serial.printf("[%lu] [ERS] Restoring position: spine %d, page %d\n", millis(), savedSpineIndex, savedPageNumber); xSemaphoreTake(renderingMutex, portMAX_DELAY); currentSpineIndex = savedSpineIndex; diff --git a/src/screens/EpubReaderScreen.h b/src/screens/EpubReaderScreen.h index 7cf4047..14bc012 100644 --- a/src/screens/EpubReaderScreen.h +++ b/src/screens/EpubReaderScreen.h @@ -4,8 +4,8 @@ #include #include #include -#include "EpubReaderFootnotesScreen.h" +#include "EpubReaderFootnotesScreen.h" #include "Screen.h" class EpubReaderScreen final : public Screen { @@ -35,7 +35,7 @@ class EpubReaderScreen final : public Screen { void navigateToHref(const char* href, bool savePosition = false); void restoreSavedPosition(); -public: + public: explicit EpubReaderScreen(GfxRenderer& renderer, InputManager& inputManager, std::unique_ptr epub, const std::function& onGoBack) : Screen(renderer, inputManager), epub(std::move(epub)), onGoBack(onGoBack) {}