diff --git a/manual/template_lang.rst b/manual/template_lang.rst index 343f5861a9..a12c8eea4d 100644 --- a/manual/template_lang.rst +++ b/manual/template_lang.rst @@ -649,7 +649,9 @@ Python Template Mode Python Template Mode (PTM) lets you write templates using native python and the `calibre API `_. The database API will be of most use; further discussion is beyond the scope of this manual. PTM templates are faster and can do more complicated operations but you must know how to write code in python using the calibre API. -A PTM template begins with:: +A PTM template begins with: + +.. code-block:: python python: def evaluate(book, db, globals, arguments, **kwargs): @@ -664,7 +666,7 @@ A PTM template begins with:: You can add the above text to your template using the context menu, usually accessed with a right click. The comments are not significant and can be removed. You must use python indenting. -Here is an example of a PTM template that produces a list of all the authors for a series. The list is stored in a `Column built from other columns, behaves like tags`. It shows in :guilabel:`Book details` and has the `on separate lines` checked (in :guilabel:`Preferences->Look & feel->Book details`). That option requires the list to be comma-separated. To satisfy that requirement the template converts commas in author names to semicolons then builds a comma-separated list of authors. The authors are then sorted, which is why the template uses author_sort.:: +Here is an example of a PTM template that produces a list of all the authors for a series. The list is stored in a `Column built from other columns, behaves like tags`. It shows in :guilabel:`Book details` and has the :guilabel:`on separate lines` checked (in :guilabel:`Preferences->Look & feel->Book details`). That option requires the list to be comma-separated. To satisfy that requirement the template converts commas in author names to semicolons then builds a comma-separated list of authors. The authors are then sorted, which is why the template uses author_sort.:: python: def evaluate(book, db, globals, arguments, **kwargs): @@ -672,7 +674,7 @@ Here is an example of a PTM template that produces a list of all the authors for return '' ans = set() 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('&')]) + ans.update(v.strip() for v in db.new_api.field_for('author_sort', id_).split('&')) return ', '.join(v.replace(',', ';') for v in sorted(ans)) The output in :guilabel:`Book details` looks like this: diff --git a/src/calibre/gui2/actions/booklist_context_menu.py b/src/calibre/gui2/actions/booklist_context_menu.py index 94bcefc49b..01d66539e5 100644 --- a/src/calibre/gui2/actions/booklist_context_menu.py +++ b/src/calibre/gui2/actions/booklist_context_menu.py @@ -1,7 +1,6 @@ #!/usr/bin/env python # License: GPLv3 Copyright: 2022, Charles Haley # -from qt.core import QPoint from calibre.gui2.actions import InterfaceAction diff --git a/src/calibre/gui2/dialogs/template_dialog.py b/src/calibre/gui2/dialogs/template_dialog.py index 24eff84f9f..91ed448b73 100644 --- a/src/calibre/gui2/dialogs/template_dialog.py +++ b/src/calibre/gui2/dialogs/template_dialog.py @@ -776,7 +776,7 @@ class TemplateDialog(QDialog, Ui_TemplateDialog): def textbox_changed(self): cur_text = str(self.textbox.toPlainText()) if cur_text.startswith('python:'): - if self.highlighting_gpm == True: + if self.highlighting_gpm is True: self.highlighter.initialize_rules(self.builtins, True) self.highlighting_gpm = False self.break_box.setChecked(False) diff --git a/src/calibre/gui2/preferences/template_functions.py b/src/calibre/gui2/preferences/template_functions.py index 29982a5d45..15f510fbd6 100644 --- a/src/calibre/gui2/preferences/template_functions.py +++ b/src/calibre/gui2/preferences/template_functions.py @@ -315,7 +315,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form): return True try: prog = str(self.program.toPlainText()) - cls = compile_user_function(name, str(self.documentation.toPlainText()), + compile_user_function(name, str(self.documentation.toPlainText()), self.argument_count.value(), prog) except: error_dialog(self.gui, _('Template functions'), diff --git a/src/calibre/utils/formatter.py b/src/calibre/utils/formatter.py index 44f9da012e..7cfec49d7b 100644 --- a/src/calibre/utils/formatter.py +++ b/src/calibre/utils/formatter.py @@ -140,7 +140,7 @@ class StoredTemplateCallNode(Node): Node.__init__(self, line_number, 'call template: ' + name + '()') self.node_type = self.NODE_CALL_STORED_TEMPLATE self.name = name - self.function = function # instance of the definition class + self.function = function # instance of the definition class self.expression_list = expression_list @@ -1550,7 +1550,6 @@ class TemplateFormatter(string.Formatter): if compiled_text is None: compiled_text = self.compile_python_template(func.program_text[len('python:'):]) func.cached_compiled_text = compiled_text - print(args) return self._run_python_template(compiled_text, args) def _eval_python_template(self, template, column_name): @@ -1588,10 +1587,10 @@ class TemplateFormatter(string.Formatter): func = locals_['evaluate'] return func except SyntaxError as e: - raise(ValueError( - _('Syntax error on line {0} column {1}: text {2}').format(e.lineno, e.offset, e.text))) + raise ValueError( + _('Syntax error on line {0} column {1}: text {2}').format(e.lineno, e.offset, e.text)) except KeyError: - raise(ValueError(_("The {0} function is not defined in the template").format('evaluate'))) + raise ValueError(_("The {0} function is not defined in the template").format('evaluate')) # ################# Override parent classes methods ##################### diff --git a/src/calibre/utils/formatter_functions.py b/src/calibre/utils/formatter_functions.py index 0f1238c498..533eab5d94 100644 --- a/src/calibre/utils/formatter_functions.py +++ b/src/calibre/utils/formatter_functions.py @@ -14,7 +14,7 @@ __docformat__ = 'restructuredtext en' import inspect, re, traceback, numbers from contextlib import suppress from datetime import datetime, timedelta -from enum import Enum +from enum import Enum, auto from functools import partial from math import trunc, floor, ceil, modf @@ -30,9 +30,9 @@ from polyglot.builtins import iteritems, itervalues class StoredObjectType(Enum): - PythonFunction = 1 - StoredGPMTemplate = 2 - StoredPythonTemplate = 3 + PythonFunction = auto() + StoredGPMTemplate = auto() + StoredPythonTemplate = auto() class FormatterFunctions: