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