From 10036f66ff0a9eed196b9cc23c9d86f68d36cfa1 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Thu, 30 Nov 2017 12:05:57 +0530 Subject: [PATCH] Edit book: Auto-generate links to existing stylesheets when adding a new HTML file. Fixes #1733845 [[enhancement] editor, adding or importing a new hmtl page, add css](https://bugs.launchpad.net/calibre/+bug/1733845) --- src/calibre/ebooks/oeb/polish/css.py | 20 ++++++++++++++++++-- src/calibre/gui2/tweak_book/__init__.py | 1 + src/calibre/gui2/tweak_book/file_list.py | 10 ++++++++++ src/calibre/gui2/tweak_book/templates.py | 14 +++++++------- 4 files changed, 36 insertions(+), 9 deletions(-) diff --git a/src/calibre/ebooks/oeb/polish/css.py b/src/calibre/ebooks/oeb/polish/css.py index f4fd0e2681..4b393b939d 100644 --- a/src/calibre/ebooks/oeb/polish/css.py +++ b/src/calibre/ebooks/oeb/polish/css.py @@ -13,9 +13,9 @@ from cssutils.css import CSSRule, CSSStyleDeclaration from css_selectors import parse, SelectorSyntaxError from calibre import force_unicode -from calibre.ebooks.oeb.base import OEB_STYLES, OEB_DOCS +from calibre.ebooks.oeb.base import OEB_STYLES, OEB_DOCS, XHTML from calibre.ebooks.oeb.normalize_css import normalize_filter_css, normalizers -from calibre.ebooks.oeb.polish.pretty import pretty_script_or_style +from calibre.ebooks.oeb.polish.pretty import pretty_script_or_style, pretty_xml_tree, serialize from calibre.utils.icu import numeric_sort_key from css_selectors import Select, SelectorError @@ -369,3 +369,19 @@ def sort_sheet(container, sheet_or_text): return primary, secondary, tertiary sheet.cssRules.sort(key=rule_sort_key) return sheet + + +def add_stylesheet_links(container, name, text): + root = container.parse_xhtml(text, name) + head = root.xpath('//*[local-name() = "head"]') + if not head: + return + head = head[0] + sheets = tuple(container.manifest_items_of_type(lambda mt: mt in OEB_STYLES)) + if not sheets: + return + for sname in sheets: + link = head.makeelement(XHTML('link'), type='text/css', rel='stylesheet', href=container.name_to_href(sname, name)) + head.append(link) + pretty_xml_tree(head) + return serialize(root, 'text/html') diff --git a/src/calibre/gui2/tweak_book/__init__.py b/src/calibre/gui2/tweak_book/__init__.py index 92901c7a2d..d9dbe87476 100644 --- a/src/calibre/gui2/tweak_book/__init__.py +++ b/src/calibre/gui2/tweak_book/__init__.py @@ -76,6 +76,7 @@ d['toolbar_icon_size'] = 24 d['insert_full_screen_image'] = False d['preserve_aspect_ratio_when_inserting_image'] = False d['file_list_shows_full_pathname'] = False +d['auto_link_stylesheets'] = True del d ucase_map = {l:string.ascii_uppercase[i] for i, l in enumerate(string.ascii_lowercase)} diff --git a/src/calibre/gui2/tweak_book/file_list.py b/src/calibre/gui2/tweak_book/file_list.py index 06da2107c8..56ac047696 100644 --- a/src/calibre/gui2/tweak_book/file_list.py +++ b/src/calibre/gui2/tweak_book/file_list.py @@ -23,6 +23,7 @@ from calibre.ebooks.oeb.polish.container import OEB_FONTS, guess_type from calibre.ebooks.oeb.polish.cover import ( get_cover_page_name, get_raster_cover_name, is_raster_image ) +from calibre.ebooks.oeb.polish.css import add_stylesheet_links from calibre.ebooks.oeb.polish.replace import get_recommended_folders from calibre.gui2 import ( choose_dir, choose_files, choose_save_file, elided_text, error_dialog, @@ -827,6 +828,9 @@ class NewFileDialog(QDialog): # {{{ self.name = n = QLineEdit(self) n.textChanged.connect(self.update_ok) l.addWidget(n) + self.link_css = lc = QCheckBox(_('Automatically add style-sheet links into new HTML files')) + lc.setChecked(tprefs['auto_link_stylesheets']) + l.addWidget(lc) self.err_label = la = QLabel('') la.setWordWrap(True) l.addWidget(la) @@ -856,6 +860,7 @@ class NewFileDialog(QDialog): # {{{ self.do_import_file(path[0]) def do_import_file(self, path, hide_button=False): + self.link_css.setVisible(False) with open(path, 'rb') as f: self.file_data = f.read() name = os.path.basename(path) @@ -878,6 +883,7 @@ class NewFileDialog(QDialog): # {{{ if not self.name_is_ok: return error_dialog(self, _('No name specified'), _( 'You must specify a name for the new file, with an extension, for example, chapter1.html'), show=True) + tprefs['auto_link_stylesheets'] = self.link_css.isChecked() name = unicode(self.name.text()) name, ext = name.rpartition('.')[0::2] name = (name + '.' + ext.lower()).replace('\\', '/') @@ -885,6 +891,10 @@ class NewFileDialog(QDialog): # {{{ if not self.file_data: if mt in OEB_DOCS: self.file_data = template_for('html').encode('utf-8') + if tprefs['auto_link_stylesheets']: + data = add_stylesheet_links(current_container(), name, self.file_data) + if data is not None: + self.file_data = data self.using_template = True elif mt in OEB_STYLES: self.file_data = template_for('css').encode('utf-8') diff --git a/src/calibre/gui2/tweak_book/templates.py b/src/calibre/gui2/tweak_book/templates.py index 3764880bf9..5c845ab282 100644 --- a/src/calibre/gui2/tweak_book/templates.py +++ b/src/calibre/gui2/tweak_book/templates.py @@ -14,12 +14,13 @@ DEFAULT_TEMPLATES = { '''\ - - {TITLE} - - - %CURSOR% - + + {TITLE} + + + + %CURSOR% + ''', @@ -46,4 +47,3 @@ def template_for(syntax): } return raw_template_for(syntax).format( **{k:prepare_string_for_xml(v, True) for k, v in data.iteritems()}) -