From 5872edc9b2d1cc668ab4275eac9b83213b0be39d Mon Sep 17 00:00:00 2001 From: Dave Allie Date: Tue, 30 Dec 2025 21:15:44 +1000 Subject: [PATCH] Parse the author name from content.opf file (#165) ## Summary * Parse the author name from content.opf file * Listed in the dc:creator tag within the metadata section --- lib/Epub/Epub.cpp | 12 ++++++++++-- lib/Epub/Epub.h | 1 + lib/Epub/Epub/parsers/ContentOpfParser.cpp | 15 +++++++++++++++ lib/Epub/Epub/parsers/ContentOpfParser.h | 2 ++ 4 files changed, 28 insertions(+), 2 deletions(-) diff --git a/lib/Epub/Epub.cpp b/lib/Epub/Epub.cpp index 00417780..29a89243 100644 --- a/lib/Epub/Epub.cpp +++ b/lib/Epub/Epub.cpp @@ -72,8 +72,7 @@ bool Epub::parseContentOpf(BookMetadataCache::BookMetadata& bookMetadata) { // Grab data from opfParser into epub bookMetadata.title = opfParser.title; - // TODO: Parse author - bookMetadata.author = ""; + bookMetadata.author = opfParser.author; bookMetadata.coverItemHref = opfParser.coverItemHref; bookMetadata.textReferenceHref = opfParser.textReferenceHref; @@ -254,6 +253,15 @@ const std::string& Epub::getTitle() const { return bookMetadataCache->coreMetadata.title; } +const std::string& Epub::getAuthor() const { + static std::string blank; + if (!bookMetadataCache || !bookMetadataCache->isLoaded()) { + return blank; + } + + return bookMetadataCache->coreMetadata.author; +} + std::string Epub::getCoverBmpPath() const { return cachePath + "/cover.bmp"; } bool Epub::generateCoverBmp() const { diff --git a/lib/Epub/Epub.h b/lib/Epub/Epub.h index 7ab8bcc4..4bd9c46f 100644 --- a/lib/Epub/Epub.h +++ b/lib/Epub/Epub.h @@ -40,6 +40,7 @@ class Epub { const std::string& getCachePath() const; const std::string& getPath() const; const std::string& getTitle() const; + const std::string& getAuthor() const; std::string getCoverBmpPath() const; bool generateCoverBmp() const; uint8_t* readItemContentsToBytes(const std::string& itemHref, size_t* size = nullptr, diff --git a/lib/Epub/Epub/parsers/ContentOpfParser.cpp b/lib/Epub/Epub/parsers/ContentOpfParser.cpp index 4ac83cc3..c9398778 100644 --- a/lib/Epub/Epub/parsers/ContentOpfParser.cpp +++ b/lib/Epub/Epub/parsers/ContentOpfParser.cpp @@ -102,6 +102,11 @@ void XMLCALL ContentOpfParser::startElement(void* userData, const XML_Char* name return; } + if (self->state == IN_METADATA && strcmp(name, "dc:creator") == 0) { + self->state = IN_BOOK_AUTHOR; + return; + } + if (self->state == IN_PACKAGE && (strcmp(name, "manifest") == 0 || strcmp(name, "opf:manifest") == 0)) { self->state = IN_MANIFEST; if (!SdMan.openFileForWrite("COF", self->cachePath + itemCacheFile, self->tempItemStore)) { @@ -244,6 +249,11 @@ void XMLCALL ContentOpfParser::characterData(void* userData, const XML_Char* s, self->title.append(s, len); return; } + + if (self->state == IN_BOOK_AUTHOR) { + self->author.append(s, len); + return; + } } void XMLCALL ContentOpfParser::endElement(void* userData, const XML_Char* name) { @@ -273,6 +283,11 @@ void XMLCALL ContentOpfParser::endElement(void* userData, const XML_Char* name) return; } + if (self->state == IN_BOOK_AUTHOR && strcmp(name, "dc:creator") == 0) { + self->state = IN_METADATA; + return; + } + if (self->state == IN_METADATA && (strcmp(name, "metadata") == 0 || strcmp(name, "opf:metadata") == 0)) { self->state = IN_PACKAGE; return; diff --git a/lib/Epub/Epub/parsers/ContentOpfParser.h b/lib/Epub/Epub/parsers/ContentOpfParser.h index 11eef596..245fca3b 100644 --- a/lib/Epub/Epub/parsers/ContentOpfParser.h +++ b/lib/Epub/Epub/parsers/ContentOpfParser.h @@ -12,6 +12,7 @@ class ContentOpfParser final : public Print { IN_PACKAGE, IN_METADATA, IN_BOOK_TITLE, + IN_BOOK_AUTHOR, IN_MANIFEST, IN_SPINE, IN_GUIDE, @@ -32,6 +33,7 @@ class ContentOpfParser final : public Print { public: std::string title; + std::string author; std::string tocNcxPath; std::string coverItemHref; std::string textReferenceHref;