Conversion: When using the Level x Table of Contents options, support the case when the level 1,2,3 items are spread over multiple HTML files.

This commit is contained in:
Kovid Goyal 2011-03-09 11:11:13 -07:00
parent 24a23a8d7e
commit 438c87e022

View File

@ -13,6 +13,7 @@ from urlparse import urlparse
from calibre.ebooks.oeb.base import XPNSMAP, TOC, XHTML, xml2text from calibre.ebooks.oeb.base import XPNSMAP, TOC, XHTML, xml2text
from calibre.ebooks import ConversionError from calibre.ebooks import ConversionError
from calibre.utils.ordered_dict import OrderedDict
def XPath(x): def XPath(x):
try: try:
@ -95,10 +96,8 @@ class DetectStructure(object):
self.log.exception('Failed to mark chapter') self.log.exception('Failed to mark chapter')
def create_level_based_toc(self): def create_level_based_toc(self):
if self.opts.level1_toc is None: if self.opts.level1_toc is not None:
return self.add_leveled_toc_items()
for item in self.oeb.spine:
self.add_leveled_toc_items(item)
def create_toc_from_chapters(self): def create_toc_from_chapters(self):
counter = self.oeb.toc.next_play_order() counter = self.oeb.toc.next_play_order()
@ -145,49 +144,57 @@ class DetectStructure(object):
return text, href return text, href
def add_leveled_toc_items(self, item): def add_leveled_toc_items(self):
level1 = XPath(self.opts.level1_toc)(item.data) added = OrderedDict()
level1_order = [] added2 = OrderedDict()
document = item
counter = 1 counter = 1
if level1: for document in self.oeb.spine:
added = {} previous_level1 = list(added.itervalues())[-1] if added else None
for elem in level1: previous_level2 = list(added2.itervalues())[-1] if added2 else None
for elem in XPath(self.opts.level1_toc)(document.data):
text, _href = self.elem_to_link(document, elem, counter) text, _href = self.elem_to_link(document, elem, counter)
counter += 1 counter += 1
if text: if text:
node = self.oeb.toc.add(text, _href, node = self.oeb.toc.add(text, _href,
play_order=self.oeb.toc.next_play_order()) play_order=self.oeb.toc.next_play_order())
level1_order.append(node)
added[elem] = node added[elem] = node
#node.add(_('Top'), _href) #node.add(_('Top'), _href)
if self.opts.level2_toc is not None:
added2 = {} if self.opts.level2_toc is not None and added:
level2 = list(XPath(self.opts.level2_toc)(document.data)) for elem in XPath(self.opts.level2_toc)(document.data):
for elem in level2:
level1 = None level1 = None
for item in document.data.iterdescendants(): for item in document.data.iterdescendants():
if item in added.keys(): if item in added:
level1 = added[item] level1 = added[item]
elif item == elem and level1 is not None: elif item == elem:
if level1 is None:
if previous_level1 is None:
break
level1 = previous_level1
text, _href = self.elem_to_link(document, elem, counter) text, _href = self.elem_to_link(document, elem, counter)
counter += 1 counter += 1
if text: if text:
added2[elem] = level1.add(text, _href, added2[elem] = level1.add(text, _href,
play_order=self.oeb.toc.next_play_order()) play_order=self.oeb.toc.next_play_order())
if self.opts.level3_toc is not None: break
level3 = list(XPath(self.opts.level3_toc)(document.data))
for elem in level3: if self.opts.level3_toc is not None and added2:
for elem in XPath(self.opts.level3_toc)(document.data):
level2 = None level2 = None
for item in document.data.iterdescendants(): for item in document.data.iterdescendants():
if item in added2.keys(): if item in added2:
level2 = added2[item] level2 = added2[item]
elif item == elem and level2 is not None: elif item == elem:
if level2 is None:
if previous_level2 is None:
break
level2 = previous_level2
text, _href = \ text, _href = \
self.elem_to_link(document, elem, counter) self.elem_to_link(document, elem, counter)
counter += 1 counter += 1
if text: if text:
level2.add(text, _href, level2.add(text, _href,
play_order=self.oeb.toc.next_play_order()) play_order=self.oeb.toc.next_play_order())
break