Template language: Allow the str_in_list() function to return different values depending on what is found

Merge branch 'master' of https://github.com/cbhaley/calibre
This commit is contained in:
Kovid Goyal 2017-07-10 08:00:42 +05:30
commit aa935d074d
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
2 changed files with 24 additions and 13 deletions

View File

@ -132,7 +132,7 @@ The functions available are listed below. Note that the definitive documentation
* ``re(pattern, replacement)`` -- return the field after applying the regular expression. All instances of `pattern` are replaced with `replacement`. As in all of calibre, these are Python-compatible regular expressions.
* ``select(key)`` -- interpret the field as a comma-separated list of items, with the items being of the form "id:value". Find the pair with the id equal to key, and return the corresponding value. This function is particularly useful for extracting a value such as an isbn from the set of identifiers for a book.
* ``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.
* ``str_in_list(val, separator, string, found_val, not_found_val)`` -- treat val as a list of items separated by separator, comparing the string against each value in the list. If the string matches a value, return found_val, otherwise return not_found_val. If the string contains separators, then it is also treated as a list and each value is checked.
* ``str_in_list(val, separator, string, found_val, ..., not_found_val)`` -- treat val as a list of items separated by separator, comparing the string against each value in the list. If the string matches a value (ignoring case), return found_val, otherwise return not_found_val. If the string contains separators, then it is also treated as a list and each value is checked. The string and found_value can be repeated as many times as desired, permitting returning different values depending on the search. The strings are checked in order. The first match is returned.
* ``subitems(val, start_index, end_index)`` -- This function is used to break apart lists of tag-like hierarchical items such as genres. It interprets the value as a comma-separated list of tag-like items, where each item is a period-separated list. Returns a new list made by first finding all the period-separated tag-like items, then for each such item extracting the components from `start_index` to `end_index`, then combining the results back together. The first component in a period-separated list has an index of zero. If an index is negative, then it counts from the end of the list. As a special case, an end_index of zero is assumed to be the length of the list. Examples::
Assuming a #genre column containing "A.B.C":

View File

@ -544,24 +544,35 @@ class BuiltinInList(BuiltinFormatterFunction):
class BuiltinStrInList(BuiltinFormatterFunction):
name = 'str_in_list'
arg_count = 5
arg_count = -1
category = 'List lookup'
__doc__ = doc = _('str_in_list(val, separator, string, found_val, not_found_val) -- '
__doc__ = doc = _('str_in_list(val, separator, string, found_val, ..., not_found_val) -- '
'treat val as a list of items separated by separator, '
'comparing the string against each value in the list. If the '
'string matches a value, return found_val, otherwise return '
'string matches a value (ignoring case) then return found_val, otherwise return '
'not_found_val. If the string contains separators, then it is '
'also treated as a list and each value is checked.')
'also treated as a list and each value is checked. The string and '
'found_value can be repeated as many times as desired, permitting '
'returning different values depending on the search. The strings are '
'checked in order. The first match is returned.')
def evaluate(self, formatter, kwargs, mi, locals, val, sep, str, fv, nfv):
def evaluate(self, formatter, kwargs, mi, locals, val, sep, *args):
if (len(args) % 2) != 1:
raise ValueError(_('wstr_in_list requires an odd number of arguments'))
l = [v.strip() for v in val.split(sep) if v.strip()]
c = [v.strip() for v in str.split(sep) if v.strip()]
if l:
for v in l:
for t in c:
if strcmp(t, v) == 0:
return fv
return nfv
i = 0
while i < len(args):
if i + 1 >= len(args):
return args[i]
sf = args[i]
fv = args[i+1]
c = [v.strip() for v in sf.split(sep) if v.strip()]
if l:
for v in l:
for t in c:
if strcmp(t, v) == 0:
return fv
i += 2
class BuiltinIdentifierInList(BuiltinFormatterFunction):