diff --git a/src/calibre/ebooks/metadata/opf2.py b/src/calibre/ebooks/metadata/opf2.py index e4c6d19321..4a19a6492d 100644 --- a/src/calibre/ebooks/metadata/opf2.py +++ b/src/calibre/ebooks/metadata/opf2.py @@ -270,6 +270,7 @@ class Spine(ResourceCollection): Resource.__init__(self, *args, **kwargs) self.is_linear = True self.id = idfunc(self.path) + self.idref = None @staticmethod def from_opf_spine_element(itemrefs, manifest): @@ -281,6 +282,7 @@ class Spine(ResourceCollection): if path: r = Spine.Item(s.manifest.id_for_path, path, is_path=True) r.is_linear = itemref.get('linear', 'yes') == 'yes' + r.idref = idref s.append(r) return s diff --git a/src/calibre/ebooks/oeb/iterator.py b/src/calibre/ebooks/oeb/iterator.py index 05bbe7410d..762b14c3e5 100644 --- a/src/calibre/ebooks/oeb/iterator.py +++ b/src/calibre/ebooks/oeb/iterator.py @@ -19,6 +19,7 @@ from calibre.utils.zipfile import safe_replace, ZipFile from calibre.utils.config import DynamicConfig from calibre.utils.logging import Log from calibre.ebooks.epub.output import EPUBOutput +from calibre import guess_type TITLEPAGE = EPUBOutput.TITLEPAGE_COVER.decode('utf-8') @@ -39,20 +40,20 @@ class UnsupportedFormatError(Exception): class SpineItem(unicode): - def __new__(cls, *args): - args = list(args) - path = args[0] + def __new__(cls, path, mime_type=None): ppath = path.partition('#')[0] if not os.path.exists(path) and os.path.exists(ppath): path = ppath - args[0] = path - obj = super(SpineItem, cls).__new__(cls, *args) + obj = super(SpineItem, cls).__new__(cls, path) raw = open(path, 'rb').read() raw, obj.encoding = xml_to_unicode(raw) obj.character_count = character_count(raw) obj.start_page = -1 obj.pages = -1 obj.max_page = -1 + if mime_type is None: + mime_type = guess_type(obj)[0] + obj.mime_type = mime_type return obj class FakeOpts(object): @@ -150,8 +151,17 @@ class EbookIterator(object): self.language = self.opf.language if self.language: self.language = self.language.lower() - self.spine = [SpineItem(i.path) for i in self.opf.spine if i.is_linear] - self.spine += [SpineItem(i.path) for i in self.opf.spine if not i.is_linear] + ordered = [i for i in self.opf.spine if i.is_linear] + \ + [i for i in self.opf.spine if not i.is_linear] + self.spine = [] + for i in ordered: + spath = i.path + mt = None + if i.idref is not None: + mt = self.opf.manifest.type_for_id(i.idref) + if mt is None: + mt = guess_type(spath)[0] + self.spine.append(SpineItem(spath, mime_type=mt)) cover = self.opf.cover if self.ebook_ext in ('lit', 'mobi', 'prc', 'opf') and cover: diff --git a/src/calibre/gui2/viewer/documentview.py b/src/calibre/gui2/viewer/documentview.py index f6e6e2972d..aeaf8e2c4f 100644 --- a/src/calibre/gui2/viewer/documentview.py +++ b/src/calibre/gui2/viewer/documentview.py @@ -18,7 +18,7 @@ from calibre.gui2.viewer.config_ui import Ui_Dialog from calibre.gui2.viewer.js import bookmarks, referencing, hyphenation from calibre.ptempfile import PersistentTemporaryFile from calibre.constants import iswindows -from calibre import prints +from calibre import prints, guess_type def load_builtin_fonts(): base = P('fonts/liberation/*.ttf') @@ -352,6 +352,8 @@ class DocumentView(QWebView): def __init__(self, *args): QWidget.__init__(self, *args) self.debug_javascript = False + self.self_closing_pat = re.compile(r'<([a-z]+)\s+([^>]+)/>', + re.IGNORECASE) self.setSizePolicy(QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)) self._size_hint = QSize(510, 680) self.initial_pos = 0.0 @@ -447,8 +449,14 @@ class DocumentView(QWebView): def load_path(self, path, pos=0.0): self.initial_pos = pos + mt = getattr(path, 'mime_type', None) + if mt is None: + mt = guess_type(path)[0] html = open(path, 'rb').read().decode(path.encoding, 'replace') html = EntityDeclarationProcessor(html).processed_html + if 'xhtml' in mt: + html = self.self_closing_pat.sub(r'<\1 \2>', html) + #self.setContent(QByteArray(html.encode(path.encoding)), mt, QUrl.fromLocalFile(path)) self.setHtml(html, QUrl.fromLocalFile(path)) self.turn_off_internal_scrollbars()