diff --git a/src/calibre/utils/icu.c b/src/calibre/utils/icu.c index f1e8fce299..ccb1cfb5b9 100644 --- a/src/calibre/utils/icu.c +++ b/src/calibre/utils/icu.c @@ -59,7 +59,6 @@ icu_Collator_new(PyTypeObject *type, PyObject *args, PyObject *kwds) PyErr_SetString(PyExc_Exception, "Failed to create collator."); return NULL; } - ucol_setAttribute(collator, UCOL_NUMERIC_COLLATION, UCOL_ON, &status); self = (icu_Collator *)type->tp_alloc(type, 0); if (self != NULL) { diff --git a/src/calibre/utils/icu.py b/src/calibre/utils/icu.py index aa08f293fa..aaf8c415e1 100644 --- a/src/calibre/utils/icu.py +++ b/src/calibre/utils/icu.py @@ -12,7 +12,7 @@ from functools import partial from calibre.constants import plugins from calibre.utils.config_base import tweaks -_icu = _collator = _primary_collator = _secondary_collator = None +_icu = _collator = _primary_collator = _sort_collator = None _locale = None _none = u'' @@ -41,28 +41,34 @@ def load_icu(): return _icu def load_collator(): + 'The default collator for most locales takes both case and accented letters into account' global _collator if _collator is None: icu = load_icu() if icu is not None: _collator = icu.Collator(get_locale()) - if not tweaks['numeric_collation']: - _collator.numeric = False return _collator def primary_collator(): + 'Ignores case differences and accented characters' global _primary_collator if _primary_collator is None: _primary_collator = _collator.clone() _primary_collator.strength = _icu.UCOL_PRIMARY return _primary_collator -def secondary_collator(): - global _secondary_collator - if _secondary_collator is None: - _secondary_collator = _collator.clone() - _secondary_collator.strength = _icu.UCOL_SECONDARY - return _secondary_collator +def sort_collator(): + 'Ignores case differences and recognizes numbers in strings' + global _sort_collator + if _sort_collator is None: + _sort_collator = _collator.clone() + _sort_collator.strength = _icu.UCOL_SECONDARY + if tweaks['numeric_collation']: + try: + _sort_collator.numeric = True + except AttributeError: + pass + return _sort_collator def py_sort_key(obj): if not obj: @@ -74,15 +80,15 @@ def icu_sort_key(collator, obj): return _none2 try: try: - return _secondary_collator.sort_key(obj) + return _sort_collator.sort_key(obj) except AttributeError: - return secondary_collator().sort_key(obj) + return sort_collator().sort_key(obj) except TypeError: if isinstance(obj, unicode): obj = obj.replace(u'\0', u'') else: obj = obj.replace(b'\0', b'') - return _secondary_collator.sort_key(obj) + return _sort_collator.sort_key(obj) def icu_change_case(upper, locale, obj): func = _icu.upper if upper else _icu.lower @@ -235,9 +241,9 @@ def collation_order(a): if _icu_not_ok: return (ord(a[0]), 1) if a else (0, 0) try: - return icu_collation_order(_secondary_collator, a) + return icu_collation_order(_sort_collator, a) except AttributeError: - return icu_collation_order(secondary_collator(), a) + return icu_collation_order(sort_collator(), a) ################################################################################