mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Conversion: Sort the CSS rules in the output stylesheet using a "natural" sort algorithm, so that calibre2 sorts before calibre10. Fixes #1265175 [[Feature request] Alphanumeric sort of classes in stylesheet](https://bugs.launchpad.net/calibre/+bug/1265175)
This commit is contained in:
parent
f092a643ae
commit
3bfd3bc07f
@ -19,6 +19,7 @@ from calibre.ebooks.oeb.base import (XHTML, XHTML_NS, CSS_MIME, OEB_STYLES,
|
||||
namespace, barename, XPath)
|
||||
from calibre.ebooks.oeb.stylizer import Stylizer
|
||||
from calibre.utils.filenames import ascii_filename, ascii_text
|
||||
from calibre.utils.icu import numeric_sort_key
|
||||
|
||||
COLLAPSE = re.compile(r'[ \t\r\n\v]+')
|
||||
STRIPNUM = re.compile(r'[-0-9]+$')
|
||||
@ -459,7 +460,7 @@ class CSSFlattener(object):
|
||||
keep_classes = set()
|
||||
|
||||
if cssdict:
|
||||
items = sorted(cssdict.items())
|
||||
items = sorted(cssdict.iteritems())
|
||||
css = u';\n'.join(u'%s: %s' % (key, val) for key, val in items)
|
||||
classes = node.get('class', '').strip() or 'calibre'
|
||||
klass = ascii_text(STRIPNUM.sub('', classes.split()[0].replace('_', '')))
|
||||
@ -577,7 +578,7 @@ class CSSFlattener(object):
|
||||
body = html.find(XHTML('body'))
|
||||
fsize = self.context.dest.fbase
|
||||
self.flatten_node(body, stylizer, names, styles, pseudo_styles, fsize, item.id)
|
||||
items = sorted([(key, val) for (val, key) in styles.items()])
|
||||
items = sorted(((key, val) for (val, key) in styles.iteritems()), key=lambda x:numeric_sort_key(x[0]))
|
||||
# :hover must come after link and :active must come after :hover
|
||||
psels = sorted(pseudo_styles.iterkeys(), key=lambda x :
|
||||
{'hover':1, 'active':2}.get(x, 0))
|
||||
|
@ -12,7 +12,7 @@ from functools import partial
|
||||
from calibre.constants import plugins
|
||||
from calibre.utils.config_base import tweaks
|
||||
|
||||
_icu = _collator = _primary_collator = _sort_collator = None
|
||||
_icu = _collator = _primary_collator = _sort_collator = _numeric_collator = None
|
||||
_locale = None
|
||||
|
||||
_none = u''
|
||||
@ -90,6 +90,29 @@ def icu_sort_key(collator, obj):
|
||||
obj = obj.replace(b'\0', b'')
|
||||
return _sort_collator.sort_key(obj)
|
||||
|
||||
def numeric_collator():
|
||||
global _numeric_collator
|
||||
_numeric_collator = _collator.clone()
|
||||
_numeric_collator.strength = _icu.UCOL_SECONDARY
|
||||
_numeric_collator.numeric = True
|
||||
return _numeric_collator
|
||||
|
||||
def numeric_sort_key(obj):
|
||||
'Uses natural sorting for numbers inside strings so something2 will sort before something10'
|
||||
if not obj:
|
||||
return _none2
|
||||
try:
|
||||
try:
|
||||
return _numeric_collator.sort_key(obj)
|
||||
except AttributeError:
|
||||
return numeric_collator().sort_key(obj)
|
||||
except TypeError:
|
||||
if isinstance(obj, unicode):
|
||||
obj = obj.replace(u'\0', u'')
|
||||
else:
|
||||
obj = obj.replace(b'\0', b'')
|
||||
return _numeric_collator.sort_key(obj)
|
||||
|
||||
def icu_change_case(upper, locale, obj):
|
||||
func = _icu.upper if upper else _icu.lower
|
||||
try:
|
||||
|
Loading…
x
Reference in New Issue
Block a user