diff --git a/src/calibre/ebooks/epub/__init__.py b/src/calibre/ebooks/epub/__init__.py
index 4e305b000b..1bbb80cf13 100644
--- a/src/calibre/ebooks/epub/__init__.py
+++ b/src/calibre/ebooks/epub/__init__.py
@@ -142,6 +142,8 @@ to auto-generate a Table of Contents.
help=_('XPath expression that specifies all tags that should be added to the Table of Contents at level one. If this is specified, it takes precedence over other forms of auto-detection.'))
toc('level2_toc', ['--level2-toc'], default=None,
help=_('XPath expression that specifies all tags that should be added to the Table of Contents at level two. Each entry is added under the previous level one entry.'))
+ toc('level3_toc', ['--level3-toc'], default=None,
+ help=_('XPath expression that specifies all tags that should be added to the Table of Contents at level three. Each entry is added under the previous level two entry.'))
toc('from_ncx', ['--from-ncx'], default=None,
help=_('Path to a .ncx file that contains the table of contents to use for this ebook. The NCX file should contain links relative to the directory it is placed in. See http://www.niso.org/workrooms/daisy/Z39-86-2005.html#NCX for an overview of the NCX format.'))
toc('use_auto_toc', ['--use-auto-toc'], default=False,
diff --git a/src/calibre/ebooks/epub/from_html.py b/src/calibre/ebooks/epub/from_html.py
index 458fca152c..30191617a5 100644
--- a/src/calibre/ebooks/epub/from_html.py
+++ b/src/calibre/ebooks/epub/from_html.py
@@ -377,16 +377,13 @@ def convert(htmlfile, opts, notification=None, create_epub=True,
mi = merge_metadata(htmlfile, opf, opts)
opts.chapter = XPath(opts.chapter,
namespaces={'re':'http://exslt.org/regular-expressions'})
- if opts.level1_toc:
- opts.level1_toc = XPath(opts.level1_toc,
- namespaces={'re':'http://exslt.org/regular-expressions'})
- else:
- opts.level1_toc = None
- if opts.level2_toc:
- opts.level2_toc = XPath(opts.level2_toc,
- namespaces={'re':'http://exslt.org/regular-expressions'})
- else:
- opts.level2_toc = None
+ for x in (1, 2, 3):
+ attr = 'level%d_toc'%x
+ if getattr(opts, attr):
+ setattr(opts, attr, XPath(getattr(opts, attr),
+ namespaces={'re':'http://exslt.org/regular-expressions'}))
+ else:
+ setattr(opts, attr, None)
with TemporaryDirectory(suffix='_html2epub', keep=opts.keep_intermediate) as tdir:
if opts.keep_intermediate:
diff --git a/src/calibre/ebooks/html.py b/src/calibre/ebooks/html.py
index 32601320d4..47001a95fc 100644
--- a/src/calibre/ebooks/html.py
+++ b/src/calibre/ebooks/html.py
@@ -647,6 +647,7 @@ class Processor(Parser):
added[elem] = add_item(_href, frag, text, toc, type='chapter')
add_item(_href, frag, 'Top', added[elem], type='chapter')
if self.opts.level2_toc is not None:
+ added2 = {}
level2 = list(self.opts.level2_toc(self.root))
for elem in level2:
level1 = None
@@ -657,7 +658,21 @@ class Processor(Parser):
text, _href, frag = elem_to_link(elem, href, counter)
counter += 1
if text:
+ added2[elem] = \
add_item(_href, frag, text, level1, type='chapter')
+ if self.opts.level3_toc is not None:
+ level3 = list(self.opts.level3_toc(self.root))
+ for elem in level3:
+ level2 = None
+ for item in self.root.iterdescendants():
+ if item in added2.keys():
+ level2 = added2[item]
+ elif item == elem and level2 is not None:
+ text, _href, frag = elem_to_link(elem, href, counter)
+ counter += 1
+ if text:
+ add_item(_href, frag, text, level2, type='chapter')
+
if len(toc) > 0:
return
diff --git a/src/calibre/gui2/dialogs/epub.py b/src/calibre/gui2/dialogs/epub.py
index 161534a103..614f18e5b4 100644
--- a/src/calibre/gui2/dialogs/epub.py
+++ b/src/calibre/gui2/dialogs/epub.py
@@ -252,7 +252,7 @@ class Config(ResizableDialog, Ui_Dialog):
self.source_format = d.format()
def accept(self):
- for opt in ('chapter', 'level1_toc', 'level2_toc'):
+ for opt in ('chapter', 'level1_toc', 'level2_toc', 'level3_toc'):
text = unicode(getattr(self, 'opt_'+opt).text())
if text:
try:
diff --git a/src/calibre/gui2/dialogs/epub.ui b/src/calibre/gui2/dialogs/epub.ui
index cfa136e85f..a346bed4e8 100644
--- a/src/calibre/gui2/dialogs/epub.ui
+++ b/src/calibre/gui2/dialogs/epub.ui
@@ -93,7 +93,7 @@
-
- 1
+ 0
@@ -105,36 +105,6 @@
Book Cover
-
-
-
-
-
-
-
-
-
-
- :/images/book.svg
-
-
- true
-
-
- Qt::AlignCenter
-
-
-
-
-
- -
-
-
- Use cover from &source file
-
-
- true
-
-
-
-
@@ -186,6 +156,36 @@
+ -
+
+
+ Use cover from &source file
+
+
+ true
+
+
+
+ -
+
+
-
+
+
+
+
+
+ :/images/book.svg
+
+
+ true
+
+
+ Qt::AlignCenter
+
+
+
+
+
opt_prefer_metadata_cover
@@ -777,10 +777,10 @@ p, li { white-space: pre-wrap; }
-
- -
+
-
- -
+
-
&Title for generated TOC
@@ -790,6 +790,19 @@ p, li { white-space: pre-wrap; }
+ -
+
+
+ -
+
+
+ Level &3 TOC
+
+
+ opt_level3_toc
+
+
+