From ad3f6b0258a51e38cd51be3d996f27e37cfb99a0 Mon Sep 17 00:00:00 2001 From: Charles Haley Date: Thu, 26 May 2022 14:05:15 +0100 Subject: [PATCH] New template function urls_from_identifiers() --- manual/template_lang.rst | 1 + src/calibre/utils/formatter_functions.py | 40 ++++++++++++++++++++++-- 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/manual/template_lang.rst b/manual/template_lang.rst index 4040953608..3211aad499 100644 --- a/manual/template_lang.rst +++ b/manual/template_lang.rst @@ -581,6 +581,7 @@ In `GPM` the functions described in `Single Function Mode` all require an additi * ``subtract(x, y)`` -- returns ``x - y``. Throws an exception if either ``x`` or ``y`` are not numbers. This function can usually be replaced by the ``-`` operator. * ``today()`` -- return a date+time string for today (now). This value is designed for use in `format_date` or `days_between`, but can be manipulated like any other string. The date is in `ISO `_ date/time format. * ``template(x)`` -- evaluates ``x`` as a template. The evaluation is done in its own context, meaning that variables are not shared between the caller and the template evaluation. +* ``urls_from_identifiers(identifiers, sort_results)`` -- given a comma-separated list of ``identifiers``, where an `identifier` is a colon-separated pair of values (``id_name:id_value``), returns a comma-separated list of HTML URLs generated from the identifiers. The list not sorted if sort_results is ``0`` (character or number), otherwise it is sorted alphabetically by the identifier name. The URLs are generated in the same way as the built-in identifiers column when shown in :guilabel:`Book details`. .. _template_mode: diff --git a/src/calibre/utils/formatter_functions.py b/src/calibre/utils/formatter_functions.py index d99799c1ee..a05c46488d 100644 --- a/src/calibre/utils/formatter_functions.py +++ b/src/calibre/utils/formatter_functions.py @@ -13,10 +13,11 @@ __docformat__ = 'restructuredtext en' import inspect, re, traceback, numbers from datetime import datetime, timedelta +from functools import partial from math import trunc, floor, ceil, modf from contextlib import suppress -from calibre import human_readable, prints +from calibre import human_readable, prints, prepare_string_for_xml from calibre.constants import DEBUG from calibre.ebooks.metadata import title_sort from calibre.utils.config import tweaks @@ -2192,6 +2193,41 @@ class BuiltinCharacter(BuiltinFormatterFunction): raise NotImplementedError() +class BuiltinUrlsFromIdentifiers(BuiltinFormatterFunction): + name = 'urls_from_identifiers' + arg_count = 2 + category = 'Formatting values' + __doc__ = doc = _('urls_from_identifiers(identifiers, sort_results) -- given ' + 'a comma-separated list of identifiers, where an identifier ' + 'is a colon-separated pair of values (name:id_value), returns a ' + 'comma-separated list of HTML URLs generated from the ' + 'identifiers. The list not sorted if sort_results is 0 ' + '(character or number), otherwise it is sorted alphabetically ' + 'by the identifier name. The URLs are generated in the same way ' + 'as the built-in identifiers column when shown in book details.') + + def evaluate(self, formatter, kwargs, mi, locals, identifiers, sort_results): + from calibre.ebooks.metadata.sources.identify import urls_from_identifiers + try: + v = dict() + for id_ in identifiers.split(','): + if id_: + pair = id_.split(':', maxsplit=1) + if len(pair) == 2: + l = pair[0].strip() + r = pair[1].strip() + if l and r: + v[l] = r + urls = urls_from_identifiers(v, sort_results=sort_results != '0') + p = prepare_string_for_xml + a = partial(prepare_string_for_xml, attribute=True) + links = [f'{p(name)}' + for name, id_typ, id_val, url in urls] + return ', '.join(links) + except Exception as e: + return str(e) + + _formatter_builtins = [ BuiltinAdd(), BuiltinAnd(), BuiltinApproximateFormats(), BuiltinArguments(), BuiltinAssign(), @@ -2222,7 +2258,7 @@ _formatter_builtins = [ BuiltinSublist(),BuiltinSubstr(), BuiltinSubtract(), BuiltinSwapAroundArticles(), BuiltinSwapAroundComma(), BuiltinSwitch(), BuiltinTemplate(), BuiltinTest(), BuiltinTitlecase(), - BuiltinToday(), BuiltinTransliterate(), BuiltinUppercase(), + BuiltinToday(), BuiltinTransliterate(), BuiltinUppercase(), BuiltinUrlsFromIdentifiers(), BuiltinUserCategories(), BuiltinVirtualLibraries(), BuiltinAnnotationCount() ]