From 5f83f8e5010d10776de33e4dea53d220253b7a3d Mon Sep 17 00:00:00 2001 From: Charles Haley <> Date: Sat, 17 Sep 2011 11:47:32 +0200 Subject: [PATCH] Two new formatter functions: language_codes and language_strings. --- src/calibre/manual/template_lang.rst | 2 + src/calibre/utils/formatter_functions.py | 48 ++++++++++++++++++++++-- 2 files changed, 46 insertions(+), 4 deletions(-) diff --git a/src/calibre/manual/template_lang.rst b/src/calibre/manual/template_lang.rst index e2750e1ebf..e7b8594708 100644 --- a/src/calibre/manual/template_lang.rst +++ b/src/calibre/manual/template_lang.rst @@ -128,6 +128,8 @@ The functions available are listed below. Note that the definitive documentation * ``human_readable()`` -- expects the value to be a number and returns a string representing that number in KB, MB, GB, etc. * ``ifempty(text)`` -- if the field is not empty, return the value of the field. Otherwise return `text`. * ``in_list(separator, pattern, found_val, not_found_val)`` -- interpret the field as a list of items separated by `separator`, comparing the `pattern` against each value in the list. If the pattern matches a value, return `found_val`, otherwise return `not_found_val`. + * ``language_codes(lang_strings)`` -- return the language codes for the strings passed in `lang_strings`. The strings must be in the language of the current locale. `Lang_strings` is a comma-separated list. + * ``language_strings(lang_codes, localize)`` -- return the strings for the language codes passed in `lang_codes`. If `localize` is zero, return the strings in English. If localize is not zero, return the strings in the language of the current locale. `Lang_codes` is a comma-separated list. * ``list_item(index, separator)`` -- interpret the field as a list of items separated by `separator`, returning the `index`th item. The first item is number zero. The last item can be returned using `list_item(-1,separator)`. If the item is not in the list, then the empty value is returned. The separator has the same meaning as in the `count` function. * ``re(pattern, replacement)`` -- return the field after applying the regular expression. All instances of `pattern` are replaced with `replacement`. As in all of |app|, these are python-compatible regular expressions. * ``shorten(left chars, middle text, right chars)`` -- Return a shortened version of the field, consisting of `left chars` characters from the beginning of the field, followed by `middle text`, followed by `right chars` characters from the end of the string. `Left chars` and `right chars` must be integers. For example, assume the title of the book is `Ancient English Laws in the Times of Ivanhoe`, and you want it to fit in a space of at most 15 characters. If you use ``{title:shorten(9,-,5)}``, the result will be `Ancient E-nhoe`. If the field's length is less than ``left chars`` + ``right chars`` + the length of ``middle text``, then the field will be used intact. For example, the title `The Dome` would not be changed. diff --git a/src/calibre/utils/formatter_functions.py b/src/calibre/utils/formatter_functions.py index 144d130564..b5163faa74 100644 --- a/src/calibre/utils/formatter_functions.py +++ b/src/calibre/utils/formatter_functions.py @@ -14,7 +14,7 @@ from calibre import human_readable from calibre.utils.titlecase import titlecase from calibre.utils.icu import capitalize, strcmp, sort_key from calibre.utils.date import parse_date, format_date, now, UNDEFINED_DATE - +from calibre.utils.localization import calibre_langcode_to_name, canonicalize_lang class FormatterFunctions(object): @@ -968,7 +968,7 @@ class BuiltinListSort(BuiltinFormatterFunction): class BuiltinToday(BuiltinFormatterFunction): name = 'today' arg_count = 0 - category = 'Date _functions' + category = 'Date functions' __doc__ = doc = _('today() -- ' 'return a date string for today. This value is designed for use in ' 'format_date or days_between, but can be manipulated like any ' @@ -979,7 +979,7 @@ class BuiltinToday(BuiltinFormatterFunction): class BuiltinDaysBetween(BuiltinFormatterFunction): name = 'days_between' arg_count = 2 - category = 'Date _functions' + category = 'Date functions' __doc__ = doc = _('days_between(date1, date2) -- ' 'return the number of days between date1 and date2. The number is ' 'positive if date1 is greater than date2, otherwise negative. If ' @@ -998,6 +998,45 @@ class BuiltinDaysBetween(BuiltinFormatterFunction): i = d1 - d2 return str('%d.%d'%(i.days, i.seconds/8640)) +class BuiltinLanguageStrings(BuiltinFormatterFunction): + name = 'language_strings' + arg_count = 2 + category = 'Get values from metadata' + __doc__ = doc = _('language_strings(lang_codes, localize) -- ' + 'return the strings for the language codes passed in lang_codes. ' + 'If localize is zero, return the strings in English. If ' + 'localize is not zero, return the strings in the language of ' + 'the current locale. Lang_codes is a comma-separated list.') + def evaluate(self, formatter, kwargs, mi, locals, lang_codes, localize): + retval = [] + for c in [c.strip() for c in lang_codes.split(',') if c.strip()]: + try: + n = calibre_langcode_to_name(c, localize != '0') + if n: + retval.append(n) + except: + pass + return ', '.join(retval) + +class BuiltinLanguageCodes(BuiltinFormatterFunction): + name = 'language_codes' + arg_count = 1 + category = 'Get values from metadata' + __doc__ = doc = _('language_codes(lang_strings) -- ' + 'return the language codes for the strings passed in lang_strings. ' + 'The strings must be in the language of the current locale. ' + 'Lang_strings is a comma-separated list.') + def evaluate(self, formatter, kwargs, mi, locals, lang_strings): + retval = [] + for c in [c.strip() for c in lang_strings.split(',') if c.strip()]: + try: + cv = canonicalize_lang(c) + if cv: + retval.append(canonicalize_lang(cv)) + except: + pass + return ', '.join(retval) + _formatter_builtins = [ BuiltinAdd(), BuiltinAnd(), BuiltinAssign(), BuiltinBooksize(), BuiltinCapitalize(), BuiltinCmp(), BuiltinContains(), BuiltinCount(), @@ -1005,7 +1044,8 @@ _formatter_builtins = [ BuiltinFirstNonEmpty(), BuiltinField(), BuiltinFormatDate(), BuiltinFormatNumber(), BuiltinFormatsModtimes(), BuiltinFormatsSizes(), BuiltinHasCover(), BuiltinHumanReadable(), BuiltinIdentifierInList(), - BuiltinIfempty(), BuiltinInList(), BuiltinListDifference(), + BuiltinIfempty(), BuiltinLanguageCodes(), BuiltinLanguageStrings(), + BuiltinInList(), BuiltinListDifference(), BuiltinListIntersection(), BuiltinListitem(), BuiltinListSort(), BuiltinListUnion(), BuiltinLookup(), BuiltinLowercase(), BuiltinMultiply(), BuiltinNot(),