mirror of
https://github.com/daveallie/crosspoint-reader.git
synced 2026-02-05 07:07:38 +03:00
parent
0e0dd5bc9c
commit
974b7f28b7
@ -40,6 +40,23 @@ bool matches(const char* tag_name, const char* possible_tags[], const int possib
|
|||||||
return false;
|
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
|
// start a new text block if needed
|
||||||
void ChapterHtmlSlimParser::startNewTextBlock(const TextBlock::Style style) {
|
void ChapterHtmlSlimParser::startNewTextBlock(const TextBlock::Style style) {
|
||||||
if (currentTextBlock) {
|
if (currentTextBlock) {
|
||||||
@ -55,7 +72,6 @@ void ChapterHtmlSlimParser::startNewTextBlock(const TextBlock::Style style) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void XMLCALL ChapterHtmlSlimParser::startElement(void* userData, const XML_Char* name, const XML_Char** atts) {
|
void XMLCALL ChapterHtmlSlimParser::startElement(void* userData, const XML_Char* name, const XML_Char** atts) {
|
||||||
// Serial.printf("startElement: %s\n", name);
|
|
||||||
auto* self = static_cast<ChapterHtmlSlimParser*>(userData);
|
auto* self = static_cast<ChapterHtmlSlimParser*>(userData);
|
||||||
|
|
||||||
// Middle of skip
|
// Middle of skip
|
||||||
@ -126,6 +142,10 @@ void XMLCALL ChapterHtmlSlimParser::startElement(void* userData, const XML_Char*
|
|||||||
self->boldUntilDepth = std::min(self->boldUntilDepth, self->depth);
|
self->boldUntilDepth = std::min(self->boldUntilDepth, self->depth);
|
||||||
} else if (matches(name, BLOCK_TAGS, NUM_BLOCK_TAGS)) {
|
} else if (matches(name, BLOCK_TAGS, NUM_BLOCK_TAGS)) {
|
||||||
if (strcmp(name, "br") == 0) {
|
if (strcmp(name, "br") == 0) {
|
||||||
|
if (self->partWordBufferIndex > 0) {
|
||||||
|
// flush word preceding <br/> to currentTextBlock before calling startNewTextBlock
|
||||||
|
self->flushPartWordBuffer();
|
||||||
|
}
|
||||||
self->startNewTextBlock(self->currentTextBlock->getStyle());
|
self->startNewTextBlock(self->currentTextBlock->getStyle());
|
||||||
} else {
|
} else {
|
||||||
self->startNewTextBlock((TextBlock::Style)self->paragraphAlignment);
|
self->startNewTextBlock((TextBlock::Style)self->paragraphAlignment);
|
||||||
@ -150,22 +170,11 @@ void XMLCALL ChapterHtmlSlimParser::characterData(void* userData, const XML_Char
|
|||||||
return;
|
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++) {
|
for (int i = 0; i < len; i++) {
|
||||||
if (isWhitespace(s[i])) {
|
if (isWhitespace(s[i])) {
|
||||||
// Currently looking at whitespace, if there's anything in the partWordBuffer, flush it
|
// Currently looking at whitespace, if there's anything in the partWordBuffer, flush it
|
||||||
if (self->partWordBufferIndex > 0) {
|
if (self->partWordBufferIndex > 0) {
|
||||||
self->partWordBuffer[self->partWordBufferIndex] = '\0';
|
self->flushPartWordBuffer();
|
||||||
self->currentTextBlock->addWord(self->partWordBuffer, fontStyle);
|
|
||||||
self->partWordBufferIndex = 0;
|
|
||||||
}
|
}
|
||||||
// Skip the whitespace char
|
// Skip the whitespace char
|
||||||
continue;
|
continue;
|
||||||
@ -187,9 +196,7 @@ 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 we're about to run out of space, then cut the word off and start a new one
|
||||||
if (self->partWordBufferIndex >= MAX_WORD_SIZE) {
|
if (self->partWordBufferIndex >= MAX_WORD_SIZE) {
|
||||||
self->partWordBuffer[self->partWordBufferIndex] = '\0';
|
self->flushPartWordBuffer();
|
||||||
self->currentTextBlock->addWord(self->partWordBuffer, fontStyle);
|
|
||||||
self->partWordBufferIndex = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self->partWordBuffer[self->partWordBufferIndex++] = s[i];
|
self->partWordBuffer[self->partWordBufferIndex++] = s[i];
|
||||||
@ -220,18 +227,7 @@ 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;
|
matches(name, BOLD_TAGS, NUM_BOLD_TAGS) || matches(name, ITALIC_TAGS, NUM_ITALIC_TAGS) || self->depth == 1;
|
||||||
|
|
||||||
if (shouldBreakText) {
|
if (shouldBreakText) {
|
||||||
EpdFontFamily::Style fontStyle = EpdFontFamily::REGULAR;
|
self->flushPartWordBuffer();
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -254,16 +250,9 @@ void XMLCALL ChapterHtmlSlimParser::endElement(void* userData, const XML_Char* n
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool ChapterHtmlSlimParser::parseAndBuildPages() {
|
bool ChapterHtmlSlimParser::parseAndBuildPages() {
|
||||||
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);
|
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);
|
const XML_Parser parser = XML_ParserCreate(nullptr);
|
||||||
if (parser) Serial.printf("[%lu] [EHP] Parser created\n", millis());
|
|
||||||
|
|
||||||
int done;
|
int done;
|
||||||
|
|
||||||
if (!parser) {
|
if (!parser) {
|
||||||
@ -299,7 +288,6 @@ bool ChapterHtmlSlimParser::parseAndBuildPages() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const size_t len = file.read(buf, 1024);
|
const size_t len = file.read(buf, 1024);
|
||||||
// Serial.printf("[%lu] [EHP] Read %d bytes\n", millis(), len);
|
|
||||||
|
|
||||||
if (len == 0 && file.available() > 0) {
|
if (len == 0 && file.available() > 0) {
|
||||||
Serial.printf("[%lu] [EHP] File read error\n", millis());
|
Serial.printf("[%lu] [EHP] File read error\n", millis());
|
||||||
@ -325,7 +313,6 @@ bool ChapterHtmlSlimParser::parseAndBuildPages() {
|
|||||||
done = file.available() == 0;
|
done = file.available() == 0;
|
||||||
|
|
||||||
if (XML_ParseBuffer(parser, static_cast<int>(len), done) == XML_STATUS_ERROR) {
|
if (XML_ParseBuffer(parser, static_cast<int>(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),
|
Serial.printf("[%lu] [EHP] Parse error at line %lu:\n%s\n", millis(), XML_GetCurrentLineNumber(parser),
|
||||||
XML_ErrorString(XML_GetErrorCode(parser)));
|
XML_ErrorString(XML_GetErrorCode(parser)));
|
||||||
XML_StopParser(parser, XML_FALSE); // Stop any pending processing
|
XML_StopParser(parser, XML_FALSE); // Stop any pending processing
|
||||||
@ -335,7 +322,6 @@ bool ChapterHtmlSlimParser::parseAndBuildPages() {
|
|||||||
file.close();
|
file.close();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
vTaskDelay(1);
|
|
||||||
} while (!done);
|
} while (!done);
|
||||||
|
|
||||||
XML_StopParser(parser, XML_FALSE); // Stop any pending processing
|
XML_StopParser(parser, XML_FALSE); // Stop any pending processing
|
||||||
|
|||||||
@ -39,6 +39,7 @@ class ChapterHtmlSlimParser {
|
|||||||
bool hyphenationEnabled;
|
bool hyphenationEnabled;
|
||||||
|
|
||||||
void startNewTextBlock(TextBlock::Style style);
|
void startNewTextBlock(TextBlock::Style style);
|
||||||
|
void flushPartWordBuffer();
|
||||||
void makePages();
|
void makePages();
|
||||||
// XML callbacks
|
// XML callbacks
|
||||||
static void XMLCALL startElement(void* userData, const XML_Char* name, const XML_Char** atts);
|
static void XMLCALL startElement(void* userData, const XML_Char* name, const XML_Char** atts);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user