diff --git a/manual/template_lang.rst b/manual/template_lang.rst index 34656e84e7..fe0d17cf3a 100644 --- a/manual/template_lang.rst +++ b/manual/template_lang.rst @@ -600,6 +600,27 @@ In `GPM` the functions described in `Single Function Mode` all require an additi * ``has_cover()`` -- return ``'Yes'`` if the book has a cover, otherwise the empty string. +* ``has_note(field_name, field_value)``. This function has two variants: + + * if ``field_value`` is not ``''`` (the empty string) return ``'1'`` if the value ``field_value`` in the field ``field_name`` has a note, otherwise ``''``. Example::: + + has_note('tags', 'Fiction') + + returns ``'1'`` if the tag ``fiction`` has an attached note, otherwise ``''``. + + * If ``field_value`` is ``''`` then return a list of values in ``field_name`` that have a note. If no item in the field has a note, return ``''``. This variant is useful for showing column icons if any value in the field has a note, rather than a specific value. + + Example:: + + has_note('authors', '') + + returns a list of authors that have notes. or ``''`` if no author has a note. + + You can test if all the values in ``field_name`` have a note by comparing the list length of this function's return value against the list length of the values in ``field_name``. Example:: + + list_count(has_note('authors', ''), '&') ==# list_count_field('authors') + + * ``has_extra_files([pattern])`` -- returns the count of extra files, otherwise '' (the empty string). If the optional parameter ``pattern`` (a regular expression) is supplied then the list is filtered to files that match ``pattern`` before the files are counted. The pattern match is case insensitive. See also the functions ``extra_file_names()``, ``extra_file_size()`` and ``extra_file_modtime()``. This function can be used only in the GUI. * ``identifier_in_list(val, id_name [, found_val, not_found_val])`` -- treat ``val`` as a list of identifiers separated by commas. An identifier has the format ``id_name:value``. The ``id_name`` parameter is the id_name text to search for, either ``id_name`` or ``id_name:regexp``. The first case matches if there is any identifier matching that id_name. The second case matches if id_name matches an identifier and the regexp matches the identifier's value. If ``found_val`` and ``not_found_val`` are provided then if there is a match then return ``found_val``, otherwise return ``not_found_val``. If ``found_val`` and ``not_found_val`` are not provided then if there is a match then return the ``identifier:value`` pair, otherwise the empty string (``''``). * ``is_dark_mode()`` -- returns ``'1'`` if calibre is running in dark mode, ``''`` (the empty string) otherwise. This function can be used in advanced color and icon rules to choose different colors/icons according to the mode. Example:: diff --git a/src/calibre/utils/formatter_functions.py b/src/calibre/utils/formatter_functions.py index 89a0d07e6f..72c08bd899 100644 --- a/src/calibre/utils/formatter_functions.py +++ b/src/calibre/utils/formatter_functions.py @@ -2630,23 +2630,40 @@ class BuiltinHasNote(BuiltinFormatterFunction): name = 'has_note' arg_count = 2 category = 'Template database functions' - __doc__ = doc = _("has_note(field_name, field_value) -- return '1' " - "if the value 'field_value' in the field 'field_name' " - "has an attached note, '' otherwise. Example: " - "has_note('tags', 'Fiction') returns '1' if the tag " - "'fiction' has an attached note, '' otherwise.") + __doc__ = doc = _("has_note(field_name, field_value) -- if field_value is not " + "'' (the empty string) , return '1' if the value 'field_value' " + "in the field 'field_name' has an attached note, otherwise ''. " + "Example: has_note('tags', 'Fiction') returns '1' if the tag " + "'fiction' has a note, otherwise ''. If field_value " + "is '' then return a list of values in field_name that have " + "a note. If no item in the field has a note, return ''. " + "Example: has_note('authors', '') returns a list of authors " + "that have notes. or '' if no author has a note. The second " + "variant is useful for showing column icons icons if any value " + "in the field has a note, rather than a specific value. " + "You can also test if all the values have a note by comparing " + "the list length of this function's return value against " + "the list length of the values in field_name.") def evaluate(self, formatter, kwargs, mi, locals, field_name, field_value): db = self.get_database(mi).new_api - note = None + if field_value: + note = None + try: + item_id = db.get_item_id(field_name, field_value, case_sensitive=True) + if item_id is not None: + note = db.notes_data_for(field_name, item_id) + except Exception as e: + traceback.print_exc() + raise ValueError(str(e)) + return '1' if note is not None else '' try: - item_id = db.get_item_id(field_name, field_value, case_sensitive=True) - if item_id is not None: - note = db.notes_data_for(field_name, item_id) + notes_for_book = db.items_with_notes_in_book(mi.id) + values = [v for v in notes_for_book.get(field_name, {}).values()] + return db.field_metadata[field_name]['is_multiple'].get('list_to_ui', ', ').join(values) except Exception as e: traceback.print_exc() - raise ValueError(e) - return '1' if note is not None else '' + raise ValueError(str(e)) class BuiltinIsDarkMode(BuiltinFormatterFunction):