diff --git a/src/calibre/ebooks/mobi/output.py b/src/calibre/ebooks/mobi/output.py index ba88aa7779..aeab8518a9 100644 --- a/src/calibre/ebooks/mobi/output.py +++ b/src/calibre/ebooks/mobi/output.py @@ -50,6 +50,13 @@ class MOBIOutput(OutputFormatPlugin): help=_('When adding the Table of Contents to the book, add it at the start of the ' 'book instead of the end. Not recommended.') ), + OptionRecommendation(name='mobi_navpoints_only_deepest', + recommended_value=False, + help=_('When adding navpoints for the chapter-to-chapter' + ' navigation on the kindle, use only the lowest level ' + 'of items in the TOC, instead of items at every level.') + ), + OptionRecommendation(name='kindlegen', recommended_value=False, help=('Use kindlegen (must be in your PATH) to generate the' diff --git a/src/calibre/ebooks/mobi/writer.py b/src/calibre/ebooks/mobi/writer.py index bf71ad55c2..3769320dcd 100644 --- a/src/calibre/ebooks/mobi/writer.py +++ b/src/calibre/ebooks/mobi/writer.py @@ -1231,6 +1231,9 @@ class MobiWriter(object): self._oeb.logger.info(' Compressing markup content...') data, overlap = self._read_text_record(text) + if not self.opts.mobi_periodical: + self._flatten_toc() + # Evaluate toc for conformance if self.opts.mobi_periodical : self._oeb.logger.info(' MOBI periodical specified, evaluating TOC for periodical conformance ...') @@ -1697,6 +1700,32 @@ class MobiWriter(object): # Index {{{ + def _flatten_toc(self): + ''' + Flatten and re-order entries in TOC so that chapter to chapter jumping + never fails on the Kindle. + ''' + from calibre.ebooks.oeb.base import TOC + items = list(self._oeb.toc.iterdescendants()) + if self.opts.mobi_navpoints_only_deepest: + items = [i for i in items if i.depth == 1] + offsets = {i:self._id_offsets.get(i.href, -1) for i in items if i.href} + items = [i for i in items if offsets[i] > -1] + items.sort(key=lambda i:offsets[i]) + filt = [] + seen = set() + for i in items: + off = offsets[i] + if off in seen: continue + seen.add(off) + filt.append(i) + items = filt + newtoc = TOC() + for c, i in enumerate(items): + newtoc.add(i.title, i.href, play_order=c+1, id=str(c), + klass='chapter') + self._oeb.toc = newtoc + def _generate_index(self): self._oeb.log('Generating INDX ...') self._primary_index_record = None diff --git a/src/calibre/gui2/convert/mobi_output.py b/src/calibre/gui2/convert/mobi_output.py index fbd9ad4fcb..4bbf15e3ef 100644 --- a/src/calibre/gui2/convert/mobi_output.py +++ b/src/calibre/gui2/convert/mobi_output.py @@ -25,7 +25,8 @@ class PluginWidget(Widget, Ui_Form): Widget.__init__(self, parent, ['prefer_author_sort', 'rescale_images', 'toc_title', 'mobi_ignore_margins', 'mobi_toc_at_start', - 'dont_compress', 'no_inline_toc', 'masthead_font','personal_doc'] + 'dont_compress', 'no_inline_toc', + 'masthead_font','personal_doc', 'mobi_navpoints_only_deepest'] ) from calibre.utils.fonts import fontconfig self.db, self.book_id = db, book_id diff --git a/src/calibre/gui2/convert/mobi_output.ui b/src/calibre/gui2/convert/mobi_output.ui index 7601f80df9..b849bff72c 100644 --- a/src/calibre/gui2/convert/mobi_output.ui +++ b/src/calibre/gui2/convert/mobi_output.ui @@ -55,7 +55,7 @@ - + Kindle options @@ -101,7 +101,7 @@ - + Qt::Vertical @@ -128,6 +128,13 @@ + + + + Use only &lowest level of items in the TOC for chapter-to-chapter navigation + + +