diff --git a/src/calibre/gui2/dialogs/template_dialog.py b/src/calibre/gui2/dialogs/template_dialog.py
index 69151e42a4..2c2b053a45 100644
--- a/src/calibre/gui2/dialogs/template_dialog.py
+++ b/src/calibre/gui2/dialogs/template_dialog.py
@@ -62,8 +62,8 @@ from calibre.utils.resources import get_path as P
class DocViewer(Dialog):
- def __init__(self, docs_dsl, builtins, function_type_string_method, parent=None):
- self.docs_dsl = docs_dsl
+ def __init__(self, ffml, builtins, function_type_string_method, parent=None):
+ self.ffml = ffml
self.builtins = builtins
self.function_type_string = function_type_string_method
self.last_operation = None
@@ -102,18 +102,18 @@ class DocViewer(Dialog):
def header_line(self, name):
return f'\n
{name} ({self.function_type_string(name, longform=False)})
\n'
- def doc_from_class(self, cls):
- return cls.raw_doc if self.english_cb.isChecked() and hasattr(cls, 'raw_doc') else cls.doc
+ def get_doc(self, func):
+ doc = func.doc if hasattr(func, 'doc') else ''
+ return doc.raw_text if self.english_cb.isChecked() and hasattr(doc, 'raw_text') else doc
- def show_function(self, function_name):
- self.last_operation = partial(self.show_function, function_name)
- if function_name not in self.builtins or not self.builtins[function_name].doc:
- self.set_html(self.header_line(function_name) +
- ('No documentation provided'))
+ def show_function(self, fname):
+ self.last_operation = partial(self.show_function, fname)
+ bif = self.builtins[fname]
+ if fname not in self.builtins or not bif.doc:
+ self.set_html(self.header_line(fname) + ('No documentation provided'))
else:
- self.set_html(self.header_line(function_name) +
- self.docs_dsl.document_to_html(
- self.doc_from_class(self.builtins[function_name]), function_name))
+ self.set_html(self.header_line(fname) +
+ self.ffml.document_to_html(self.get_doc(bif), fname))
def show_all_functions(self):
self.last_operation = self.show_all_functions
@@ -122,11 +122,11 @@ class DocViewer(Dialog):
for name in sorted(self.builtins):
a(self.header_line(name))
try:
- doc = self.doc_from_class(cls = self.builtins[name])
+ doc = self.get_doc(self.builtins[name])
if not doc:
a(_('No documentation provided'))
else:
- a(self.docs_dsl.document_to_html(doc.strip(), name))
+ a(self.ffml.document_to_html(doc.strip(), name))
except Exception:
print('Exception in', name)
raise
@@ -441,7 +441,7 @@ class TemplateDialog(QDialog, Ui_TemplateDialog):
self.setupUi(self)
self.setWindowIcon(self.windowIcon())
- self.docs_dsl = FFMLProcessor()
+ self.ffml = FFMLProcessor()
self.dialog_number = dialog_number
self.coloring = color_field is not None
self.iconing = icon_field_key is not None
@@ -603,7 +603,7 @@ class TemplateDialog(QDialog, Ui_TemplateDialog):
def open_documentation_viewer(self):
if self.doc_viewer is None:
- dv = self.doc_viewer = DocViewer(self.docs_dsl, self.all_functions,
+ dv = self.doc_viewer = DocViewer(self.ffml, self.all_functions,
self.function_type_string, parent=self)
dv.finished.connect(self.doc_viewer_finished)
dv.show()
@@ -1048,7 +1048,7 @@ def evaluate(book, context):
self.func_type.clear()
if name in self.all_functions:
doc = self.all_functions[name].doc.strip()
- self.documentation.setHtml(self.docs_dsl.document_to_html(doc, name))
+ self.documentation.setHtml(self.ffml.document_to_html(doc, name))
if self.doc_viewer is not None:
self.doc_viewer.show_function(name)
if name in self.builtins and name in self.builtin_source_dict:
diff --git a/src/calibre/utils/formatter_functions.py b/src/calibre/utils/formatter_functions.py
index 08ea2348c1..c1636968b4 100644
--- a/src/calibre/utils/formatter_functions.py
+++ b/src/calibre/utils/formatter_functions.py
@@ -34,11 +34,24 @@ from calibre.utils.config import tweaks
from calibre.utils.date import UNDEFINED_DATE, format_date, now, parse_date
from calibre.utils.icu import capitalize, sort_key, strcmp
from calibre.utils.icu import lower as icu_lower
-from calibre.utils.localization import _, calibre_langcode_to_name, canonicalize_lang
+from calibre.utils.localization import _ as xlated, calibre_langcode_to_name, canonicalize_lang
from calibre.utils.titlecase import titlecase
from polyglot.builtins import iteritems, itervalues
+# Class and method to save an untranslated copy of translated strings
+class TranslatedStringWithRaw(str):
+
+ def __new__(cls, txt):
+ instance = super().__new__(cls, xlated(txt))
+ instance.raw_text = txt
+ return instance
+
+
+def _(txt):
+ return TranslatedStringWithRaw(txt)
+
+
class StoredObjectType(Enum):
PythonFunction = auto()
StoredGPMTemplate = auto()
@@ -48,7 +61,7 @@ class StoredObjectType(Enum):
class FormatterFunctions:
error_function_body = ('def evaluate(self, formatter, kwargs, mi, locals):\n'
- '\treturn "' +
+ '\treturn "' +
_('Duplicate user function name {0}. '
'Change the name or ensure that the functions are identical') + '"')
@@ -218,14 +231,13 @@ class BuiltinStrcmp(BuiltinFormatterFunction):
name = 'strcmp'
arg_count = 5
category = 'Relational'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``strcmp(x, y, lt, eq, gt)`` -- does a case-insensitive lexical comparison of
``x`` and ``y``. Returns ``lt`` if ``x < y``, ``eq`` if ``x == y``, otherwise
``gt``. This function can often be replaced by one of the lexical comparison
operators (``==``, ``>``, ``<``, etc.)
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals, x, y, lt, eq, gt):
v = strcmp(x, y)
@@ -240,7 +252,7 @@ class BuiltinStrcmpcase(BuiltinFormatterFunction):
name = 'strcmpcase'
arg_count = 5
category = 'Relational'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``strcmpcase(x, y, lt, eq, gt)`` -- does a case-sensitive lexical comparison of
``x`` and ``y``. Returns ``lt`` if ``x < y``, ``eq`` if ``x == y``, otherwise
@@ -250,7 +262,6 @@ Note: This is NOT the default behavior used by calibre, for example, in the
lexical comparison operators (``==``, ``>``, ``<``, etc.). This function could
cause unexpected results, preferably use ``strcmp()`` whenever possible.
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals, x, y, lt, eq, gt):
from calibre.utils.icu import case_sensitive_strcmp as case_strcmp
@@ -266,14 +277,13 @@ class BuiltinCmp(BuiltinFormatterFunction):
name = 'cmp'
category = 'Relational'
arg_count = 5
- raw_doc = (
+ __doc__ = doc = _(
r'''
``cmp(x, y, lt, eq, gt)`` -- compares ``x`` and ``y`` after converting both to
numbers. Returns ``lt`` if ``x <# y``, ``eq`` if ``x ==# y``, otherwise ``gt``.
This function can usually be replaced with one of the numeric compare operators
(``==#``, ``<#``, ``>#``, etc).
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals, x, y, lt, eq, gt):
x = float(x if x and x != 'None' else 0)
@@ -289,7 +299,7 @@ class BuiltinFirstMatchingCmp(BuiltinFormatterFunction):
name = 'first_matching_cmp'
category = 'Relational'
arg_count = -1
- raw_doc = (
+ __doc__ = doc = _(
r'''
``first_matching_cmp(val, [ cmp, result, ]* else_result)`` -- compares ``val < cmp``
in sequence, returning the associated result for the first comparison that
@@ -302,7 +312,6 @@ first_matching_cmp(i,5,"small",10,"middle",15,"large","giant")
[/CODE]
returns ``"large"``. The same example with a first value of 16 returns ``"giant"``.
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals, *args):
if (len(args) % 2) != 0:
@@ -319,12 +328,11 @@ class BuiltinStrcat(BuiltinFormatterFunction):
name = 'strcat'
arg_count = -1
category = 'String manipulation'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``strcat(a [, b]*)`` -- can take any number of arguments. Returns a string
formed by concatenating all the arguments.
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals, *args):
i = 0
@@ -338,11 +346,10 @@ class BuiltinStrlen(BuiltinFormatterFunction):
name = 'strlen'
arg_count = 1
category = 'String manipulation'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``strlen(value)`` -- Returns the length of the string ``value``.
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals, a):
try:
@@ -355,13 +362,12 @@ class BuiltinAdd(BuiltinFormatterFunction):
name = 'add'
arg_count = -1
category = 'Arithmetic'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``add(x [, y]*)`` -- returns the sum of its arguments. Throws an exception if an
argument is not a number. In most cases you can use the ``+`` operator instead
of this function.
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals, *args):
res = 0
@@ -375,13 +381,12 @@ class BuiltinSubtract(BuiltinFormatterFunction):
name = 'subtract'
arg_count = 2
category = 'Arithmetic'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``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.
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals, x, y):
x = float(x if x and x != 'None' else 0)
@@ -393,13 +398,12 @@ class BuiltinMultiply(BuiltinFormatterFunction):
name = 'multiply'
arg_count = -1
category = 'Arithmetic'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``multiply(x [, y]*)`` -- returns the product of its arguments. Throws an
exception if any argument is not a number. This function can usually be replaced
by the ``*`` operator.
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals, *args):
res = 1
@@ -413,13 +417,12 @@ class BuiltinDivide(BuiltinFormatterFunction):
name = 'divide'
arg_count = 2
category = 'Arithmetic'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``divide(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.
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals, x, y):
x = float(x if x and x != 'None' else 0)
@@ -431,12 +434,11 @@ class BuiltinCeiling(BuiltinFormatterFunction):
name = 'ceiling'
arg_count = 1
category = 'Arithmetic'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``ceiling(x)`` -- returns the smallest integer greater than or equal to ``x``.
Throws an exception if ``x`` is not a number.
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals, x):
x = float(x if x and x != 'None' else 0)
@@ -447,12 +449,11 @@ class BuiltinFloor(BuiltinFormatterFunction):
name = 'floor'
arg_count = 1
category = 'Arithmetic'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``floor(x)`` -- returns the largest integer less than or equal to ``x``. Throws
an exception if ``x`` is not a number.
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals, x):
x = float(x if x and x != 'None' else 0)
@@ -463,12 +464,11 @@ class BuiltinRound(BuiltinFormatterFunction):
name = 'round'
arg_count = 1
category = 'Arithmetic'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``round(x)`` -- returns the nearest integer to ``x``. Throws an exception if
``x`` is not a number.
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals, x):
x = float(x if x and x != 'None' else 0)
@@ -479,12 +479,11 @@ class BuiltinMod(BuiltinFormatterFunction):
name = 'mod'
arg_count = 2
category = 'Arithmetic'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``mod(x, y)`` -- returns the ``floor`` of the remainder of ``x / y``. Throws an
exception if either ``x`` or ``y`` is not a number.
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals, x, y):
x = float(x if x and x != 'None' else 0)
@@ -496,13 +495,12 @@ class BuiltinFractionalPart(BuiltinFormatterFunction):
name = 'fractional_part'
arg_count = 1
category = 'Arithmetic'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``fractional_part(value)`` -- returns the part of the value after the decimal
point. For example, ``fractional_part(3.14)`` returns ``0.14``. Throws an
exception if ``value`` is not a number.
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals, x):
x = float(x if x and x != 'None' else 0)
@@ -514,7 +512,7 @@ class BuiltinTemplate(BuiltinFormatterFunction):
arg_count = 1
category = 'Recursion'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``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
@@ -526,7 +524,6 @@ its value. Note also that prefixes and suffixes (the ``|prefix|suffix`` syntax)
cannot be used in the argument to this function when using template program
mode.
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals, template):
template = template.replace('[[', '{').replace(']]', '}')
@@ -537,7 +534,7 @@ class BuiltinEval(BuiltinFormatterFunction):
name = 'eval'
arg_count = 1
category = 'Recursion'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``eval(string)`` -- evaluates the string as a program, passing the local
variables. This permits using the template processor to construct complex
@@ -550,7 +547,6 @@ character. They are converted automatically. Note also that prefixes and
suffixes (the ``|prefix|suffix`` syntax) cannot be used in the argument to this
function when using Template Program Mode.
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals, template):
from calibre.utils.formatter import EvalFormatter
@@ -562,13 +558,12 @@ class BuiltinAssign(BuiltinFormatterFunction):
name = 'assign'
arg_count = 2
category = 'Other'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``assign(id, value)`` -- assigns ``value`` to ``id``, then returns ``value``. ``id``
must be an identifier, not an expression. In most cases you can use the ``=``
operator instead of this function.
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals, target, value):
locals[target] = value
@@ -579,7 +574,7 @@ class BuiltinListSplit(BuiltinFormatterFunction):
name = 'list_split'
arg_count = 3
category = 'List manipulation'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``list_split(list_val, sep, id_prefix)`` -- splits ``list_val`` into separate
values using ``sep``, then assigns the values to local variables named
@@ -597,7 +592,6 @@ is equivalent to:
var_2 = 'foo
[/CODE]
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals, list_val, sep, id_prefix):
l = [v.strip() for v in list_val.split(sep)]
@@ -611,13 +605,12 @@ class BuiltinPrint(BuiltinFormatterFunction):
name = 'print'
arg_count = -1
category = 'Other'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``print(a [, b]*)`` -- prints the arguments to standard output. Unless you start
calibre from the command line (``calibre-debug -g``), the output will go into a
black hole. The ``print`` function always returns its first argument.
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals, *args):
print(args)
@@ -628,11 +621,10 @@ class BuiltinField(BuiltinFormatterFunction):
name = 'field'
arg_count = 1
category = 'Get values from metadata'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``field(lookup_name)`` -- returns the value of the metadata field with lookup name ``lookup_name``.
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals, name):
return formatter.get_value(name, [], kwargs)
@@ -642,7 +634,7 @@ class BuiltinRawField(BuiltinFormatterFunction):
name = 'raw_field'
arg_count = -1
category = 'Get values from metadata'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``raw_field(lookup_name [, optional_default])`` -- returns the metadata field
named by ``lookup_name`` without applying any formatting. It evaluates and
@@ -650,7 +642,6 @@ returns the optional second argument ``optional_default`` if the field's value
is undefined (``None``). The ``$$`` prefix can be used instead of the function,
as in ``$$pubdate``.
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals, name, default=None):
res = getattr(mi, name, None)
@@ -668,13 +659,12 @@ class BuiltinRawList(BuiltinFormatterFunction):
name = 'raw_list'
arg_count = 2
category = 'Get values from metadata'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``raw_list(lookup_name, separator)`` -- returns the metadata list named by
``lookup_name`` without applying any formatting or sorting, with the items
separated by separator.
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals, name, separator):
res = getattr(mi, name, None)
@@ -687,7 +677,7 @@ class BuiltinSubstr(BuiltinFormatterFunction):
name = 'substr'
arg_count = 3
category = 'String manipulation'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``substr(str, start, end)`` -- returns the ``start``'th through the ``end``'th
characters of ``str``. The first character in ``str`` is the zero'th character.
@@ -696,7 +686,6 @@ right. If ``end`` is zero, then it indicates the last character. For example,
``substr('12345', 1, 0)`` returns ``'2345'``, and ``substr('12345', 1, -1)``
returns ``'234'``.
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals, str_, start_, end_):
return str_[int(start_): len(str_) if int(end_) == 0 else int(end_)]
@@ -706,14 +695,13 @@ class BuiltinLookup(BuiltinFormatterFunction):
name = 'lookup'
arg_count = -1
category = 'Iterating over values'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``lookup(value, [ pattern, key, ]* else_key)`` -- The patterns will be checked against
the value in order. If a pattern matches then the value of the field named by
``key`` is returned. If no pattern matches then the value of the field named by
``else_key`` is returned. See also the ``switch()`` function.
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals, val, *args):
if len(args) == 2: # here for backwards compatibility
@@ -736,12 +724,11 @@ class BuiltinTest(BuiltinFormatterFunction):
name = 'test'
arg_count = 3
category = 'If-then-else'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``test(value, text if not empty, text if empty)`` -- return ``text if not empty`` if
the value is not empty, otherwise return ``text if empty``.
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals, val, value_if_set, value_not_set):
if val:
@@ -754,13 +741,12 @@ class BuiltinContains(BuiltinFormatterFunction):
name = 'contains'
arg_count = 4
category = 'If-then-else'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``contains(value, pattern, text if match, text if not match)`` -- checks if the value
is matched by the regular expression ``pattern``. Returns ``text if match`` if
the pattern matches the value, otherwise returns ``text if no match``.
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals,
val, test, value_if_present, value_if_not):
@@ -774,7 +760,7 @@ class BuiltinSwitch(BuiltinFormatterFunction):
name = 'switch'
arg_count = -1
category = 'Iterating over values'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``switch(value, [pattern, value,]+ else_value)`` -- for each ``pattern, value`` pair,
checks if the value matches the regular expression ``pattern`` and if so returns
@@ -782,7 +768,6 @@ the associated ``value``. If no ``pattern`` matches, then ``else_value`` is
returned. You can have as many ``pattern, value`` pairs as you wish. The first
match is returned.
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals, val, *args):
if (len(args) % 2) != 1:
@@ -800,7 +785,7 @@ class BuiltinSwitchIf(BuiltinFormatterFunction):
name = 'switch_if'
arg_count = -1
category = 'Iterating over values'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``switch_if([test_expression, value_expression,]+ else_expression)`` -- for each
``test_expression, value_expression`` pair, checks if ``test_expression`` is
@@ -808,7 +793,6 @@ True (non-empty) and if so returns the result of ``value_expression``. If no
``test_expression`` is True then the result of ``else_expression`` is returned.
You can have as many ``test_expression, value_expression`` pairs as you want.
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals, *args):
if (len(args) % 2) != 1:
@@ -828,7 +812,7 @@ class BuiltinStrcatMax(BuiltinFormatterFunction):
name = 'strcat_max'
arg_count = -1
category = 'String manipulation'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``strcat_max(max, string1 [, prefix2, string2]*)`` -- Returns a string formed by
concatenating the arguments. The returned value is initialized to ``string1``.
@@ -837,7 +821,6 @@ long as the resulting string length is less than ``max``. Prefixes can be empty.
Returns ``string1`` even if ``string1`` is longer than ``max``. You can pass as
many ``prefix, string`` pairs as you wish.
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals, *args):
if len(args) < 2:
@@ -866,7 +849,7 @@ class BuiltinInList(BuiltinFormatterFunction):
name = 'list_contains'
arg_count = -1
category = 'List lookup'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``list_contains(value, separator, [ pattern, found_val, ]* not_found_val)`` -- interpret the
value as a list of items separated by ``separator``, checking the ``pattern``
@@ -902,7 +885,7 @@ class BuiltinStrInList(BuiltinFormatterFunction):
name = 'str_in_list'
arg_count = -1
category = 'List lookup'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``str_in_list(value, separator, [ string, found_val, ]+ not_found_val)`` -- interpret
the value as a list of items separated by ``separator`` then compare ``string``
@@ -915,7 +898,6 @@ depending on string's value. If none of the strings match then
``not_found_value`` is returned. The strings are checked in order. The first
match is returned.
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals, val, sep, *args):
if (len(args) % 2) != 1:
@@ -940,7 +922,7 @@ class BuiltinIdentifierInList(BuiltinFormatterFunction):
name = 'identifier_in_list'
arg_count = -1
category = 'List lookup'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``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
@@ -953,7 +935,6 @@ 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 (``''``).
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals, val, ident, *args):
if len(args) == 0:
@@ -982,7 +963,7 @@ class BuiltinRe(BuiltinFormatterFunction):
name = 're'
arg_count = 3
category = 'String manipulation'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``re(value, pattern, replacement)`` -- return the value after applying the regular
expression. All instances of ``pattern`` in the value are replaced with
@@ -990,7 +971,6 @@ expression. All instances of ``pattern`` in the value are replaced with
[URL href="https://docs.python.org/3/library/re.html"]Python regular
expressions[/URL].
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals, val, pattern, replacement):
return re.sub(pattern, replacement, val, flags=re.I)
@@ -1000,7 +980,7 @@ class BuiltinReGroup(BuiltinFormatterFunction):
name = 're_group'
arg_count = -1
category = 'String manipulation'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``re_group(value, pattern [, template_for_group]*)`` -- return a string made by
applying the regular expression pattern to ``value`` and replacing each matched
@@ -1013,7 +993,6 @@ The following example looks for a series with more than one word and uppercases
program: re_group(field('series'), "(\S* )(.*)", "{$:uppercase()}", "{$}")'}
[/CODE]
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals, val, pattern, *args):
from calibre.utils.formatter import EvalFormatter
@@ -1039,13 +1018,12 @@ class BuiltinSwapAroundComma(BuiltinFormatterFunction):
name = 'swap_around_comma'
arg_count = 1
category = 'String manipulation'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``swap_around_comma(value)`` -- given a value of the form ``B, A``, return ``A B``.
This is most useful for converting names in LN, FN format to FN LN. If there is
no comma in the value then the function returns the value unchanged.
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals, val):
return re.sub(r'^(.*?),\s*(.*$)', r'\2 \1', val, flags=re.I).strip()
@@ -1055,12 +1033,11 @@ class BuiltinIfempty(BuiltinFormatterFunction):
name = 'ifempty'
arg_count = 2
category = 'If-then-else'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``ifempty(value, text if empty)`` -- if the value is not empty then return that value,
otherwise return ``text if empty``.
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals, val, value_if_empty):
if val:
@@ -1073,7 +1050,7 @@ class BuiltinShorten(BuiltinFormatterFunction):
name = 'shorten'
arg_count = 4
category = 'String manipulation'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``shorten(value, left chars, middle text, right chars)`` -- Return a shortened version
of the value, consisting of ``left chars`` characters from the beginning of the
@@ -1090,7 +1067,6 @@ length is less than ``left chars`` + ``right chars`` + the length of ``middle te
then the value will be returned unchanged. For example, the title `The
Dome` would not be changed.
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals,
val, leading, center_string, trailing):
@@ -1108,7 +1084,7 @@ class BuiltinCount(BuiltinFormatterFunction):
category = 'List manipulation'
aliases = ['count']
- raw_doc = (
+ __doc__ = doc = _(
r'''
``list_count(value, separator)`` -- interprets the value as a list of items separated by
``separator`` and returns the number of items in the list. Most lists use
@@ -1118,7 +1094,6 @@ Examples: ``{tags:list_count(,)}``, ``{authors:list_count(&)}``.
Aliases: ``count()``, ``list_count()``
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals, val, sep):
return str(len([v for v in val.split(sep) if v]))
@@ -1130,7 +1105,7 @@ class BuiltinListCountMatching(BuiltinFormatterFunction):
category = 'List manipulation'
aliases = ['count_matching']
- raw_doc = (
+ __doc__ = doc = _(
r'''
``list_count_matching(list, pattern, separator)`` -- interprets ``list`` as a
list of items separated by ``separator``, returning the number of items in the
@@ -1138,7 +1113,6 @@ list that match the regular expression ``pattern``.
Aliases: ``list_count_matching()``, ``count_matching()``
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals, list_, pattern, sep):
res = 0
@@ -1152,7 +1126,7 @@ class BuiltinListitem(BuiltinFormatterFunction):
name = 'list_item'
arg_count = 3
category = 'List lookup'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``list_item(value, index, separator)`` -- interpret the value as a list of items
separated by ``separator``, returning the 'index'th item. The first item is
@@ -1161,7 +1135,6 @@ number zero. The last item has the index ``-1`` as in
string is returned. The separator has the same meaning as in the count function,
usually comma but is ampersand for author-like lists.
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals, val, index, sep):
if not val:
@@ -1178,7 +1151,7 @@ class BuiltinSelect(BuiltinFormatterFunction):
name = 'select'
arg_count = 2
category = 'List lookup'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``select(value, key)`` -- interpret the value as a comma-separated list of items with
each item having the form ``id:value`` (the calibre ``identifier`` format). The
@@ -1186,7 +1159,6 @@ function finds the first pair with the id equal to key and returns the
corresponding value. If no id matches then the function returns the empty
string.
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals, val, key):
if not val:
@@ -1203,7 +1175,7 @@ class BuiltinApproximateFormats(BuiltinFormatterFunction):
name = 'approximate_formats'
arg_count = 0
category = 'Get values from metadata'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``approximate_formats()`` -- return a comma-separated list of formats associated
with the book. Because the list comes from calibre's database instead of the
@@ -1217,7 +1189,6 @@ or send-to-device templates then you must make a custom "Column built from
other columns", use the function in that column's template, and use that
column's value in your save/send templates.
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals):
if hasattr(mi, '_proxy_metadata'):
@@ -1233,7 +1204,7 @@ class BuiltinFormatsModtimes(BuiltinFormatterFunction):
name = 'formats_modtimes'
arg_count = 1
category = 'Get values from metadata'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``formats_modtimes(date_format_string)`` -- return a comma-separated list of
colon-separated items ``FMT:DATE`` representing modification times for the
@@ -1258,14 +1229,13 @@ class BuiltinFormatsSizes(BuiltinFormatterFunction):
name = 'formats_sizes'
arg_count = 0
category = 'Get values from metadata'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``formats_sizes()`` -- return a comma-separated list of colon-separated
``FMT:SIZE`` items giving the sizes of the formats of a book in bytes. You can
use the ``select()`` function to get the size for a specific format. Note that
format names are always uppercase, as in EPUB.
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals):
fmt_data = mi.get('format_metadata', {})
@@ -1279,14 +1249,13 @@ class BuiltinFormatsPaths(BuiltinFormatterFunction):
name = 'formats_paths'
arg_count = 0
category = 'Get values from metadata'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``formats_paths()`` -- return a comma-separated list of colon-separated items
``FMT:PATH`` giving the full path to the formats of a book. You can use the
``select()`` function to get the path for a specific format. Note that format names
are always uppercase, as in EPUB.
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals):
fmt_data = mi.get('format_metadata', {})
@@ -1300,12 +1269,11 @@ class BuiltinHumanReadable(BuiltinFormatterFunction):
name = 'human_readable'
arg_count = 1
category = 'Formatting values'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``human_readable(value)`` -- expects the value to be a number and returns a string
representing that number in KB, MB, GB, etc.
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals, val):
try:
@@ -1318,7 +1286,7 @@ class BuiltinFormatNumber(BuiltinFormatterFunction):
name = 'format_number'
arg_count = 2
category = 'Formatting values'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``format_number(value, template)`` -- interprets the value as a number and formats that
number using a Python formatting template such as ``{0:5.2f}`` or ``{0:,d}`` or
@@ -1329,7 +1297,6 @@ language and the [URL href="https://docs.python.org/3/library/string.html#format
Python documentation[/URL]
for more examples. Returns the empty string if formatting fails.
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals, val, template):
if val == '' or val == 'None':
@@ -1357,7 +1324,7 @@ class BuiltinSublist(BuiltinFormatterFunction):
name = 'sublist'
arg_count = 4
category = 'List manipulation'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``sublist(value, start_index, end_index, separator)`` -- interpret the value as a
list of items separated by ``separator``, returning a new list made from the
@@ -1372,7 +1339,6 @@ Examples assuming that the tags column (which is comma-separated) contains "A, B
[*]``{tags:sublist(0,-1,\,)}`` returns "A, B"
[/LIST]
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals, val, start_index, end_index, sep):
if not val:
@@ -1397,7 +1363,7 @@ class BuiltinSubitems(BuiltinFormatterFunction):
name = 'subitems'
arg_count = 3
category = 'List manipulation'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``subitems(value, start_index, end_index)`` -- This function breaks apart lists of
tag-like hierarchical items such as genres. It interprets the value as a comma-
@@ -1455,7 +1421,7 @@ class BuiltinFormatDate(BuiltinFormatterFunction):
name = 'format_date'
arg_count = 2
category = 'Formatting values'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``format_date(value, format_string)`` -- format the value, which must be a date
string, using the format_string, returning a string. It is best if the date is
@@ -1496,7 +1462,6 @@ You might get unexpected results if the date you are formatting contains
localized month names, which can happen if you changed the date format to
contain ``MMMM``. Using ``format_date_field()`` avoids this problem.
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals, val, format_string):
if not val or val == 'None':
@@ -1520,7 +1485,7 @@ class BuiltinFormatDateField(BuiltinFormatterFunction):
name = 'format_date_field'
arg_count = 2
category = 'Formatting values'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``format_date_field(field_name, format_string)`` -- format the value in the
field ``field_name``, which must be the lookup name of a date field, either
@@ -1534,7 +1499,6 @@ format_date_field('pubdate', 'yyyy.MM.dd')
format_date_field('#date_read', 'MMM dd, yyyy')
[/CODE]
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals, field, format_string):
try:
@@ -1567,11 +1531,10 @@ class BuiltinUppercase(BuiltinFormatterFunction):
name = 'uppercase'
arg_count = 1
category = 'String case changes'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``uppercase(value)`` -- returns the value in upper case.
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals, val):
return val.upper()
@@ -1581,11 +1544,10 @@ class BuiltinLowercase(BuiltinFormatterFunction):
name = 'lowercase'
arg_count = 1
category = 'String case changes'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``lowercase(value)`` -- returns the value in lower case.
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals, val):
return val.lower()
@@ -1595,11 +1557,10 @@ class BuiltinTitlecase(BuiltinFormatterFunction):
name = 'titlecase'
arg_count = 1
category = 'String case changes'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``titlecase(value)`` -- returns the value in title case.
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals, val):
return titlecase(val)
@@ -1609,11 +1570,10 @@ class BuiltinCapitalize(BuiltinFormatterFunction):
name = 'capitalize'
arg_count = 1
category = 'String case changes'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``capitalize(value)`` -- returns the value with the first letter in upper case and the rest lower case.
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals, val):
return capitalize(val)
@@ -1623,7 +1583,7 @@ class BuiltinBooksize(BuiltinFormatterFunction):
name = 'booksize'
arg_count = 0
category = 'Get values from metadata'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``booksize()`` -- returns the value of the calibre ``size`` field. Returns '' if the book has no formats.
@@ -1632,7 +1592,6 @@ or send-to-device templates then you must make a custom "Column built from
other columns", use the function in that column's template, and use that
column's value in your save/send templates
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals):
if hasattr(mi, '_proxy_metadata'):
@@ -1651,7 +1610,7 @@ class BuiltinOndevice(BuiltinFormatterFunction):
name = 'ondevice'
arg_count = 0
category = 'Get values from metadata'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``ondevice()`` -- return the string ``'Yes'`` if ``ondevice`` is set, otherwise
return the empty string. This function works only in the GUI. If you want to use
@@ -1659,7 +1618,6 @@ this value in save-to-disk or send-to-device templates then you must make a
custom "Column built from other columns", use the function in that column\'s
template, and use that column\'s value in your save/send templates.
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals):
if hasattr(mi, '_proxy_metadata'):
@@ -1673,12 +1631,11 @@ class BuiltinAnnotationCount(BuiltinFormatterFunction):
name = 'annotation_count'
arg_count = 0
category = 'Get values from metadata'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``annotation_count()`` -- return the total number of annotations of all types
attached to the current book. This function works only in the GUI.
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals):
c = self.get_database(mi).new_api.annotation_count_for_book(mi.id)
@@ -1689,14 +1646,13 @@ class BuiltinIsMarked(BuiltinFormatterFunction):
name = 'is_marked'
arg_count = 0
category = 'Get values from metadata'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``is_marked()`` -- check whether the book is `marked` in calibre. If it is then
return the value of the mark, either ``'true'`` (lower case) or a comma-separated
list of named marks. Returns ``''`` (the empty string) if the book is
not marked. This function works only in the GUI.
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals):
c = self.get_database(mi).data.get_marked(mi.id)
@@ -1707,11 +1663,10 @@ class BuiltinSeriesSort(BuiltinFormatterFunction):
name = 'series_sort'
arg_count = 0
category = 'Get values from metadata'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``series_sort()`` -- returns the series sort value.
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals):
if mi.series:
@@ -1725,11 +1680,10 @@ class BuiltinHasCover(BuiltinFormatterFunction):
name = 'has_cover'
arg_count = 0
category = 'Get values from metadata'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``has_cover()`` -- return ``'Yes'`` if the book has a cover, otherwise the empty string.
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals):
if mi.has_cover:
@@ -1741,13 +1695,12 @@ class BuiltinFirstNonEmpty(BuiltinFormatterFunction):
name = 'first_non_empty'
arg_count = -1
category = 'Iterating over values'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``first_non_empty(value [, value]*)`` -- returns the first ``value`` that is not
empty. If all values are empty, then the empty string is returned. You can have
as many values as you want.
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals, *args):
i = 0
@@ -1762,7 +1715,7 @@ class BuiltinAnd(BuiltinFormatterFunction):
name = 'and'
arg_count = -1
category = 'Boolean'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``and(value [, value]*)`` -- returns the string ``'1'`` if all values are not empty,
otherwise returns the empty string. You can have as many values as you want. In
@@ -1771,7 +1724,6 @@ not to replace ``and()`` with ``&&`` is when short-circuiting can change the res
because of side effects. For example, ``and(a='',b=5)`` will always do both
assignments, where the ``&&`` operator won't do the second.
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals, *args):
i = 0
@@ -1786,7 +1738,7 @@ class BuiltinOr(BuiltinFormatterFunction):
name = 'or'
arg_count = -1
category = 'Boolean'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``or(value [, value]*)`` -- returns the string ``'1'`` if any value is not
empty, otherwise returns the empty string. You can have as many values as you
@@ -1794,7 +1746,6 @@ want. This function can usually be replaced by the ``||`` operator. A reason it
cannot be replaced is if short-circuiting will change the results because of
side effects.
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals, *args):
i = 0
@@ -1809,13 +1760,12 @@ class BuiltinNot(BuiltinFormatterFunction):
name = 'not'
arg_count = 1
category = 'Boolean'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``not(value)`` -- returns the string ``'1'`` if the value is empty, otherwise
returns the empty string. This function can usually be replaced with the unary
not (``!``) operator.
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals, val):
return '' if val else '1'
@@ -1825,7 +1775,7 @@ class BuiltinListJoin(BuiltinFormatterFunction):
name = 'list_join'
arg_count = -1
category = 'List manipulation'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``list_join(with_separator, list1, separator1 [, list2, separator2]*)`` --
return a list made by joining the items in the source lists (``list1`` etc)
@@ -1857,7 +1807,6 @@ program:
list_join('#@#', $authors, '&', list_re($#genre, ',', '^(.).*$', 'Genre: \1'), ',')
[/CODE]
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals, with_separator, *args):
if len(args) % 2 != 0:
@@ -1879,7 +1828,7 @@ class BuiltinListUnion(BuiltinFormatterFunction):
name = 'list_union'
arg_count = 3
category = 'List manipulation'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``list_union(list1, list2, separator)`` -- return a list made by merging the
items in ``list1`` and ``list2``, removing duplicate items using a case-insensitive
@@ -1901,7 +1850,7 @@ class BuiltinRange(BuiltinFormatterFunction):
name = 'range'
arg_count = -1
category = 'List manipulation'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``range(start, stop, step, limit)`` -- returns a list of numbers generated by
looping over the range specified by the parameters start, stop, and step, with a
@@ -1926,7 +1875,6 @@ range(1, 5, 2, 5) -> '1, 3'
range(1, 5, 2, 1) -> error(limit exceeded)
[/CODE]
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals, *args):
limit_val = 1000
@@ -1955,14 +1903,13 @@ class BuiltinListRemoveDuplicates(BuiltinFormatterFunction):
name = 'list_remove_duplicates'
arg_count = 2
category = 'List manipulation'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``list_remove_duplicates(list, separator)`` -- return a list made by removing
duplicate items in ``list``. If items differ only in case then the last is
returned. The items in ``list`` are separated by ``separator``, as are the items
in the returned list.
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals, list_, separator):
res = {icu_lower(l.strip()): l.strip() for l in list_.split(separator) if l.strip()}
@@ -1975,14 +1922,13 @@ class BuiltinListDifference(BuiltinFormatterFunction):
name = 'list_difference'
arg_count = 3
category = 'List manipulation'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``list_difference(list1, list2, separator)`` -- return a list made by removing
from ``list1`` any item found in ``list2`` using a case-insensitive comparison.
The items in ``list1`` and ``list2`` are separated by separator, as are the
items in the returned list.
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals, list1, list2, separator):
l1 = [l.strip() for l in list1.split(separator) if l.strip()]
@@ -2001,14 +1947,13 @@ class BuiltinListIntersection(BuiltinFormatterFunction):
name = 'list_intersection'
arg_count = 3
category = 'List manipulation'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``list_intersection(list1, list2, separator)`` -- return a list made by removing
from ``list1`` any item not found in ``list2``, using a case-insensitive
comparison. The items in ``list1`` and ``list2`` are separated by separator, as
are the items in the returned list.
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals, list1, list2, separator):
l1 = [l.strip() for l in list1.split(separator) if l.strip()]
@@ -2027,14 +1972,13 @@ class BuiltinListSort(BuiltinFormatterFunction):
name = 'list_sort'
arg_count = 3
category = 'List manipulation'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``list_sort(list, direction, separator)`` -- return ``list`` sorted using a
case-insensitive lexical sort. If ``direction`` is zero (number or character),
``list`` is sorted ascending, otherwise descending. The list items are separated
by ``separator``, as are the items in the returned list.
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals, list1, direction, separator):
res = [l.strip() for l in list1.split(separator) if l.strip()]
@@ -2047,7 +1991,7 @@ class BuiltinListEquals(BuiltinFormatterFunction):
name = 'list_equals'
arg_count = 6
category = 'List manipulation'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``list_equals(list1, sep1, list2, sep2, yes_val, no_val)`` -- return ``yes_val``
if ``list1`` and ``list2`` contain the same items, otherwise return ``no_val``.
@@ -2055,7 +1999,6 @@ The items are determined by splitting each list using the appropriate separator
character (``sep1`` or ``sep2``). The order of items in the lists is not
relevant. The comparison is case-insensitive.
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals, list1, sep1, list2, sep2, yes_val, no_val):
s1 = {icu_lower(l.strip()) for l in list1.split(sep1) if l.strip()}
@@ -2069,7 +2012,7 @@ class BuiltinListRe(BuiltinFormatterFunction):
name = 'list_re'
arg_count = 4
category = 'List manipulation'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``list_re(src_list, separator, include_re, opt_replace)`` -- Construct a list by
first separating ``src_list`` into items using the ``separator`` character. For
@@ -2077,7 +2020,6 @@ each item in the list, check if it matches ``include_re``. If it does then add
it to the list to be returned. If ``opt_replace`` is not the empty string then
apply the replacement before adding the item to the returned list.
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals, src_list, separator, include_re, opt_replace):
l = [l.strip() for l in src_list.split(separator) if l.strip()]
@@ -2098,13 +2040,12 @@ class BuiltinListReGroup(BuiltinFormatterFunction):
name = 'list_re_group'
arg_count = -1
category = 'List manipulation'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``list_re_group(src_list, separator, include_re, search_re [,template_for_group]*)``
-- Like list_re except replacements are not optional. It
uses ``re_group(item, search_re, template ...)`` when doing the replacements.
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals, src_list, separator, include_re,
search_re, *args):
@@ -2141,14 +2082,13 @@ class BuiltinToday(BuiltinFormatterFunction):
name = 'today'
arg_count = 0
category = 'Date functions'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``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 [URL href="https://en.wikipedia.org/wiki/ISO_8601"]ISO[/URL]
date/time format.
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals):
return format_date(now(), 'iso')
@@ -2158,14 +2098,13 @@ class BuiltinDaysBetween(BuiltinFormatterFunction):
name = 'days_between'
arg_count = 2
category = 'Date functions'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``days_between(date1, date2)`` -- return the number of days between ``date1``
and ``date2``. The number is positive if ``date1`` is greater than ``date2``,
otherwise negative. If either ``date1`` or ``date2`` are not dates, the function
returns the empty string.
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals, date1, date2):
try:
@@ -2185,7 +2124,7 @@ class BuiltinDateArithmetic(BuiltinFormatterFunction):
name = 'date_arithmetic'
arg_count = -1
category = 'Date functions'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``date_arithmetic(date, calc_spec, fmt)`` -- Calculate a new date from ``date``
using ``calc_spec``. Return the new date formatted according to optional
@@ -2237,7 +2176,7 @@ class BuiltinLanguageStrings(BuiltinFormatterFunction):
name = 'language_strings'
arg_count = 2
category = 'Get values from metadata'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``language_strings(localize)`` -- return the
language names for the language codes
@@ -2247,7 +2186,6 @@ passed in as the value. Example: ``{languages:language_strings()}``.
If ``localize`` is zero, return the strings in English. If ``localize`` is not zero,
return the strings in the language of the current locale. ``Lang_codes`` is a comma-separated list.
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals, lang_codes, localize):
retval = []
@@ -2265,14 +2203,13 @@ class BuiltinLanguageCodes(BuiltinFormatterFunction):
name = 'language_codes'
arg_count = 1
category = 'Get values from metadata'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``language_codes(lang_strings)`` -- return the
[URL href="https://www.loc.gov/standards/iso639-2/php/code_list.php"]language codes[/URL] for the language
names passed in ``lang_strings``. The strings must be in the language of the
current locale. ``Lang_strings`` is a comma-separated list.
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals, lang_strings):
retval = []
@@ -2290,11 +2227,10 @@ class BuiltinCurrentLibraryName(BuiltinFormatterFunction):
name = 'current_library_name'
arg_count = 0
category = 'Get values from metadata'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``current_library_name()`` -- return the last name on the path to the current calibre library.
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals):
from calibre.library import current_library_name
@@ -2305,12 +2241,11 @@ class BuiltinCurrentLibraryPath(BuiltinFormatterFunction):
name = 'current_library_path'
arg_count = 0
category = 'Get values from metadata'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``current_library_path()`` -- return the full path to the current calibre
library.
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals):
from calibre.library import current_library_path
@@ -2321,7 +2256,7 @@ class BuiltinFinishFormatting(BuiltinFormatterFunction):
name = 'finish_formatting'
arg_count = 4
category = 'Formatting values'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``finish_formatting(val, format, prefix, suffix)`` -- apply the ``format``, ``prefix``, and
``suffix`` to a value in the same way as done in a template like
@@ -2346,7 +2281,6 @@ program:
)
[/CODE]
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals_, val, fmt, prefix, suffix):
if not val:
@@ -2358,7 +2292,7 @@ class BuiltinVirtualLibraries(BuiltinFormatterFunction):
name = 'virtual_libraries'
arg_count = 0
category = 'Get values from metadata'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``virtual_libraries()`` -- return a comma-separated list of Virtual libraries that
contain this book. This function works only in the GUI. If you want to use these
@@ -2366,7 +2300,6 @@ values in save-to-disk or send-to-device templates then you must make a custom
"Column built from other columns", use the function in that column's template,
and use that column's value in your save/send templates.
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals_):
db = self.get_database(mi)
@@ -2381,7 +2314,7 @@ class BuiltinCurrentVirtualLibraryName(BuiltinFormatterFunction):
name = 'current_virtual_library_name'
arg_count = 0
category = 'Get values from metadata'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``current_virtual_library_name()`` -- return the name of the current
virtual library if there is one, otherwise the empty string. Library name case
@@ -2391,7 +2324,6 @@ program: current_virtual_library_name()
[/CODE]
This function works only in the GUI.
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals):
return self.get_database(mi).data.get_base_restriction_name()
@@ -2401,7 +2333,7 @@ class BuiltinUserCategories(BuiltinFormatterFunction):
name = 'user_categories'
arg_count = 0
category = 'Get values from metadata'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``user_categories()`` -- return a comma-separated list of the user categories that
contain this book. This function works only in the GUI. If you want to use these
@@ -2409,7 +2341,6 @@ values in save-to-disk or send-to-device templates then you must make a custom
`Column built from other columns`, use the function in that column's template,
and use that column's value in your save/send templates
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals_):
if hasattr(mi, '_proxy_metadata'):
@@ -2423,14 +2354,13 @@ class BuiltinTransliterate(BuiltinFormatterFunction):
name = 'transliterate'
arg_count = 1
category = 'String manipulation'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``transliterate(value)`` -- Return a string in a latin alphabet formed by
approximating the sound of the words in the source field. For example, if the
source field is ``Фёдор Миха́йлович Достоевский`` this function returns ``Fiodor
Mikhailovich Dostoievskii``.
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals, source):
from calibre.utils.filenames import ascii_text
@@ -2441,7 +2371,7 @@ class BuiltinGetLink(BuiltinFormatterFunction):
name = 'get_link'
arg_count = 2
category = 'Template database functions'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``get_link(field_name, field_value)`` -- fetch the link for field ``field_name``
with value ``field_value``. If there is no attached link, return the empty
@@ -2466,7 +2396,6 @@ ans
[/CODE]
[/LIST]
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals, field_name, field_value):
db = self.get_database(mi).new_api
@@ -2485,7 +2414,7 @@ class BuiltinAuthorLinks(BuiltinFormatterFunction):
name = 'author_links'
arg_count = 2
category = 'Get values from metadata'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``author_links(val_separator, pair_separator)`` -- returns a string containing a
list of authors and those authors' link values in the form:
@@ -2498,7 +2427,6 @@ with no added spaces. Assuming the ``val_separator`` is a colon,
choose separators that do not occur in author names or links. An author
is included even if the author link is empty.
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals, val_sep, pair_sep):
if hasattr(mi, '_proxy_metadata'):
@@ -2517,7 +2445,7 @@ class BuiltinAuthorSorts(BuiltinFormatterFunction):
name = 'author_sorts'
arg_count = 1
category = 'Get values from metadata'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``author_sorts(val_separator)`` -- returns a string containing a list of
author's sort values for the authors of the book. The sort is the one in the
@@ -2527,7 +2455,6 @@ etc. with no added spaces. The author sort values in this list are in the same
order as the authors of the book. If you want spaces around ``val_separator``
then include them in the ``val_separator`` string.
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals, val_sep):
sort_data = mi.author_sort_map
@@ -2541,7 +2468,7 @@ class BuiltinConnectedDeviceName(BuiltinFormatterFunction):
name = 'connected_device_name'
arg_count = 1
category = 'Get values from metadata'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``connected_device_name(storage_location_key)`` -- if a device is connected then
return the device name, otherwise return the empty string. Each storage location
@@ -2579,7 +2506,7 @@ class BuiltinConnectedDeviceUUID(BuiltinFormatterFunction):
name = 'connected_device_uuid'
arg_count = 1
category = 'Get values from metadata'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``connected_device_uuid(storage_location_key)`` -- if a device is connected then
return the device uuid (unique id), otherwise return the empty string. Each
@@ -2587,7 +2514,6 @@ storage location on a device has a different uuid. The ``storage_location_key``
location names are ``'main'``, ``'carda'`` and ``'cardb'``. This function works
only in the GUI.
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals, storage_location):
# We can't use get_database() here because we need the device manager.
@@ -2618,7 +2544,7 @@ class BuiltinCheckYesNo(BuiltinFormatterFunction):
name = 'check_yes_no'
arg_count = 4
category = 'If-then-else'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``check_yes_no(field_name, is_undefined, is_false, is_true)`` -- checks if the
value of the yes/no field named by the lookup name ``field_name`` is one of the
@@ -2632,7 +2558,6 @@ Example: ``check_yes_no("#bool", 1, 0, 1)`` returns ``'Yes'`` if the yes/no fiel
More than one of ``is_undefined``, ``is_false``, or ``is_true`` can be set to 1.
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals, field, is_undefined, is_false, is_true):
# 'field' is a lookup name, not a value
@@ -2656,14 +2581,13 @@ class BuiltinRatingToStars(BuiltinFormatterFunction):
name = 'rating_to_stars'
arg_count = 2
category = 'Formatting values'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``rating_to_stars(value, use_half_stars)`` -- Returns the value as string of star
(``★``) characters. The value must be a number between 0 and 5. Set
use_half_stars to 1 if you want half star characters for fractional numbers
available with custom ratings columns.
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals, value, use_half_stars):
if not value:
@@ -2683,7 +2607,7 @@ class BuiltinSwapAroundArticles(BuiltinFormatterFunction):
name = 'swap_around_articles'
arg_count = 2
category = 'String manipulation'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``swap_around_articles(value, separator)`` -- returns the value with articles moved to
the end. The value can be a list, in which case each item in the list is
@@ -2691,7 +2615,6 @@ processed. If the value is a list then you must provide the ``separator``. If no
``separator`` is provided then the value is treated as being a single value, not
a list. The `articles` are those used by calibre to generate the ``title_sort``.
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals, val, separator):
if not val:
@@ -2711,7 +2634,7 @@ class BuiltinArguments(BuiltinFormatterFunction):
name = 'arguments'
arg_count = -1
category = 'Other'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``arguments(id[=expression] [, id[=expression]]*)`` -- Used in a stored
template to retrieve the arguments passed in the call. It both declares and
@@ -2722,7 +2645,6 @@ argument is not provided in the call then ``arguments()`` assigns that variable
the provided default value. If there is no default value then the variable
is set to the empty string.
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals, *args):
# The arguments function is implemented in-line in the formatter
@@ -2733,7 +2655,7 @@ class BuiltinGlobals(BuiltinFormatterFunction):
name = 'globals'
arg_count = -1
category = 'Other'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``globals(id[=expression] [, id[=expression]]*)`` -- Retrieves "global variables"
that can be passed into the formatter. The name ``id`` is the name of the global
@@ -2743,7 +2665,6 @@ provided in the globals then it assigns that variable the provided default
value. If there is no default value then the variable is set to the empty
string.)
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals, *args):
# The globals function is implemented in-line in the formatter
@@ -2754,14 +2675,13 @@ class BuiltinSetGlobals(BuiltinFormatterFunction):
name = 'set_globals'
arg_count = -1
category = 'other'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``set_globals(id[=expression] [, id[=expression]]*)`` -- Sets `global
variables` that can be passed into the formatter. The globals are given the name
of the ``id`` passed in. The value of the ``id`` is used unless an expression is
provided.
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals, *args):
# The globals function is implemented in-line in the formatter
@@ -2772,12 +2692,11 @@ class BuiltinFieldExists(BuiltinFormatterFunction):
name = 'field_exists'
arg_count = 1
category = 'If-then-else'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``field_exists(lookup_name)`` -- checks if a field (column) with the lookup name
``lookup_name`` exists, returning ``'1'`` if so and the empty string if not.
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals, field_name):
if field_name.lower() in mi.all_field_keys():
@@ -2789,7 +2708,7 @@ class BuiltinCharacter(BuiltinFormatterFunction):
name = 'character'
arg_count = 1
category = 'String manipulation'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``character(character_name)`` -- returns the character named by character_name.
For example, ``character('newline')`` returns a newline character (``'\n'``).
@@ -2797,7 +2716,6 @@ The supported character names are ``newline``, ``return``, ``tab``, and
``backslash``. This function is used to put these characters into the output
of templates.
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals, character_name):
# The globals function is implemented in-line in the formatter
@@ -2808,12 +2726,11 @@ class BuiltinToHex(BuiltinFormatterFunction):
name = 'to_hex'
arg_count = 1
category = 'String manipulation'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``to_hex(val)`` -- returns the string ``val`` encoded into hex. This is useful
when constructing calibre URLs.
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals, val):
return val.encode().hex()
@@ -2823,7 +2740,7 @@ class BuiltinUrlsFromIdentifiers(BuiltinFormatterFunction):
name = 'urls_from_identifiers'
arg_count = 2
category = 'Formatting values'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``urls_from_identifiers(identifiers, sort_results)`` -- given a comma-separated
list of ``identifiers``, where an ``identifier`` is a colon-separated pair of
@@ -2833,7 +2750,6 @@ generated from the identifiers. The list not sorted if sort_results is ``0``
name. The URLs are generated in the same way as the built-in identifiers column
when shown in Book Details.
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals, identifiers, sort_results):
from calibre.ebooks.metadata.sources.identify import urls_from_identifiers
@@ -2861,7 +2777,7 @@ class BuiltinBookCount(BuiltinFormatterFunction):
name = 'book_count'
arg_count = 2
category = 'Template database functions'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``book_count(query, use_vl)`` -- returns the count of books found by searching
for ``query``. If ``use_vl`` is ``0`` (zero) then virtual libraries are ignored.
@@ -2902,7 +2818,6 @@ eliminates problems caused by the requirement to escape quotes in search
expressions.
[/LIST]
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals, query, use_vl):
from calibre.db.fields import rendering_composite_name
@@ -2921,7 +2836,7 @@ class BuiltinBookValues(BuiltinFormatterFunction):
name = 'book_values'
arg_count = 4
category = 'Template database functions'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``book_values(column, query, sep, use_vl)`` -- returns a list of the unique
values contained in the column ``column`` (a lookup name), separated by ``sep``,
@@ -2933,7 +2848,6 @@ with only one book. It cannot be used in composite columns unless the tweak
``allow_template_database_functions_in_composites`` is set to True. It can be
used only in the GUI.
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals, column, query, sep, use_vl):
from calibre.db.fields import rendering_composite_name
@@ -2961,7 +2875,7 @@ class BuiltinHasExtraFiles(BuiltinFormatterFunction):
name = 'has_extra_files'
arg_count = -1
category = 'Template database functions'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``has_extra_files([pattern])`` -- returns the count of extra files, otherwise ''
(the empty string). If the optional parameter ``pattern`` (a regular expression)
@@ -2970,7 +2884,6 @@ 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.
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals, *args):
if len(args) > 1:
@@ -2993,7 +2906,7 @@ class BuiltinExtraFileNames(BuiltinFormatterFunction):
name = 'extra_file_names'
arg_count = -1
category = 'Template database functions'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``extra_file_names(sep [, pattern])`` -- returns a ``sep``-separated list of
extra files in the book's ``data/`` folder. If the optional parameter
@@ -3002,7 +2915,6 @@ files that match ``pattern``. The pattern match is case insensitive. See also
the functions ``has_extra_files()``, ``extra_file_modtime()`` and
``extra_file_size()``. This function can be used only in the GUI.
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals, sep, *args):
if len(args) > 1:
@@ -3025,14 +2937,13 @@ class BuiltinExtraFileSize(BuiltinFormatterFunction):
name = 'extra_file_size'
arg_count = 1
category = 'Template database functions'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``extra_file_size(file_name)`` -- returns the size in bytes of the extra file
``file_name`` in the book's ``data/`` folder if it exists, otherwise ``-1``. See
also the functions ``has_extra_files()``, ``extra_file_names()`` and
``extra_file_modtime()``. This function can be used only in the GUI.
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals, file_name):
db = self.get_database(mi).new_api
@@ -3051,7 +2962,7 @@ class BuiltinExtraFileModtime(BuiltinFormatterFunction):
name = 'extra_file_modtime'
arg_count = 2
category = 'Template database functions'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``extra_file_modtime(file_name, format_string)`` -- returns the modification
time of the extra file ``file_name`` in the book's ``data/`` folder if it
@@ -3062,7 +2973,6 @@ since the epoch. See also the functions ``has_extra_files()``,
``extra_file_names()`` and ``extra_file_size()``. The epoch is OS dependent.
This function can be used only in the GUI.
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals, file_name, format_string):
db = self.get_database(mi).new_api
@@ -3084,7 +2994,7 @@ class BuiltinGetNote(BuiltinFormatterFunction):
name = 'get_note'
arg_count = 3
category = 'Template database functions'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``get_note(field_name, field_value, plain_text)`` -- fetch the note for field
'field_name' with value 'field_value'. If ``plain_text`` is empty, return the
@@ -3104,7 +3014,6 @@ program:
[/CODE]
[/LIST]
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals, field_name, field_value, plain_text):
db = self.get_database(mi).new_api
@@ -3147,7 +3056,7 @@ class BuiltinHasNote(BuiltinFormatterFunction):
name = 'has_note'
arg_count = 2
category = 'Template database functions'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``has_note(field_name, field_value)``. This function has two variants:
[LIST]
@@ -3172,7 +3081,6 @@ values in ``field_name``. Example:
list_count(has_note('authors', ''), '&') ==# list_count_field('authors')
[/CODE]
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals, field_name, field_value):
db = self.get_database(mi).new_api
@@ -3199,7 +3107,7 @@ class BuiltinIsDarkMode(BuiltinFormatterFunction):
name = 'is_dark_mode'
arg_count = 0
category = 'other'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``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
@@ -3208,7 +3116,6 @@ icon rules to choose different colors/icons according to the mode. Example:
if is_dark_mode() then 'dark.png' else 'light.png' fi
[/CODE]
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals):
try:
@@ -3223,7 +3130,7 @@ class BuiltinFieldListCount(BuiltinFormatterFunction):
name = 'list_count_field'
arg_count = 0
category = 'List manipulation'
- raw_doc = (
+ __doc__ = doc = _(
r'''
``list_count_field(lookup_name)``-- returns the count of items in the field with
the lookup name ``lookup_name``. The field must be multi-valued such as
@@ -3232,7 +3139,6 @@ is much faster than ``list_count()`` because it operates directly on calibre
data without converting it to a string first. Example:
``list_count_field('tags')``
''')
- __doc__ = doc = _(raw_doc)
def evaluate(self, formatter, kwargs, mi, locals, *args):
# The globals function is implemented in-line in the formatter