diff --git a/manual/conversion.rst b/manual/conversion.rst
index 817821a9b1..bf451d0980 100644
--- a/manual/conversion.rst
+++ b/manual/conversion.rst
@@ -434,6 +434,18 @@ a number of older formats either do not support a metadata based Table of Conten
documents do not have one. In these cases, the options in this section can help you automatically
generate a Table of Contents in the converted ebook, based on the actual content in the input document.
+.. note:: Using these options can be a little challenging to get exactly right.
+ If you prefer creating/editing the Table of Contents by hand, convert to
+ the EPUB or AZW3 formats and select the checkbox at the bottom of the
+ screen that says
+ :guilabel:`Manually fine-tune the Table of Contents after conversion`.
+ This will launch the ToC Editor tool after the conversion. It allows you to
+ create entries in the Table of Contents by simply clicking the place in the
+ book where you want the entry to point. You can also use the ToC Editor by
+ itself, without doing a conversion. Go to :guilabel:`Preferences->Toolbars`
+ and add the ToC Editor to the main toolbar. Then just select the book you
+ want to edit and click the ToC Editor button.
+
The first option is :guilabel:`Force use of auto-generated Table of Contents`. By checking this option
you can have |app| override any Table of Contents found in the metadata of the input document with the
auto generated one.
@@ -456,7 +468,7 @@ For example, to remove all entries titles "Next" or "Previous" use::
Next|Previous
-Finally, the :guilabel:`Level 1,2,3 TOC` options allow you to create a sophisticated multi-level Table of Contents.
+The :guilabel:`Level 1,2,3 TOC` options allow you to create a sophisticated multi-level Table of Contents.
They are XPath expressions that match tags in the intermediate XHTML produced by the conversion pipeline. See the
:ref:`conversion-introduction` for how to get access to this XHTML. Also read the :ref:`xpath-tutorial`, to learn
how to construct XPath expressions. Next to each option is a button that launches a wizard to help with the creation
diff --git a/src/calibre/gui2/actions/convert.py b/src/calibre/gui2/actions/convert.py
index 68415db748..c5e1580c6d 100644
--- a/src/calibre/gui2/actions/convert.py
+++ b/src/calibre/gui2/actions/convert.py
@@ -167,8 +167,8 @@ class ConvertAction(InterfaceAction):
def queue_convert_jobs(self, jobs, changed, bad, rows, previous,
converted_func, extra_job_args=[], rows_are_ids=False):
for func, args, desc, fmt, id, temp_files in jobs:
- func, _, same_fmt = func.partition(':')
- same_fmt = same_fmt == 'same_fmt'
+ func, _, parts = func.partition(':')
+ parts = {x for x in parts.split(';')}
input_file = args[0]
input_fmt = os.path.splitext(input_file)[1]
core_usage = 1
@@ -182,7 +182,8 @@ class ConvertAction(InterfaceAction):
job = self.gui.job_manager.run_job(Dispatcher(converted_func),
func, args=args, description=desc,
core_usage=core_usage)
- job.conversion_of_same_fmt = same_fmt
+ job.conversion_of_same_fmt = 'same_fmt' in parts
+ job.manually_fine_tune_toc = 'manually_fine_tune_toc' in parts
args = [temp_files, fmt, id]+extra_job_args
self.conversion_jobs[job] = tuple(args)
@@ -223,6 +224,7 @@ class ConvertAction(InterfaceAction):
self.gui.job_exception(job)
return
same_fmt = getattr(job, 'conversion_of_same_fmt', False)
+ manually_fine_tune_toc = getattr(job, 'manually_fine_tune_toc', False)
fmtf = temp_files[-1].name
if os.stat(fmtf).st_size < 1:
raise Exception(_('Empty output file, '
@@ -248,4 +250,7 @@ class ConvertAction(InterfaceAction):
current = self.gui.library_view.currentIndex()
if current.isValid():
self.gui.library_view.model().current_changed(current, QModelIndex())
+ if manually_fine_tune_toc:
+ self.gui.iactions['Edit ToC'].do_one(book_id, fmt.upper())
+
diff --git a/src/calibre/gui2/convert/bulk.py b/src/calibre/gui2/convert/bulk.py
index 213f23ced2..b1c3de122b 100644
--- a/src/calibre/gui2/convert/bulk.py
+++ b/src/calibre/gui2/convert/bulk.py
@@ -88,6 +88,7 @@ class BulkConfig(Config):
ps = widget_factory(PageSetupWidget)
sd = widget_factory(StructureDetectionWidget)
toc = widget_factory(TOCWidget)
+ toc.manually_fine_tune_toc.hide()
output_widget = self.plumber.output_plugin.gui_configuration_widget(
self.stack, self.plumber.get_option_by_name,
diff --git a/src/calibre/gui2/convert/single.py b/src/calibre/gui2/convert/single.py
index cff7ee8c3d..469091162b 100644
--- a/src/calibre/gui2/convert/single.py
+++ b/src/calibre/gui2/convert/single.py
@@ -165,6 +165,12 @@ class Config(ResizableDialog, Ui_Dialog):
def output_format(self):
return unicode(self.output_formats.currentText()).lower()
+ @property
+ def manually_fine_tune_toc(self):
+ for i in xrange(self.stack.count()):
+ w = self.stack.widget(i)
+ if hasattr(w, 'manually_fine_tune_toc'):
+ return w.manually_fine_tune_toc.isChecked()
def setup_pipeline(self, *args):
oidx = self.groups.currentIndex().row()
@@ -191,6 +197,8 @@ class Config(ResizableDialog, Ui_Dialog):
ps = widget_factory(PageSetupWidget)
sd = widget_factory(StructureDetectionWidget)
toc = widget_factory(TOCWidget)
+ from calibre.gui2.actions.toc_edit import SUPPORTED
+ toc.manually_fine_tune_toc.setVisible(output_format.upper() in SUPPORTED)
debug = widget_factory(DebugWidget)
output_widget = self.plumber.output_plugin.gui_configuration_widget(
diff --git a/src/calibre/gui2/convert/toc.ui b/src/calibre/gui2/convert/toc.ui
index da15551f80..6140816804 100644
--- a/src/calibre/gui2/convert/toc.ui
+++ b/src/calibre/gui2/convert/toc.ui
@@ -6,22 +6,32 @@
0
0
- 436
- 382
+ 596
+ 493
Form
+ -
+
+
-
+
+
+ &Force use of auto-generated Table of Contents
+
+
+
+ -
Do not add &detected chapters to the Table of Contents
- -
+
-
Number of &links to add to Table of Contents
@@ -31,34 +41,7 @@
- -
-
-
- 10000
-
-
-
- -
-
-
- Chapter &threshold
-
-
- opt_toc_threshold
-
-
-
- -
-
-
- -
-
-
- &Force use of auto-generated Table of Contents
-
-
-
- -
+
-
TOC &Filter:
@@ -68,19 +51,27 @@
- -
-
-
- -
-
-
- -
-
-
- -
+
-
- -
+
-
+
+
+ 10000
+
+
+
+ -
+
+
+ Chapter &threshold
+
+
+ opt_toc_threshold
+
+
+
+ -
Qt::Vertical
@@ -93,13 +84,47 @@
- -
+
-
Allow &duplicate links when creating the Table of Contents
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ <a href="http://manual.calibre-ebook.com/conversion.html#table-of-contents">Help with using these options to generate a Table of Contents</a>
+
+
+ true
+
+
+ true
+
+
+
+ -
+
+
+ This option will cause calibre to popup the Table of Contents Editor tool,
+ which will allow you to manually edit the Table of Contents, to fix any errors
+ caused by automatic generation.
+
+
+ &Manually fine-tune the ToC after conversion is completed
+
+
+
diff --git a/src/calibre/gui2/preferences/conversion.py b/src/calibre/gui2/preferences/conversion.py
index a15ee0a750..6c9e1f8f5b 100644
--- a/src/calibre/gui2/preferences/conversion.py
+++ b/src/calibre/gui2/preferences/conversion.py
@@ -61,6 +61,8 @@ class Base(ConfigWidgetBase, Ui_Form):
for w in widgets:
w.changed_signal.connect(self.changed_signal)
self.stack.addWidget(w)
+ if isinstance(w, TOCWidget):
+ w.manually_fine_tune_toc.hide()
self.list.currentChanged = self.category_current_changed
self.list.setCurrentIndex(self.model.index(0))
diff --git a/src/calibre/gui2/tools.py b/src/calibre/gui2/tools.py
index 98a59ccdd5..eda60a4fec 100644
--- a/src/calibre/gui2/tools.py
+++ b/src/calibre/gui2/tools.py
@@ -82,8 +82,13 @@ def convert_single_ebook(parent, db, book_ids, auto_conversion=False, # {{{
args = [in_file.name, out_file.name, recs]
temp_files.append(out_file)
func = 'gui_convert_override'
+ parts = []
+ if not auto_conversion and d.manually_fine_tune_toc:
+ parts.append('manually_fine_tune_toc')
if same_fmt:
- func += ':same_fmt'
+ parts.append('same_fmt')
+ if parts:
+ func += ':%s'%(';'.join(parts))
jobs.append((func, args, desc, d.output_format.upper(), book_id, temp_files))
changed = True