diff --git a/src/calibre/ebooks/conversion/cli.py b/src/calibre/ebooks/conversion/cli.py index ae0af532ab..e12686a36c 100644 --- a/src/calibre/ebooks/conversion/cli.py +++ b/src/calibre/ebooks/conversion/cli.py @@ -128,7 +128,7 @@ def add_pipeline_options(parser, plumber): [ 'dont_split_on_page_breaks', 'chapter', 'chapter_mark', 'prefer_metadata_cover', 'remove_first_image', - 'insert_comments', + 'insert_comments', 'page_breaks_before', ] ), diff --git a/src/calibre/ebooks/conversion/plumber.py b/src/calibre/ebooks/conversion/plumber.py index f55d677d08..da9c9f11e2 100644 --- a/src/calibre/ebooks/conversion/plumber.py +++ b/src/calibre/ebooks/conversion/plumber.py @@ -227,6 +227,14 @@ OptionRecommendation(name='extra_css', 'rules.') ), +OptionRecommendation(name='page_breaks_before', + recommended_value="//*[name()='h1' or name()='h2']", + level=OptionRecommendation.LOW, + help=_('An XPath expression. Page breaks are inserted ' + 'before the specified elements.') + ), + + OptionRecommendation(name='margin_top', recommended_value=5.0, level=OptionRecommendation.LOW, help=_('Set the top margin in pts. Default is %default')), diff --git a/src/calibre/ebooks/conversion/preprocess.py b/src/calibre/ebooks/conversion/preprocess.py index 43f1f619d0..230d759755 100644 --- a/src/calibre/ebooks/conversion/preprocess.py +++ b/src/calibre/ebooks/conversion/preprocess.py @@ -26,10 +26,17 @@ def sanitize_head(match): def chap_head(match): chap = match.group('chap') title = match.group('title') +<<<<<<< TREE if not title: return '
'), - # Clean up spaces (re.compile(u'(?<=[\.,:;\?!”"\'])[\s^ ]*(?=<)'), lambda match: ' '), # Add space before and after italics @@ -154,6 +160,7 @@ class HTMLPreProcessor(object): def __call__(self, html, remove_special_chars=None): if remove_special_chars is not None: html = remove_special_chars.sub('', html) + html = html.replace('\0', '') if self.is_baen(html): rules = [] elif self.is_book_designer(html): diff --git a/src/calibre/ebooks/oeb/base.py b/src/calibre/ebooks/oeb/base.py index 33bb44840b..9d8598c766 100644 --- a/src/calibre/ebooks/oeb/base.py +++ b/src/calibre/ebooks/oeb/base.py @@ -941,7 +941,10 @@ class Manifest(object): href = urlunparse(purl) path, frag = urldefrag(href) if not path: - return '#'.join((self.href, frag)) + if frag: + return '#'.join((self.href, frag)) + else: + return self.href if '/' not in self.href: return href dirname = os.path.dirname(self.href) diff --git a/src/calibre/ebooks/oeb/transforms/structure.py b/src/calibre/ebooks/oeb/transforms/structure.py index 197a265139..8ec3c7737a 100644 --- a/src/calibre/ebooks/oeb/transforms/structure.py +++ b/src/calibre/ebooks/oeb/transforms/structure.py @@ -45,6 +45,14 @@ class DetectStructure(object): if not node.title or regexp.search(node.title) is not None: self.oeb.toc.remove(node) + if opts.page_breaks_before is not None: + pb_xpath = XPath(opts.page_breaks_before) + for item in oeb.spine: + for elem in pb_xpath(item.data): + style = elem.get('style', '') + if style: + style += '; ' + elem.set('style', style+'page-break-before:always') def detect_chapters(self): self.detected_chapters = [] @@ -102,6 +110,7 @@ class DetectStructure(object): play_order=self.oeb.toc.next_play_order()) + def elem_to_link(self, item, elem, counter): text = u' '.join([t.strip() for t in elem.xpath('descendant::text()')]) text = text[:100].strip() diff --git a/src/calibre/gui2/dialogs/metadata_single.py b/src/calibre/gui2/dialogs/metadata_single.py index e3e2080cc0..4d5471caf0 100644 --- a/src/calibre/gui2/dialogs/metadata_single.py +++ b/src/calibre/gui2/dialogs/metadata_single.py @@ -159,9 +159,12 @@ class MetadataSingleDialog(ResizableDialog, Ui_MetadataSingleDialog): row = self.formats.currentRow() fmt = self.formats.item(row) if fmt is None: - error_dialog(self, _('No format selected'), + if self.formats.count() == 1: + fmt = self.formats.item(0) + if fmt is None: + error_dialog(self, _('No format selected'), _('No format selected')).exec_() - return + return ext = fmt.ext.lower() if fmt.path is None: stream = self.db.format(self.row, ext, as_file=True)