diff --git a/manual/template_lang.rst b/manual/template_lang.rst index c3c46e6e4f..f37d45859f 100644 --- a/manual/template_lang.rst +++ b/manual/template_lang.rst @@ -677,10 +677,17 @@ Here is an example of a PTM template that produces a list of all the authors for def evaluate(book, context): if book.series is None: return '' + db = context.db.new_api ans = set() - db = context.db - for id_ in db.search_getting_ids(f'series:"={book.series}"', ''): - ans.update(v.strip() for v in db.new_api.field_for('author_sort', id_).split('&')) + # Get the list of books in the series + ids = db.search(f'series:"={book.series}"', '') + if ids: + # Get all the author_sort values for the books in the series + author_sorts = (v for v in db.all_field_for('author_sort', ids).values()) + # Add the names to the result set, removing duplicates + for aus in author_sorts: + ans.update(v.strip() for v in aus.split('&')) + # Make a sorted comma-separated string from the result set return ', '.join(v.replace(',', ';') for v in sorted(ans)) The output in :guilabel:`Book details` looks like this: diff --git a/src/calibre/gui2/dialogs/template_dialog.py b/src/calibre/gui2/dialogs/template_dialog.py index a158f6a982..2aa8888cc5 100644 --- a/src/calibre/gui2/dialogs/template_dialog.py +++ b/src/calibre/gui2/dialogs/template_dialog.py @@ -18,7 +18,8 @@ from calibre import sanitize_file_name from calibre.constants import config_dir from calibre.ebooks.metadata.book.base import Metadata from calibre.ebooks.metadata.book.formatter import SafeFormat -from calibre.gui2 import gprefs, error_dialog, choose_files, choose_save_file, pixmap_to_data +from calibre.gui2 import (gprefs, error_dialog, choose_files, choose_save_file, + pixmap_to_data, question_dialog) from calibre.gui2.dialogs.template_dialog_ui import Ui_TemplateDialog from calibre.library.coloring import (displayable_columns, color_row_key) from calibre.utils.config_base import tweaks @@ -84,45 +85,30 @@ class TemplateHighlighter(QSyntaxHighlighter): r.append((re.compile(a), b)) if not for_python: - a( - r"\b[a-zA-Z]\w*\b(?!\(|\s+\()" - r"|\$+#?[a-zA-Z]\w*", - "identifier") - + a(r"\b[a-zA-Z]\w*\b(?!\(|\s+\()" + r"|\$+#?[a-zA-Z]\w*", + "identifier") a(r"^program:", "keymode") - a( - "|".join([r"\b%s\b" % keyword for keyword in self.KEYWORDS_GPM]), - "keyword") - - a( - "|".join([r"\b%s\b" % builtin for builtin in + a("|".join([r"\b%s\b" % keyword for keyword in self.KEYWORDS_GPM]), "keyword") + a("|".join([r"\b%s\b" % builtin for builtin in (builtin_functions if builtin_functions else formatter_functions().get_builtins())]), "builtin") - a(r"""(?