Template language: Add a few new functions to manipulate lists (list_difference, list_intersection, list_sort)

This commit is contained in:
Kovid Goyal 2011-08-01 05:54:57 -06:00
commit 3570067aa0
2 changed files with 60 additions and 5 deletions

View File

@ -263,6 +263,9 @@ The following functions are available in addition to those described in single-f
* ``formats_sizes()`` -- return a comma-separated list of colon_separated items representing sizes in bytes of the formats of a book. You can use the select function to get the size for a specific format. Note that format names are always uppercase, as in EPUB.
* ``has_cover()`` -- return ``Yes`` if the book has a cover, otherwise return the empty string
* ``not(value)`` -- returns the string "1" if the value is empty, otherwise returns the empty string. This function works well with test or first_non_empty. You can have as many values as you want.
* ``list_difference(list1, list2, separator)`` -- return a list made by removing from `list1` any item found in `list2`, using a case-insensitive compare. The items in `list1` and `list2` are separated by separator, as are the items in the returned list.
* ``list_intersection(list1, list2, separator)`` -- return a list made by removing from `list1` any item not found in `list2`, using a case-insensitive compare. The items in `list1` and `list2` are separated by separator, as are the items in the returned list.
* ``list_sort(list, direction, separator)`` -- return list sorted using a case-insensitive sort. If `direction` is zero, the list is sorted ascending, otherwise descending. The list items are separated by separator, as are the items in the returned list.
* ``merge_lists(list1, list2, separator)`` -- return a list made by merging the items in list1 and list2, removing duplicate items using a case-insensitive compare. If items differ in case, the one in list1 is used. The items in list1 and list2 are separated by separator, as are the items in the returned list.
* ``multiply(x, y)`` -- returns x * y. Throws an exception if either x or y are not numbers.
* ``ondevice()`` -- return the string "Yes" if ondevice is set, otherwise return the empty string

View File

@ -851,7 +851,58 @@ class BuiltinMergeLists(BuiltinFormatterFunction):
for i in l2:
if icu_lower(i) not in lcl1:
res.append(i)
return ', '.join(sorted(res, key=sort_key))
return ', '.join(res)
class BuiltinListDifference(BuiltinFormatterFunction):
name = 'list_difference'
arg_count = 3
category = 'List Manipulation'
__doc__ = doc = _('list_difference(list1, list2, separator) -- '
'return a list made by removing from list1 any item found in list2, '
'using a case-insensitive compare. The items in list1 and list2 '
'are separated by separator, as are the items in the returned list.')
def evaluate(self, formatter, kwargs, mi, locals, list1, list2, separator):
l1 = [l.strip() for l in list1.split(separator) if l.strip()]
l2 = [icu_lower(l.strip()) for l in list2.split(separator) if l.strip()]
res = []
for i in l1:
if icu_lower(i) not in l2:
res.append(i)
return ', '.join(res)
class BuiltinListIntersection(BuiltinFormatterFunction):
name = 'list_intersection'
arg_count = 3
category = 'List Manipulation'
__doc__ = doc = _('list_intersection(list1, list2, separator) -- '
'return a list made by removing from list1 any item not found in list2, '
'using a case-insensitive compare. The items in list1 and list2 '
'are separated by separator, as are the items in the returned list.')
def evaluate(self, formatter, kwargs, mi, locals, list1, list2, separator):
l1 = [l.strip() for l in list1.split(separator) if l.strip()]
l2 = [icu_lower(l.strip()) for l in list2.split(separator) if l.strip()]
res = []
for i in l1:
if icu_lower(i) in l2:
res.append(i)
return ', '.join(res)
class BuiltinListSort(BuiltinFormatterFunction):
name = 'list_sort'
arg_count = 3
category = 'List Manipulation'
__doc__ = doc = _('list_sort(list, direction, separator) -- '
'return list sorted using a case-insensitive sort. If direction is '
'zero, the list is sorted ascending, otherwise descending. The list items '
'are separated by separator, as are the items in the returned list.')
def evaluate(self, formatter, kwargs, mi, locals, list1, direction, separator):
res = [l.strip() for l in list1.split(separator) if l.strip()]
return ', '.join(sorted(res, key=sort_key, reverse=direction != 0))
class BuiltinToday(BuiltinFormatterFunction):
name = 'today'
@ -893,12 +944,13 @@ formatter_builtins = [
BuiltinFirstNonEmpty(), BuiltinField(), BuiltinFormatDate(),
BuiltinFormatNumber(), BuiltinFormatsModtimes(), BuiltinFormatsSizes(),
BuiltinHasCover(), BuiltinHumanReadable(), BuiltinIdentifierInList(),
BuiltinIfempty(), BuiltinInList(), BuiltinListitem(), BuiltinLookup(),
BuiltinIfempty(), BuiltinInList(), BuiltinListDifference(),
BuiltinListIntersection(), BuiltinListitem(), BuiltinListSort(), BuiltinLookup(),
BuiltinLowercase(), BuiltinMergeLists(), BuiltinMultiply(), BuiltinNot(),
BuiltinOndevice(), BuiltinOr(), BuiltinPrint(), BuiltinRawField(),
BuiltinRe(), BuiltinSelect(), BuiltinShorten(), BuiltinStrcat(),
BuiltinStrcmp(), BuiltinStrInList(), BuiltinSubitems(), BuiltinSublist(),
BuiltinSubstr(), BuiltinSubtract(), BuiltinSwapAroundComma(),
BuiltinStrcmp(), BuiltinStrInList(), BuiltinSubitems(),
BuiltinSublist(),BuiltinSubstr(), BuiltinSubtract(), BuiltinSwapAroundComma(),
BuiltinSwitch(), BuiltinTemplate(), BuiltinTest(), BuiltinTitlecase(),
BuiltinToday(), BuiltinUppercase(),
]