From fb2f1849583dfa94df37b9a60ec1eea0a5939fd2 Mon Sep 17 00:00:00 2001 From: Charles Haley Date: Sat, 13 Feb 2021 13:08:27 +0000 Subject: [PATCH] Two changes: 1) Add the alias "list_contains" to the "in_list" function so that naming is more consistent. 2) Add composite categories to valid grouped searches. --- manual/template_lang.rst | 8 ++++++-- src/calibre/gui2/preferences/search.py | 13 ++++--------- src/calibre/utils/formatter_functions.py | 2 ++ 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/manual/template_lang.rst b/manual/template_lang.rst index f09e19a523..2e6bf56bc1 100644 --- a/manual/template_lang.rst +++ b/manual/template_lang.rst @@ -460,8 +460,10 @@ parameters can be statements (sequences of expressions). Note that the definitiv * ``fractional_part(x)`` -- returns the value after the decimal point. For example, ``fractional_part(3.14)`` returns ``0.14``. Throws an exception if ``x`` is not a number. * ``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. + * ``list_contains(separator, pattern, found_val, ..., not_found_val)`` -- (Alias of ``in_list``) Interpret the field as a list + of items separated by `separator`, evaluating the `pattern` against each value in the list. If the `pattern` matches a value, + return `found_val`, otherwise return `not_found_val`. The `pattern` and `found_value` can be repeated as many times as desired, + permitting returning different values depending on the search. The patterns are checked in order. The first match is returned. * ``list_difference(list1, list2, separator)`` -- return a list made by removing from `list1` any item found in `list2`, using a case-insensitive comparison. The items in `list1` and `list2` are separated by separator, as are the items in the returned list. * ``list_equals(list1, sep1, list2, sep2, yes_val, no_val)`` -- return `yes_val` if `list1` and `list2` contain the same items, @@ -482,6 +484,8 @@ parameters can be statements (sequences of expressions). Note that the definitiv * ``mod(x)`` -- returns the remainder of ``x / y``, where ``x``, ``y``, and the result are integers. Throws an exception if either ``x`` or ``y`` is not a number. * ``multiply(x, y, ...)`` -- returns the product of its arguments. Throws an exception if any argument is not a number. + * ``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. * ``ondevice()`` -- return the string "Yes" if ``ondevice`` is set, otherwise return the empty string * ``or(value, value, ...)`` -- returns the string ``"1"`` if any value is not 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. diff --git a/src/calibre/gui2/preferences/search.py b/src/calibre/gui2/preferences/search.py index 0b4b7b6f29..593ac1a2b7 100644 --- a/src/calibre/gui2/preferences/search.py +++ b/src/calibre/gui2/preferences/search.py @@ -8,6 +8,7 @@ __docformat__ = 'restructuredtext en' from PyQt5.Qt import QApplication +from calibre.db.categories import find_categories from calibre.gui2.preferences import ConfigWidgetBase, test_widget, \ CommaSeparatedList, AbortCommit from calibre.gui2.preferences.search_ui import Ui_Form @@ -67,15 +68,9 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form): self.gst = db.prefs.get('grouped_search_terms', {}).copy() self.orig_gst_keys = list(self.gst.keys()) - fl = [] - for f in db.all_field_keys(): - fm = db.metadata_for_field(f) - if not fm['search_terms']: - continue - if not fm['is_category']: - continue - fl.append(f) - self.gst_value.update_items_cache(fl) + fm = db.new_api.field_metadata + categories = [x[0] for x in find_categories(fm) if fm[x[0]]['search_terms']] + self.gst_value.update_items_cache(categories) self.fill_gst_box(select=None) self.user_category_layout.setContentsMargins(0, 30, 0, 0) diff --git a/src/calibre/utils/formatter_functions.py b/src/calibre/utils/formatter_functions.py index 2e58047a54..b1d1563e1e 100644 --- a/src/calibre/utils/formatter_functions.py +++ b/src/calibre/utils/formatter_functions.py @@ -629,6 +629,8 @@ class BuiltinInList(BuiltinFormatterFunction): 'many times as desired, permitting returning different values ' 'depending on the search. The patterns are checked in order. The ' 'first match is returned.') + aliases = ['list_contains'] + def evaluate(self, formatter, kwargs, mi, locals, val, sep, *args): if (len(args) % 2) != 1: