Skip to content
Permalink
Browse files
Edit Book: A new tool to sort the rules in a CSS stylesheet. To use i…
…t add it to the toolbar for CSS editors
  • Loading branch information
kovidgoyal committed Sep 7, 2016
1 parent d23532e commit d28114bde1a4aaab94484ef6abfe8ba3b03acf03
Binary file not shown.
@@ -16,6 +16,7 @@
from calibre.ebooks.oeb.base import OEB_STYLES, OEB_DOCS
from calibre.ebooks.oeb.normalize_css import normalize_filter_css, normalizers
from calibre.ebooks.oeb.polish.pretty import pretty_script_or_style
from calibre.utils.icu import numeric_sort_key
from css_selectors import Select, SelectorError


@@ -324,3 +325,37 @@ def remove_property_value(prop, predicate):
x = x.replace(v.cssText, '').strip()
prop.propertyValue.cssText = x
return bool(removed_vals)


RULE_PRIORITIES = {t:i for i, t in enumerate((CSSRule.COMMENT, CSSRule.CHARSET_RULE, CSSRule.IMPORT_RULE, CSSRule.NAMESPACE_RULE))}

def sort_sheet(container, sheet_or_text):
''' Sort the rules in a stylesheet. Note that in the general case this can
change the effective styles, but for most common sheets, it should be safe.
'''
sheet = container.parse_css(sheet_or_text) if isinstance(sheet_or_text, unicode) else sheet_or_text

def text_sort_key(x):
return numeric_sort_key(unicode(x or ''))

def selector_sort_key(x):
return (x.specificity, text_sort_key(x.selectorText))

def rule_sort_key(rule):
primary = RULE_PRIORITIES.get(rule.type, len(RULE_PRIORITIES))
secondary = text_sort_key(getattr(rule, 'atkeyword', '') or '')
tertiary = None
if rule.type == CSSRule.STYLE_RULE:
primary += 1
selectors = sorted(rule.selectorList, key=selector_sort_key)
tertiary = selector_sort_key(selectors[0])
rule.selectorText = ', '.join(s.selectorText for s in selectors)
elif rule.type == CSSRule.FONT_FACE_RULE:
try:
tertiary = text_sort_key(rule.style.getPropertyValue('font-family'))
except Exception:
pass

return primary, secondary, tertiary
sheet.cssRules.sort(key=rule_sort_key)
return sheet
@@ -58,7 +58,7 @@
]
d['global_plugins_toolbar'] = []
d['editor_common_toolbar'] = [('editor-' + x) if x else None for x in ('undo', 'redo', None, 'cut', 'copy', 'paste', 'smart-comment')]
d['editor_css_toolbar'] = ['pretty-current', 'insert-image']
d['editor_css_toolbar'] = ['pretty-current', 'sort-css', 'insert-image']
d['editor_xml_toolbar'] = ['pretty-current', 'insert-tag']
d['editor_html_toolbar'] = ['fix-html-current', 'pretty-current', 'insert-image', 'insert-hyperlink', 'insert-tag', 'change-paragraph']
d['editor_format_toolbar'] = [('format-text-' + x) if x else x for x in (
@@ -17,7 +17,7 @@
QColorDialog, QTimer, pyqtSignal)

from calibre import prepare_string_for_xml
from calibre.gui2.tweak_book import tprefs, TOP
from calibre.gui2.tweak_book import tprefs, TOP, current_container
from calibre.gui2.tweak_book.completion.popup import CompletionPopup
from calibre.gui2.tweak_book.editor import (
SYNTAX_PROPERTY, SPELL_PROPERTY, SPELL_LOCALE_PROPERTY, store_locale, LINK_PROPERTY)
@@ -332,6 +332,14 @@ def smart_comment(self):
from calibre.gui2.tweak_book.editor.comments import smart_comment
smart_comment(self, self.syntax)

def sort_css(self):
from calibre.gui2.dialogs.confirm_delete import confirm
if confirm(_('Sorting CSS rules can in rare cases change the effective styles applied to the book.'
' Are you sure you want to proceed?'), 'edit-book-confirm-sort-css', parent=self, config_set=tprefs):
from calibre.ebooks.oeb.polish.css import sort_sheet
text = sort_sheet(current_container(), self.toPlainText()).cssText
self.setPlainText(text)

def find(self, pat, wrap=False, marked=False, complete=False, save_match=None):
if marked:
return self.find_in_marked(pat, wrap=wrap, save_match=save_match)
@@ -80,6 +80,8 @@ def reg(*args, **kw):
ac = reg('format-justify-fill.png', _('&Justify'), ('format_text', 'justify_justify'), 'format-text-justify-fill', (), _('Justify'))
ac.setToolTip(_('<h3>Justify</h3>Align the paragraph to both the left and right margins'))

ac = reg('sort.png', _('&Sort style rules'), ('sort_css',), 'editor-sort-css', (),
_('Sort the style rules'), syntaxes=('css',))
ac = reg('view-image.png', _('&Insert image'), ('insert_resource', 'image'), 'insert-image', (),
_('Insert an image into the text'), syntaxes=('html', 'css'))
ac.setToolTip(_('<h3>Insert image</h3>Insert an image into the text'))

0 comments on commit d28114b

Please sign in to comment.