Initial commit. FBReader 0.8.12
[lbook_fbreader.git] / fbreader / src / formats / oeb / OEBBookReader.cpp
blobe39a88454bf1e1ed3488e91b92cabd59c34be64e
1 /*
2 * Copyright (C) 2004-2008 Geometer Plus <contact@geometerplus.com>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 * 02110-1301, USA.
20 #include <algorithm>
22 #include <ZLUnicodeUtil.h>
23 #include <ZLFileImage.h>
25 #include "OEBBookReader.h"
26 #include "../xhtml/XHTMLReader.h"
27 #include "../util/MiscUtil.h"
28 #include "../../bookmodel/BookModel.h"
30 OEBBookReader::OEBBookReader(BookModel &model) : myModelReader(model) {
33 void OEBBookReader::characterDataHandler(const char*, int) {
36 static const std::string MANIFEST = "manifest";
37 static const std::string SPINE = "spine";
38 static const std::string GUIDE = "guide";
39 static const std::string TOUR = "tour";
40 static const std::string SITE = "site";
42 static const std::string ITEM = "item";
43 static const std::string ITEMREF = "itemref";
44 static const std::string REFERENCE = "reference";
46 void OEBBookReader::startElementHandler(const char *tag, const char **xmlattributes) {
47 const std::string tagString = ZLUnicodeUtil::toLower(tag);
48 if (MANIFEST == tagString) {
49 myState = READ_MANIFEST;
50 } else if (SPINE == tagString) {
51 myState = READ_SPINE;
52 } else if (GUIDE == tagString) {
53 myState = READ_GUIDE;
54 } else if (TOUR == tagString) {
55 myState = READ_TOUR;
56 } else if ((myState == READ_MANIFEST) && (ITEM == tagString)) {
57 const char *id = attributeValue(xmlattributes, "id");
58 const char *href = attributeValue(xmlattributes, "href");
59 if ((id != 0) && (href != 0)) {
60 myIdToHref[id] = href;
62 } else if ((myState == READ_SPINE) && (ITEMREF == tagString)) {
63 const char *id = attributeValue(xmlattributes, "idref");
64 if (id != 0) {
65 const std::string &fileName = myIdToHref[id];
66 if (!fileName.empty()) {
67 myHtmlFileNames.push_back(fileName);
70 } else if ((myState == READ_GUIDE) && (REFERENCE == tagString)) {
71 const char *type = attributeValue(xmlattributes, "type");
72 const char *title = attributeValue(xmlattributes, "title");
73 const char *href = attributeValue(xmlattributes, "href");
74 if (href != 0) {
75 if (title != 0) {
76 myGuideTOC.push_back(std::pair<std::string,std::string>(title, href));
78 static const std::string COVER_IMAGE = "other.ms-coverimage-standard";
79 if ((type != 0) && (COVER_IMAGE == type)) {
80 myModelReader.setMainTextModel();
81 myModelReader.addImageReference(href);
82 myModelReader.addImage(href, new ZLFileImage("image/auto", myFilePrefix + href, 0));
85 } else if ((myState == READ_TOUR) && (SITE == tagString)) {
86 const char *title = attributeValue(xmlattributes, "title");
87 const char *href = attributeValue(xmlattributes, "href");
88 if ((title != 0) && (href != 0)) {
89 myTourTOC.push_back(std::pair<std::string,std::string>(title, href));
94 void OEBBookReader::endElementHandler(const char *tag) {
95 const std::string tagString = ZLUnicodeUtil::toLower(tag);
96 if ((MANIFEST == tagString) || (SPINE == tagString) || (GUIDE == tagString) || (TOUR == tagString)) {
97 myState = READ_NONE;
101 bool OEBBookReader::readBook(const std::string &fileName) {
102 myFilePrefix = MiscUtil::htmlDirectoryPrefix(fileName);
104 myIdToHref.clear();
105 myHtmlFileNames.clear();
106 myTourTOC.clear();
107 myGuideTOC.clear();
108 myState = READ_NONE;
110 if (!readDocument(fileName)) {
111 return false;
114 myModelReader.setMainTextModel();
115 myModelReader.pushKind(REGULAR);
117 for (std::vector<std::string>::const_iterator it = myHtmlFileNames.begin(); it != myHtmlFileNames.end(); ++it) {
118 XHTMLReader(myModelReader).readFile(myFilePrefix, *it, *it);
121 std::vector<std::pair<std::string,std::string> > &toc = myTourTOC.empty() ? myGuideTOC : myTourTOC;
122 for (std::vector<std::pair<std::string,std::string> >::const_iterator it = toc.begin(); it != toc.end(); ++it) {
123 int index = myModelReader.model().label(it->second).ParagraphNumber;
124 if (index != -1) {
125 myModelReader.beginContentsParagraph(index);
126 myModelReader.addContentsData(it->first);
127 myModelReader.endContentsParagraph();
131 return true;