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
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
) {
52 } else if (GUIDE
== tagString
) {
54 } else if (TOUR
== tagString
) {
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");
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");
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
)) {
101 bool OEBBookReader::readBook(const std::string
&fileName
) {
102 myFilePrefix
= MiscUtil::htmlDirectoryPrefix(fileName
);
105 myHtmlFileNames
.clear();
110 if (!readDocument(fileName
)) {
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
;
125 myModelReader
.beginContentsParagraph(index
);
126 myModelReader
.addContentsData(it
->first
);
127 myModelReader
.endContentsParagraph();