diff --git a/lib/Epub/Epub/parsers/ChapterHtmlSlimParser.cpp b/lib/Epub/Epub/parsers/ChapterHtmlSlimParser.cpp index 53359179..f9793230 100644 --- a/lib/Epub/Epub/parsers/ChapterHtmlSlimParser.cpp +++ b/lib/Epub/Epub/parsers/ChapterHtmlSlimParser.cpp @@ -40,23 +40,6 @@ bool matches(const char* tag_name, const char* possible_tags[], const int possib return false; } -// flush the contents of partWordBuffer to currentTextBlock -void ChapterHtmlSlimParser::flushPartWordBuffer() { - // determine font style - EpdFontFamily::Style fontStyle = EpdFontFamily::REGULAR; - if (boldUntilDepth < depth && italicUntilDepth < depth) { - fontStyle = EpdFontFamily::BOLD_ITALIC; - } else if (boldUntilDepth < depth) { - fontStyle = EpdFontFamily::BOLD; - } else if (italicUntilDepth < depth) { - fontStyle = EpdFontFamily::ITALIC; - } - // flush the buffer - partWordBuffer[partWordBufferIndex] = '\0'; - currentTextBlock->addWord(partWordBuffer, fontStyle); - partWordBufferIndex = 0; -} - // start a new text block if needed void ChapterHtmlSlimParser::startNewTextBlock(const TextBlock::Style style) { if (currentTextBlock) { @@ -72,6 +55,7 @@ void ChapterHtmlSlimParser::startNewTextBlock(const TextBlock::Style style) { } void XMLCALL ChapterHtmlSlimParser::startElement(void* userData, const XML_Char* name, const XML_Char** atts) { + // Serial.printf("startElement: %s\n", name); auto* self = static_cast(userData); // Middle of skip @@ -142,10 +126,6 @@ void XMLCALL ChapterHtmlSlimParser::startElement(void* userData, const XML_Char* self->boldUntilDepth = std::min(self->boldUntilDepth, self->depth); } else if (matches(name, BLOCK_TAGS, NUM_BLOCK_TAGS)) { if (strcmp(name, "br") == 0) { - if (self->partWordBufferIndex > 0) { - // flush word preceding
to currentTextBlock before calling startNewTextBlock - self->flushPartWordBuffer(); - } self->startNewTextBlock(self->currentTextBlock->getStyle()); } else { self->startNewTextBlock((TextBlock::Style)self->paragraphAlignment); @@ -170,11 +150,22 @@ void XMLCALL ChapterHtmlSlimParser::characterData(void* userData, const XML_Char return; } + EpdFontFamily::Style fontStyle = EpdFontFamily::REGULAR; + if (self->boldUntilDepth < self->depth && self->italicUntilDepth < self->depth) { + fontStyle = EpdFontFamily::BOLD_ITALIC; + } else if (self->boldUntilDepth < self->depth) { + fontStyle = EpdFontFamily::BOLD; + } else if (self->italicUntilDepth < self->depth) { + fontStyle = EpdFontFamily::ITALIC; + } + for (int i = 0; i < len; i++) { if (isWhitespace(s[i])) { // Currently looking at whitespace, if there's anything in the partWordBuffer, flush it if (self->partWordBufferIndex > 0) { - self->flushPartWordBuffer(); + self->partWordBuffer[self->partWordBufferIndex] = '\0'; + self->currentTextBlock->addWord(self->partWordBuffer, fontStyle); + self->partWordBufferIndex = 0; } // Skip the whitespace char continue; @@ -196,7 +187,9 @@ void XMLCALL ChapterHtmlSlimParser::characterData(void* userData, const XML_Char // If we're about to run out of space, then cut the word off and start a new one if (self->partWordBufferIndex >= MAX_WORD_SIZE) { - self->flushPartWordBuffer(); + self->partWordBuffer[self->partWordBufferIndex] = '\0'; + self->currentTextBlock->addWord(self->partWordBuffer, fontStyle); + self->partWordBufferIndex = 0; } self->partWordBuffer[self->partWordBufferIndex++] = s[i]; @@ -227,7 +220,18 @@ void XMLCALL ChapterHtmlSlimParser::endElement(void* userData, const XML_Char* n matches(name, BOLD_TAGS, NUM_BOLD_TAGS) || matches(name, ITALIC_TAGS, NUM_ITALIC_TAGS) || self->depth == 1; if (shouldBreakText) { - self->flushPartWordBuffer(); + EpdFontFamily::Style fontStyle = EpdFontFamily::REGULAR; + if (self->boldUntilDepth < self->depth && self->italicUntilDepth < self->depth) { + fontStyle = EpdFontFamily::BOLD_ITALIC; + } else if (self->boldUntilDepth < self->depth) { + fontStyle = EpdFontFamily::BOLD; + } else if (self->italicUntilDepth < self->depth) { + fontStyle = EpdFontFamily::ITALIC; + } + + self->partWordBuffer[self->partWordBufferIndex] = '\0'; + self->currentTextBlock->addWord(self->partWordBuffer, fontStyle); + self->partWordBufferIndex = 0; } } @@ -250,9 +254,16 @@ void XMLCALL ChapterHtmlSlimParser::endElement(void* userData, const XML_Char* n } bool ChapterHtmlSlimParser::parseAndBuildPages() { - startNewTextBlock((TextBlock::Style)this->paragraphAlignment); + Serial.printf("[%lu] [EHP] parseAndBuildPages start. Heap: %u\n", millis(), ESP.getFreeHeap()); + Serial.printf("[%lu] [EHP] Calling startNewTextBlock\n", millis()); + startNewTextBlock((TextBlock::Style)this->paragraphAlignment); + Serial.printf("[%lu] [EHP] startNewTextBlock returned\n", millis()); + + Serial.printf("[%lu] [EHP] Creating XML parser\n", millis()); const XML_Parser parser = XML_ParserCreate(nullptr); + if (parser) Serial.printf("[%lu] [EHP] Parser created\n", millis()); + int done; if (!parser) { @@ -288,6 +299,7 @@ bool ChapterHtmlSlimParser::parseAndBuildPages() { } const size_t len = file.read(buf, 1024); + // Serial.printf("[%lu] [EHP] Read %d bytes\n", millis(), len); if (len == 0 && file.available() > 0) { Serial.printf("[%lu] [EHP] File read error\n", millis()); @@ -313,6 +325,7 @@ bool ChapterHtmlSlimParser::parseAndBuildPages() { done = file.available() == 0; if (XML_ParseBuffer(parser, static_cast(len), done) == XML_STATUS_ERROR) { + Serial.printf("[%lu] [EHP] XML_ParseBuffer returned error\n", millis()); Serial.printf("[%lu] [EHP] Parse error at line %lu:\n%s\n", millis(), XML_GetCurrentLineNumber(parser), XML_ErrorString(XML_GetErrorCode(parser))); XML_StopParser(parser, XML_FALSE); // Stop any pending processing @@ -322,6 +335,7 @@ bool ChapterHtmlSlimParser::parseAndBuildPages() { file.close(); return false; } + vTaskDelay(1); } while (!done); XML_StopParser(parser, XML_FALSE); // Stop any pending processing diff --git a/lib/Epub/Epub/parsers/ChapterHtmlSlimParser.h b/lib/Epub/Epub/parsers/ChapterHtmlSlimParser.h index 2d8ebe5c..5355211a 100644 --- a/lib/Epub/Epub/parsers/ChapterHtmlSlimParser.h +++ b/lib/Epub/Epub/parsers/ChapterHtmlSlimParser.h @@ -39,7 +39,6 @@ class ChapterHtmlSlimParser { bool hyphenationEnabled; void startNewTextBlock(TextBlock::Style style); - void flushPartWordBuffer(); void makePages(); // XML callbacks static void XMLCALL startElement(void* userData, const XML_Char* name, const XML_Char** atts);