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)
|
namespace, barename, XPath)
|
||||||
from calibre.ebooks.oeb.stylizer import Stylizer
|
from calibre.ebooks.oeb.stylizer import Stylizer
|
||||||
from calibre.utils.filenames import ascii_filename, ascii_text
|
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]+')
|
COLLAPSE = re.compile(r'[ \t\r\n\v]+')
|
||||||
STRIPNUM = re.compile(r'[-0-9]+$')
|
STRIPNUM = re.compile(r'[-0-9]+$')
|
||||||
@ -459,7 +460,7 @@ class CSSFlattener(object):
|
|||||||
keep_classes = set()
|
keep_classes = set()
|
||||||
|
|
||||||
if cssdict:
|
if cssdict:
|
||||||
items = sorted(cssdict.items())
|
items = sorted(cssdict.iteritems())
|
||||||
css = u';\n'.join(u'%s: %s' % (key, val) for key, val in items)
|
css = u';\n'.join(u'%s: %s' % (key, val) for key, val in items)
|
||||||
classes = node.get('class', '').strip() or 'calibre'
|
classes = node.get('class', '').strip() or 'calibre'
|
||||||
klass = ascii_text(STRIPNUM.sub('', classes.split()[0].replace('_', '')))
|
klass = ascii_text(STRIPNUM.sub('', classes.split()[0].replace('_', '')))
|
||||||
@ -577,7 +578,7 @@ class CSSFlattener(object):
|
|||||||
body = html.find(XHTML('body'))
|
body = html.find(XHTML('body'))
|
||||||
fsize = self.context.dest.fbase
|
fsize = self.context.dest.fbase
|
||||||
self.flatten_node(body, stylizer, names, styles, pseudo_styles, fsize, item.id)
|
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
|
# :hover must come after link and :active must come after :hover
|
||||||
psels = sorted(pseudo_styles.iterkeys(), key=lambda x :
|
psels = sorted(pseudo_styles.iterkeys(), key=lambda x :
|
||||||
{'hover':1, 'active':2}.get(x, 0))
|
{'hover':1, 'active':2}.get(x, 0))
|
||||||
|
@ -12,7 +12,7 @@ from functools import partial
|
|||||||
from calibre.constants import plugins
|
from calibre.constants import plugins
|
||||||
from calibre.utils.config_base import tweaks
|
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
|
_locale = None
|
||||||
|
|
||||||
_none = u''
|
_none = u''
|
||||||
@ -90,6 +90,29 @@ def icu_sort_key(collator, obj):
|
|||||||
obj = obj.replace(b'\0', b'')
|
obj = obj.replace(b'\0', b'')
|
||||||
return _sort_collator.sort_key(obj)
|
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):
|
def icu_change_case(upper, locale, obj):
|
||||||
func = _icu.upper if upper else _icu.lower
|
func = _icu.upper if upper else _icu.lower
|
||||||
try:
|
try:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user