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)

This commit is contained in:
Kovid Goyal 2017-11-30 12:05:57 +05:30
parent c247cd6b35
commit 10036f66ff
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
4 changed files with 36 additions and 9 deletions

View File

@ -13,9 +13,9 @@ from cssutils.css import CSSRule, CSSStyleDeclaration
from css_selectors import parse, SelectorSyntaxError from css_selectors import parse, SelectorSyntaxError
from calibre import force_unicode 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.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 calibre.utils.icu import numeric_sort_key
from css_selectors import Select, SelectorError from css_selectors import Select, SelectorError
@ -369,3 +369,19 @@ def sort_sheet(container, sheet_or_text):
return primary, secondary, tertiary return primary, secondary, tertiary
sheet.cssRules.sort(key=rule_sort_key) sheet.cssRules.sort(key=rule_sort_key)
return sheet 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')

View File

@ -76,6 +76,7 @@ d['toolbar_icon_size'] = 24
d['insert_full_screen_image'] = False d['insert_full_screen_image'] = False
d['preserve_aspect_ratio_when_inserting_image'] = False d['preserve_aspect_ratio_when_inserting_image'] = False
d['file_list_shows_full_pathname'] = False d['file_list_shows_full_pathname'] = False
d['auto_link_stylesheets'] = True
del d del d
ucase_map = {l:string.ascii_uppercase[i] for i, l in enumerate(string.ascii_lowercase)} ucase_map = {l:string.ascii_uppercase[i] for i, l in enumerate(string.ascii_lowercase)}

View File

@ -23,6 +23,7 @@ from calibre.ebooks.oeb.polish.container import OEB_FONTS, guess_type
from calibre.ebooks.oeb.polish.cover import ( from calibre.ebooks.oeb.polish.cover import (
get_cover_page_name, get_raster_cover_name, is_raster_image 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.ebooks.oeb.polish.replace import get_recommended_folders
from calibre.gui2 import ( from calibre.gui2 import (
choose_dir, choose_files, choose_save_file, elided_text, error_dialog, choose_dir, choose_files, choose_save_file, elided_text, error_dialog,
@ -827,6 +828,9 @@ class NewFileDialog(QDialog): # {{{
self.name = n = QLineEdit(self) self.name = n = QLineEdit(self)
n.textChanged.connect(self.update_ok) n.textChanged.connect(self.update_ok)
l.addWidget(n) 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('') self.err_label = la = QLabel('')
la.setWordWrap(True) la.setWordWrap(True)
l.addWidget(la) l.addWidget(la)
@ -856,6 +860,7 @@ class NewFileDialog(QDialog): # {{{
self.do_import_file(path[0]) self.do_import_file(path[0])
def do_import_file(self, path, hide_button=False): def do_import_file(self, path, hide_button=False):
self.link_css.setVisible(False)
with open(path, 'rb') as f: with open(path, 'rb') as f:
self.file_data = f.read() self.file_data = f.read()
name = os.path.basename(path) name = os.path.basename(path)
@ -878,6 +883,7 @@ class NewFileDialog(QDialog): # {{{
if not self.name_is_ok: if not self.name_is_ok:
return error_dialog(self, _('No name specified'), _( 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) '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 = unicode(self.name.text())
name, ext = name.rpartition('.')[0::2] name, ext = name.rpartition('.')[0::2]
name = (name + '.' + ext.lower()).replace('\\', '/') name = (name + '.' + ext.lower()).replace('\\', '/')
@ -885,6 +891,10 @@ class NewFileDialog(QDialog): # {{{
if not self.file_data: if not self.file_data:
if mt in OEB_DOCS: if mt in OEB_DOCS:
self.file_data = template_for('html').encode('utf-8') 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 self.using_template = True
elif mt in OEB_STYLES: elif mt in OEB_STYLES:
self.file_data = template_for('css').encode('utf-8') self.file_data = template_for('css').encode('utf-8')

View File

@ -14,12 +14,13 @@ DEFAULT_TEMPLATES = {
'''\ '''\
<?xml version='1.0' encoding='utf-8'?> <?xml version='1.0' encoding='utf-8'?>
<html xmlns="http://www.w3.org/1999/xhtml"> <html xmlns="http://www.w3.org/1999/xhtml">
<head> <head>
<title>{TITLE}</title> <title>{TITLE}</title>
</head> </head>
<body>
%CURSOR% <body>
</body> %CURSOR%
</body>
</html> </html>
''', ''',
@ -46,4 +47,3 @@ def template_for(syntax):
} }
return raw_template_for(syntax).format( return raw_template_for(syntax).format(
**{k:prepare_string_for_xml(v, True) for k, v in data.iteritems()}) **{k:prepare_string_for_xml(v, True) for k, v in data.iteritems()})