diff --git a/manual/template_lang.rst b/manual/template_lang.rst index 2f828133e0..5a3748e2c5 100644 --- a/manual/template_lang.rst +++ b/manual/template_lang.rst @@ -150,6 +150,7 @@ The functions available are listed below. Note that the definitive documentation {tags:sublist(-1,0,\,)} returns "C" {tags:sublist(0,-1,\,)} returns "A, B" + * ``swap_around_articles(separator)`` -- returns the val with articles moved to the end. The value can be a list, in which case each member of the list is processed. If the value is a list then you must provide the list value separator. If no separator is provided then the value is treated as being a single value, not a list. * ``swap_around_comma()`` -- given a field with a value of the form ``B, A``, return ``A B``. This is most useful for converting names in LN, FN format to FN LN. If there is no comma, the function returns val unchanged. * ``switch(pattern, value, pattern, value, ..., else_value)`` -- for each ``pattern, value`` pair, checks if the field matches the regular expression ``pattern`` and if so, returns that ``value``. If no ``pattern`` matches, then ``else_value`` is returned. You can have as many ``pattern, value`` pairs as you want. * ``test(text if not empty, text if empty)`` -- return `text if not empty` if the field is not empty, otherwise return `text if empty`. diff --git a/src/calibre/utils/formatter_functions.py b/src/calibre/utils/formatter_functions.py index 3141534838..16b4b65d16 100644 --- a/src/calibre/utils/formatter_functions.py +++ b/src/calibre/utils/formatter_functions.py @@ -1659,6 +1659,32 @@ class BuiltinRatingToStars(BuiltinFormatterFunction): return rating_to_stars(v, use_half_stars == '1') +class BuiltinSwapAroundArticles(BuiltinFormatterFunction): + name = 'swap_around_articles' + arg_count = 2 + category = 'String manipulation' + __doc__ = doc = _('swap_around_articles(val, separator) ' + '-- returns the val with articles moved to the end. ' + 'The value can be a list, in which case each member ' + 'of the list is processed. If the value is a list then ' + 'you must provide the list value separator. If no ' + 'separator is provided then the value is treated as ' + 'being a single value, not a list.') + + def evaluate(self, formatter, kwargs, mi, locals, val, separator): + if not val: + return '' + if not separator: + return title_sort(val).replace(',', ';') + result = [] + try: + for v in [x.strip() for x in val.split(separator)]: + result.append(title_sort(v).replace(',', ';')) + except: + traceback.print_exc() + return separator.join(sorted(result, key=sort_key)) + + _formatter_builtins = [ BuiltinAdd(), BuiltinAnd(), BuiltinApproximateFormats(), BuiltinAssign(), BuiltinAuthorLinks(), BuiltinAuthorSorts(), BuiltinBooksize(), @@ -1678,8 +1704,9 @@ _formatter_builtins = [ BuiltinRe(), BuiltinReGroup(), BuiltinSelect(), BuiltinSeriesSort(), BuiltinShorten(), BuiltinStrcat(), BuiltinStrcatMax(), BuiltinStrcmp(), BuiltinStrInList(), BuiltinStrlen(), BuiltinSubitems(), - BuiltinSublist(),BuiltinSubstr(), BuiltinSubtract(), BuiltinSwapAroundComma(), - BuiltinSwitch(), BuiltinTemplate(), BuiltinTest(), BuiltinTitlecase(), + BuiltinSublist(),BuiltinSubstr(), BuiltinSubtract(), BuiltinSwapAroundArticles(), + BuiltinSwapAroundComma(), BuiltinSwitch(), + BuiltinTemplate(), BuiltinTest(), BuiltinTitlecase(), BuiltinToday(), BuiltinTransliterate(), BuiltinUppercase(), BuiltinUserCategories(), BuiltinVirtualLibraries() ]