diff options
author | Michele Calgaro <[email protected]> | 2024-05-11 21:28:48 +0900 |
---|---|---|
committer | Michele Calgaro <[email protected]> | 2024-05-11 21:28:48 +0900 |
commit | 2462d03f322261bd616721c2b2065c4004b36c9c (patch) | |
tree | 239947a0737bb8386703a1497f12c09aebd3080a /fbreader/src/formats/openreader | |
download | tde-ebook-reader-2462d03f322261bd616721c2b2065c4004b36c9c.tar.gz tde-ebook-reader-2462d03f322261bd616721c2b2065c4004b36c9c.zip |
Initial import (as is) from Debian Snapshot's 'fbreader' source code (https://snapshot.debian.org/package/fbreader/0.99.4%2Bdfsg-6).
The Debian code is provided under GPL2 license.
Signed-off-by: Michele Calgaro <[email protected]>
Diffstat (limited to 'fbreader/src/formats/openreader')
-rw-r--r-- | fbreader/src/formats/openreader/ORBookReader.cpp | 185 | ||||
-rw-r--r-- | fbreader/src/formats/openreader/ORBookReader.h | 77 | ||||
-rw-r--r-- | fbreader/src/formats/openreader/ORDescriptionReader.cpp | 88 | ||||
-rw-r--r-- | fbreader/src/formats/openreader/ORDescriptionReader.h | 53 | ||||
-rw-r--r-- | fbreader/src/formats/openreader/OpenReaderPlugin.cpp | 52 | ||||
-rw-r--r-- | fbreader/src/formats/openreader/OpenReaderPlugin.h | 36 |
6 files changed, 491 insertions, 0 deletions
diff --git a/fbreader/src/formats/openreader/ORBookReader.cpp b/fbreader/src/formats/openreader/ORBookReader.cpp new file mode 100644 index 0000000..d494b7f --- /dev/null +++ b/fbreader/src/formats/openreader/ORBookReader.cpp @@ -0,0 +1,185 @@ +/* + * Copyright (C) 2004-2012 Geometer Plus <[email protected]> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +#include <cstring> +#include <cstdlib> +#include <algorithm> + +#include <ZLUnicodeUtil.h> +#include <ZLFileImage.h> + +#include "ORBookReader.h" +#include "../xhtml/XHTMLReader.h" +#include "../util/MiscUtil.h" +#include "../../bookmodel/BookModel.h" +#include "../../library/Book.h" + +ORBookReader::ORBookReader(BookModel &model) : myModelReader(model) { +} + +void ORBookReader::characterDataHandler(const char *data, std::size_t len) { + if (myState == READ_TOCTITLE) { + myTOCTitle.append(data, len); + } +} + +static const std::string TAG_RESOURCES = "resources"; +static const std::string TAG_USERSET = "userset"; +static const std::string TAG_NAVIGATION = "primarynav"; + +static const std::string TAG_SPINE = "spine"; +static const std::string TAG_COVER = "cover"; + +static const std::string TAG_ITEM = "item"; +static const std::string TAG_ITEMREF = "itemref"; +static const std::string TAG_POINTER = "pointer"; +static const std::string TAG_TITLE = "title"; + +static const std::string xhtmlMediaType = "application/x-orp-bcd1+xml"; + +void ORBookReader::startElementHandler(const char *tag, const char **xmlattributes) { + const std::string tagString = ZLUnicodeUtil::toLower(tag); + if (TAG_RESOURCES == tagString) { + myState = READ_RESOURCES; + } else if (TAG_USERSET == tagString) { + myState = READ_USERSET; + } else if ((myState == READ_RESOURCES) && (TAG_ITEM == tagString)) { + const char *resid = attributeValue(xmlattributes, "resid"); + const char *resource = attributeValue(xmlattributes, "resource"); + shared_ptr<ZLMimeType> mediaType = ZLMimeType::get(attributeValue(xmlattributes, "media-type")); + if ((resid != 0) && (resource != 0)) { + myResources[resid] = resource; + if (!mediaType.isNull() && mediaType != ZLMimeType::EMPTY) { + if (ZLMimeType::APPLICATION_OR_XML == mediaType) { + myHtmlFileIDs.insert(resid); + } else if (ZLMimeType::isImage(mediaType)) { + myImageIDs[resid] = mediaType; + } + } + } + } else if (myState == READ_USERSET) { + if (TAG_NAVIGATION == tagString) { + myState = READ_NAVIGATION; + } else if (TAG_SPINE == tagString) { + const char *residrefs = attributeValue(xmlattributes, "residrefs"); + if (residrefs != 0) { + while (1) { + const char *nextSpace = std::strchr(residrefs, ' '); + if (nextSpace == 0) { + if (*residrefs != '\0') { + myHtmlFilesOrder.push_back(residrefs); + } + break; + } + if (nextSpace != residrefs) { + myHtmlFilesOrder.push_back(std::string(residrefs, nextSpace - residrefs)); + } + residrefs = nextSpace + 1; + } + } + } else if (TAG_COVER == tagString) { + const char *residrefs = attributeValue(xmlattributes, "residrefs"); + if (residrefs != 0) { + myCoverReference = residrefs; + } + } + } else if (myState == READ_NAVIGATION && TAG_POINTER == tagString) { + const char *ref = attributeValue(xmlattributes, "elemrefs"); + const char *level = attributeValue(xmlattributes, "level"); + if (ref != 0 && level != 0) { + myTOCReference = ref; + myTOCLevel = std::atoi(level); + myState = READ_POINTER; + } + } else if (myState == READ_POINTER && TAG_TITLE == tagString) { + myState = READ_TOCTITLE; + } +} + +void ORBookReader::endElementHandler(const char *tag) { + const std::string tagString = ZLUnicodeUtil::toLower(tag); + if (TAG_RESOURCES == tagString || TAG_USERSET == tagString) { + myState = READ_NONE; + } else if (myState == READ_NAVIGATION && TAG_NAVIGATION == tagString) { + myState = READ_USERSET; + } else if (myState == READ_POINTER && TAG_POINTER == tagString) { + myState = READ_NAVIGATION; + } else if (myState == READ_TOCTITLE && TAG_TITLE == tagString) { + myTOC.push_back(TOCItem(myTOCReference, myTOCTitle, myTOCLevel)); + myTOCTitle.erase(); + myState = READ_POINTER; + } +} + +bool ORBookReader::readBook() { + const ZLFile &file = myModelReader.model().book()->file(); + myFilePrefix = MiscUtil::htmlDirectoryPrefix(file.path()); + + myResources.clear(); + myCoverReference.erase(); + myHtmlFileIDs.clear(); + myImageIDs.clear(); + myHtmlFilesOrder.clear(); + myTOC.clear(); + myState = READ_NONE; + + if (!readDocument(file)) { + return false; + } + + myModelReader.setMainTextModel(); + myModelReader.pushKind(REGULAR); + + if (!myCoverReference.empty()) { + myModelReader.addImageReference(myCoverReference); + } + + for (std::vector<std::string>::const_iterator it = myHtmlFilesOrder.begin(); it != myHtmlFilesOrder.end(); ++it) { + myHtmlFileIDs.erase(*it); + XHTMLReader(myModelReader).readFile(ZLFile(myFilePrefix + myResources[*it]), *it); + } + + int level = 1; + for (std::vector<TOCItem>::const_iterator it = myTOC.begin(); it != myTOC.end(); ++it) { + int index = myModelReader.model().label(it->Reference).ParagraphNumber; + if (index != -1) { + for (; level > it->Level; --level) { + myModelReader.endContentsParagraph(); + } + ++level; + myModelReader.beginContentsParagraph(index); + myModelReader.addContentsData(it->Text); + } + } + for (; level > 1; --level) { + myModelReader.endContentsParagraph(); + } + + for (std::set<std::string>::const_iterator it = myHtmlFileIDs.begin(); it != myHtmlFileIDs.end(); ++it) { + myModelReader.setFootnoteTextModel(*it); + myModelReader.pushKind(REGULAR); + XHTMLReader(myModelReader).readFile(ZLFile(myFilePrefix + myResources[*it]), *it); + } + + for (std::map<std::string,shared_ptr<ZLMimeType> >::const_iterator it = myImageIDs.begin(); it != myImageIDs.end(); ++it) { + myModelReader.addImage(it->first, new ZLFileImage(ZLFile(myFilePrefix + myResources[it->first], it->second), 0)); + } + + return true; +} diff --git a/fbreader/src/formats/openreader/ORBookReader.h b/fbreader/src/formats/openreader/ORBookReader.h new file mode 100644 index 0000000..160c9f1 --- /dev/null +++ b/fbreader/src/formats/openreader/ORBookReader.h @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2004-2012 Geometer Plus <[email protected]> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +#ifndef __ORBOOKREADER_H__ +#define __ORBOOKREADER_H__ + +#include <map> +#include <set> +#include <vector> +#include <string> + +#include <ZLXMLReader.h> + +#include "../../bookmodel/BookReader.h" + +class ORBookReader : public ZLXMLReader { + +public: + ORBookReader(BookModel &model); + bool readBook(); + + void startElementHandler(const char *tag, const char **attributes); + void endElementHandler(const char *tag); + void characterDataHandler(const char *text, std::size_t len); + +private: + enum ReaderState { + READ_NONE, + READ_RESOURCES, + READ_USERSET, + READ_NAVIGATION, + READ_POINTER, + READ_TOCTITLE + }; + + BookReader myModelReader; + ReaderState myState; + + std::string myFilePrefix; + std::map<std::string,std::string> myResources; + std::string myCoverReference; + std::set<std::string> myHtmlFileIDs; + std::map<std::string,shared_ptr<ZLMimeType> > myImageIDs; + std::vector<std::string> myHtmlFilesOrder; + + struct TOCItem { + TOCItem(const std::string &reference, const std::string &text, int level) : Reference(reference), Text(text), Level(level) { + } + + std::string Reference; + std::string Text; + int Level; + }; + std::vector<TOCItem> myTOC; + + std::string myTOCReference; + int myTOCLevel; + std::string myTOCTitle; +}; + +#endif /* __ORBOOKREADER_H__ */ diff --git a/fbreader/src/formats/openreader/ORDescriptionReader.cpp b/fbreader/src/formats/openreader/ORDescriptionReader.cpp new file mode 100644 index 0000000..8c80dfa --- /dev/null +++ b/fbreader/src/formats/openreader/ORDescriptionReader.cpp @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2004-2012 Geometer Plus <[email protected]> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +#include <ZLUnicodeUtil.h> + +#include "ORDescriptionReader.h" + +#include "../util/EntityFilesCollector.h" +#include "../../library/Book.h" + +ORDescriptionReader::ORDescriptionReader(Book &book) : myBook(book) { + myBook.removeAllAuthors(); + myBook.setTitle(""); +} + +// TODO: replace "dc" by real DC scheme name +static const std::string METADATA = "metadata"; +static const std::string TITLE = "dc:title"; +static const std::string AUTHOR_TAG = "dc:creator"; +static const std::string AUTHOR_ROLE = "aut"; + +void ORDescriptionReader::characterDataHandler(const char *text, std::size_t len) { + switch (myReadState) { + case READ_NONE: + break; + case READ_AUTHOR: + myCurrentAuthor.append(text, len); + break; + case READ_TITLE: + myBook.setTitle(myBook.title() + std::string(text, len)); + break; + } +} + +void ORDescriptionReader::startElementHandler(const char *tag, const char **attributes) { + const std::string tagString = ZLUnicodeUtil::toLower(tag); + if (METADATA == tagString) { + myReadMetaData = true; + } else if (myReadMetaData) { + if (TITLE == tagString) { + myReadState = READ_TITLE; + } else if (AUTHOR_TAG == tagString) { + const char *role = attributeValue(attributes, "role"); + if ((role != 0) && (AUTHOR_ROLE == role)) { + myReadState = READ_AUTHOR; + } + } + } +} + +void ORDescriptionReader::endElementHandler(const char *tag) { + const std::string tagString = ZLUnicodeUtil::toLower(tag); + if (METADATA == tagString) { + interrupt(); + } else { + if (!myCurrentAuthor.empty()) { + myBook.addAuthor(myCurrentAuthor); + myCurrentAuthor.erase(); + } + myReadState = READ_NONE; + } +} + +bool ORDescriptionReader::readMetaInfo() { + myReadMetaData = false; + myReadState = READ_NONE; + return readDocument(myBook.file()); +} + +const std::vector<std::string> &ORDescriptionReader::externalDTDs() const { + return EntityFilesCollector::Instance().externalDTDs("xhtml"); +} diff --git a/fbreader/src/formats/openreader/ORDescriptionReader.h b/fbreader/src/formats/openreader/ORDescriptionReader.h new file mode 100644 index 0000000..a4f6b2a --- /dev/null +++ b/fbreader/src/formats/openreader/ORDescriptionReader.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2004-2012 Geometer Plus <[email protected]> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +#ifndef __ORDESCRIPTIONREADER_H__ +#define __ORDESCRIPTIONREADER_H__ + +#include <ZLXMLReader.h> + +class Book; + +class ORDescriptionReader : public ZLXMLReader { + +public: + ORDescriptionReader(Book &book); + bool readMetaInfo(); + +private: + void startElementHandler(const char *tag, const char **attributes); + void endElementHandler(const char *tag); + void characterDataHandler(const char *text, std::size_t len); + + const std::vector<std::string> &externalDTDs() const; + +private: + Book &myBook; + + bool myReadMetaData; + enum { + READ_NONE, + READ_AUTHOR, + READ_TITLE + } myReadState; + + std::string myCurrentAuthor; +}; + +#endif /* __ORDESCRIPTIONREADER_H__ */ diff --git a/fbreader/src/formats/openreader/OpenReaderPlugin.cpp b/fbreader/src/formats/openreader/OpenReaderPlugin.cpp new file mode 100644 index 0000000..545f83b --- /dev/null +++ b/fbreader/src/formats/openreader/OpenReaderPlugin.cpp @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2004-2012 Geometer Plus <[email protected]> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +#include <ZLFile.h> +#include <ZLStringUtil.h> +#include <ZLDir.h> + +#include "OpenReaderPlugin.h" +#include "ORDescriptionReader.h" +#include "ORBookReader.h" + +#include "../../library/Book.h" + +OpenReaderPlugin::~OpenReaderPlugin() { +} + +bool OpenReaderPlugin::providesMetaInfo() const { + return true; +} + +bool OpenReaderPlugin::acceptsFile(const ZLFile &file) const { + return file.extension() == "orb"; +} + +bool OpenReaderPlugin::readMetaInfo(Book &book) const { + return ORDescriptionReader(book).readMetaInfo(); +} + +bool OpenReaderPlugin::readLanguageAndEncoding(Book &book) const { + (void)book; + return true; +} + +bool OpenReaderPlugin::readModel(BookModel &model) const { + return ORBookReader(model).readBook(); +} diff --git a/fbreader/src/formats/openreader/OpenReaderPlugin.h b/fbreader/src/formats/openreader/OpenReaderPlugin.h new file mode 100644 index 0000000..fcfaa11 --- /dev/null +++ b/fbreader/src/formats/openreader/OpenReaderPlugin.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2004-2012 Geometer Plus <[email protected]> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +#ifndef __OPENREADERPLUGIN_H__ +#define __OPENREADERPLUGIN_H__ + +#include "../FormatPlugin.h" + +class OpenReaderPlugin : public FormatPlugin { + +public: + ~OpenReaderPlugin(); + bool providesMetaInfo() const; + bool acceptsFile(const ZLFile &file) const; + bool readMetaInfo(Book &book) const; + bool readLanguageAndEncoding(Book &book) const; + bool readModel(BookModel &model) const; +}; + +#endif /* __OPENREADERPLUGIN_H__ */ |