This commit is contained in:
Kovid Goyal 2021-02-25 22:14:32 +05:30
commit 65128bb530
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
3 changed files with 16 additions and 8 deletions

View File

@ -505,7 +505,8 @@ parameters can be statements (sequences of expressions). Note that the definitiv
well with test or `first_non_empty`. You can have as many values as you want. well with test or `first_non_empty`. You can have as many values as you want.
* ``print(a, b, ...)`` -- prints the arguments to standard output. Unless you start calibre from the command line (``calibre-debug -g``), * ``print(a, b, ...)`` -- prints the arguments to standard output. Unless you start calibre from the command line (``calibre-debug -g``),
the output will go to a black hole. the output will go to a black hole.
* ``raw_field(name)`` -- returns the metadata field named by name without applying any formatting. * ``raw_field(name [, optional_default]))`` -- returns the metadata field named by name without applying any formatting.
It evaluates and returns the optional second argument ``default`` if the field is undefined (``None``).
* ``raw_list(name, separator)`` -- returns the metadata list named by name without applying any formatting or sorting and with items separated by separator. * ``raw_list(name, separator)`` -- returns the metadata list named by name without applying any formatting or sorting and with items separated by separator.
* ``re_group(val, pattern, template_for_group_1, for_group_2, ...)`` -- return a string made by applying the regular expression pattern to * ``re_group(val, pattern, template_for_group_1, for_group_2, ...)`` -- return a string made by applying the regular expression pattern to
the val and replacing each matched instance with the string computed by replacing each matched group by the value returned by the corresponding the val and replacing each matched instance with the string computed by replacing each matched group by the value returned by the corresponding

View File

@ -141,10 +141,11 @@ class FieldNode(Node):
class RawFieldNode(Node): class RawFieldNode(Node):
def __init__(self, expression): def __init__(self, expression, default=None):
Node.__init__(self) Node.__init__(self)
self.node_type = self.NODE_RAW_FIELD self.node_type = self.NODE_RAW_FIELD
self.expression = expression self.expression = expression
self.default = default
class FirstNonEmptyNode(Node): class FirstNonEmptyNode(Node):
@ -460,8 +461,8 @@ class _Parser(object):
self.error(_('Missing closing parenthesis')) self.error(_('Missing closing parenthesis'))
if id_ == 'field' and len(arguments) == 1: if id_ == 'field' and len(arguments) == 1:
return FieldNode(arguments[0]) return FieldNode(arguments[0])
if id_ == 'raw_field' and len(arguments) == 1: if id_ == 'raw_field' and (len(arguments) in (1, 2)):
return RawFieldNode(arguments[0]) return RawFieldNode(*arguments)
if id_ == 'test' and len(arguments) == 3: if id_ == 'test' and len(arguments) == 3:
return IfNode(arguments[0], (arguments[1],), (arguments[2],)) return IfNode(arguments[0], (arguments[1],), (arguments[2],))
if id_ == 'first_non_empty' and len(arguments) > 0: if id_ == 'first_non_empty' and len(arguments) > 0:
@ -634,6 +635,8 @@ class _Interpreter(object):
try: try:
name = self.expr(prog.expression) name = self.expr(prog.expression)
res = getattr(self.parent_book, name, None) res = getattr(self.parent_book, name, None)
if res is None and prog.default is not None:
return self.expr(prog.default)
if res is not None: if res is not None:
if isinstance(res, list): if isinstance(res, list):
fm = self.parent_book.metadata_for_field(name) fm = self.parent_book.metadata_for_field(name)

View File

@ -455,13 +455,17 @@ class BuiltinField(BuiltinFormatterFunction):
class BuiltinRawField(BuiltinFormatterFunction): class BuiltinRawField(BuiltinFormatterFunction):
name = 'raw_field' name = 'raw_field'
arg_count = 1 arg_count = -1
category = 'Get values from metadata' category = 'Get values from metadata'
__doc__ = doc = _('raw_field(name) -- returns the metadata field named by name ' __doc__ = doc = _('raw_field(name [, optional_default]) -- returns the '
'without applying any formatting.') 'metadata field named by name without applying any formatting. '
'It evaluates and returns the optional second argument '
"'default' if the field is undefined ('None').")
def evaluate(self, formatter, kwargs, mi, locals, name): def evaluate(self, formatter, kwargs, mi, locals, name, default=None):
res = getattr(mi, name, None) res = getattr(mi, name, None)
if res is None and default is not None:
return default
if isinstance(res, list): if isinstance(res, list):
fm = mi.metadata_for_field(name) fm = mi.metadata_for_field(name)
if fm is None: if fm is None: