Ebook viewer: handle self closed tags in XHTML docs correctly. Fixes #3727 (Ebook-viewer problems with valid xhtml)

This commit is contained in:
Kovid Goyal 2009-10-20 16:22:04 -06:00
parent 2e6b286a81
commit f279fcb5c3
3 changed files with 28 additions and 8 deletions

View File

@ -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

View File

@ -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:

View File

@ -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></\1>', html)
#self.setContent(QByteArray(html.encode(path.encoding)), mt, QUrl.fromLocalFile(path))
self.setHtml(html, QUrl.fromLocalFile(path))
self.turn_off_internal_scrollbars()