EPUB3 Input: Fix Table of Contents not being recognized for some EPUB 3 books that placed their nav document in-side a sub-folder. Fixes #1773627 [Table of Contents](https://bugs.launchpad.net/calibre/+bug/1773627)

This commit is contained in:
Kovid Goyal 2018-05-28 13:02:18 +05:30
parent 51e20f7354
commit 5f7e5bf155
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
2 changed files with 10 additions and 19 deletions

View File

@ -399,7 +399,8 @@ class EPUBInput(InputFormatPlugin):
with NamedTemporaryFile(suffix='.ncx', dir=os.path.dirname(nav_path), delete=False) as f:
f.write(etree.tostring(ncx, encoding='utf-8'))
ncx_id = opf.add_path_to_manifest(f.name, NCX_MIME)
ncx_href = os.path.relpath(f.name, os.getcwdu()).replace(os.sep, '/')
ncx_id = opf.create_manifest_item(ncx_href, NCX_MIME, append=True).get('id')
for spine in opf.root.xpath('//*[local-name()="spine"]'):
spine.set('toc', ncx_id)
opts.epub3_nav_href = urlnormalize(os.path.relpath(nav_path).replace(os.sep, '/'))

View File

@ -533,16 +533,16 @@ class OPF(object): # {{{
authors_path = XPath('descendant::*[re:match(name(), "creator", "i") and (@role="aut" or @opf:role="aut" or (not(@role) and not(@opf:role)))]')
bkp_path = XPath('descendant::*[re:match(name(), "contributor", "i") and (@role="bkp" or @opf:role="bkp")]')
tags_path = XPath('descendant::*[re:match(name(), "subject", "i")]')
isbn_path = XPath('descendant::*[re:match(name(), "identifier", "i") and '+
isbn_path = XPath('descendant::*[re:match(name(), "identifier", "i") and '
'(re:match(@scheme, "isbn", "i") or re:match(@opf:scheme, "isbn", "i"))]')
pubdate_path = XPath('descendant::*[re:match(name(), "date", "i")]')
raster_cover_path = XPath('descendant::*[re:match(name(), "meta", "i") and ' +
raster_cover_path = XPath('descendant::*[re:match(name(), "meta", "i") and '
're:match(@name, "cover", "i") and @content]')
guide_cover_path = XPath('descendant::*[local-name()="guide"]/*[local-name()="reference" and re:match(@type, "cover", "i")]/@href')
identifier_path = XPath('descendant::*[re:match(name(), "identifier", "i")]')
application_id_path = XPath('descendant::*[re:match(name(), "identifier", "i") and '+
application_id_path = XPath('descendant::*[re:match(name(), "identifier", "i") and '
'(re:match(@opf:scheme, "calibre|libprs500", "i") or re:match(@scheme, "calibre|libprs500", "i"))]')
uuid_id_path = XPath('descendant::*[re:match(name(), "identifier", "i") and '+
uuid_id_path = XPath('descendant::*[re:match(name(), "identifier", "i") and '
'(re:match(@opf:scheme, "uuid", "i") or re:match(@scheme, "uuid", "i"))]')
languages_path = XPath('descendant::*[local-name()="language"]')
@ -705,7 +705,7 @@ class OPF(object): # {{{
def itermanifest(self):
return self.manifest_path(self.root)
def create_manifest_item(self, href, media_type):
def create_manifest_item(self, href, media_type, append=False):
ids = [i.get('id', None) for i in self.itermanifest()]
id = None
for c in xrange(1, sys.maxint):
@ -717,6 +717,9 @@ class OPF(object): # {{{
ans = etree.Element('{%s}item'%self.NAMESPACES['opf'],
attrib={'id':id, 'href':href, 'media-type':media_type})
ans.tail = '\n\t\t'
if append:
manifest = self.manifest_ppath(self.root)[0]
manifest.append(ans)
return ans
def replace_manifest_item(self, item, items):
@ -728,19 +731,6 @@ class OPF(object): # {{{
manifest[index:index+1] = items
return [i.get('id') for i in items]
def add_path_to_manifest(self, path, media_type):
path = os.path.abspath(path)
for i in self.itermanifest():
xpath = os.path.join(self.base_dir, *(i.get('href', '').split('/')))
if os.path.abspath(xpath) == path:
return i.get('id')
href = os.path.relpath(path, self.base_dir).replace(os.sep, '/')
item = self.create_manifest_item(href, media_type)
manifest = self.manifest_ppath(self.root)[0]
manifest.append(item)
self.manifest.append_from_opf_manifest_item(item, self.basedir)
return item.get('id')
def iterspine(self):
return self.spine_path(self.root)