From 02b28118929b9f6bab7954c47662bf61f6a886aa Mon Sep 17 00:00:00 2001 From: un-pogaz <46523284+un-pogaz@users.noreply.github.com> Date: Mon, 17 Oct 2022 14:22:19 +0200 Subject: [PATCH] chaley recommandation --- manual/template_lang.rst | 2 +- src/calibre/utils/formatter.py | 57 ++++++++++++---------------------- 2 files changed, 21 insertions(+), 38 deletions(-) diff --git a/manual/template_lang.rst b/manual/template_lang.rst index 64add7f1e2..602a9306c9 100644 --- a/manual/template_lang.rst +++ b/manual/template_lang.rst @@ -670,7 +670,7 @@ You can add the above text to your template using the context menu, usually acce The context object supports ``str(context)`` that returns a string of the context's contents, and ``context.attributes`` that returns a list of the attribute names in the context. -The ``context.funcs`` attribute allows to use the Builtin and User functions, and also the Stored GPM/Python templates so that you can exectute them directly in your code. The functions can be retrieve by they name and they name plus a '_' at the end in case of conflict with Python language keywords. Note that all functions will return a string value, only the special functions ``arguments()``, ``globals()`` and ``set_globals()`` will return a dict based on the passed keywords arguments. +The ``context.funcs`` attribute allows to use the Builtin and User functions, and also the Stored GPM/Python templates so that you can exectute them directly in your code. The functions can be retrieve by they name and they name plus a '_' at the end in case of conflict with Python language keywords. 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. diff --git a/src/calibre/utils/formatter.py b/src/calibre/utils/formatter.py index 501068d676..3b016641ad 100644 --- a/src/calibre/utils/formatter.py +++ b/src/calibre/utils/formatter.py @@ -891,7 +891,7 @@ class FormatterFuncsCaller(): func_name = None if name.endswith('_') and name[:-1] in formatter.funcs: #given the priority to the backup name func_name = name[:-1] - if not func_name and name in formatter.funcs: + elif name in formatter.funcs: func_name = name if func_name: @@ -899,46 +899,29 @@ class FormatterFuncsCaller(): def n(d): return str('' if d is None else d) args = [n(a) for a in args] - kargs = {n(k):v for k,v in kargs.items()} - def raise_error(msg): - raise ValueError(msg) - try: - # special function - if func_name in ['arguments', 'globals', 'set_globals']: - if args and kargs: - raise_error(_('Invalid mixing keyword arguments and positional arguments')) - - kargs.update({a:'' for a in args}) - - if func_name == 'arguments': - args = formatter.python_context_object.arguments or [] - for i,k in enumerate(kargs.keys()): - if i == len(args): break - kargs[k] = str(args[i]) - - elif func_name == 'globals': - kargs = {k:formatter.global_vars.get(k, d) for k,d in kargs.items()} - - elif func_name == 'set_globals': - formatter.global_vars.update(kargs) - - rslt = kargs + def raise_error(msg): + raise ValueError(msg) + if kargs: + raise_error(_('Got an unsupported keyword argument')) + # special function + if func_name == 'arguments': + raise_error(_('Get the arguments from context.arguments instead of calling arguments()')) + elif func_name == 'globals': + raise_error(_('Get the globals from context.globals instead of calling globals()')) + elif func_name == 'set_globals': + raise_error(_("Set globals using context.globals['name'] = val instead of calling set_globals()")) + elif func_name == 'character': + if _Parser.inlined_function_nodes['character'][0](args): + rslt = _Interpreter.characters.get(args[0], None) + if rslt is None: + raise_error(_("Invalid character name '{0}'").format(args[0])) + else: + raise_error(_('Incorrect number of arguments')) else: - if kargs: - raise_error(_('Cannot support keyword arguments')) - - if func_name == 'character': - if _Parser.inlined_function_nodes['character'][0](args): - rslt = _Interpreter.characters.get(args[0], None) - if rslt is None: - raise_error(_("Invalid character name '{0}'").format(args[0])) - else: - raise_error(_('Incorrect number of arguments')) - - # buildin/user function and Stored GPM/Python template + # builtin/user function and Stored GPM/Python template func = formatter.funcs[func_name] if func.object_type == StoredObjectType.PythonFunction: rslt = func.evaluate(formatter, formatter.kwargs, formatter.book, formatter.locals, *args)