mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Change formatter_functions to put the program text explicitly into a string. If source is available, test that the string == the real program text
This commit is contained in:
parent
1e7c9fb2c3
commit
d7ac11d137
@ -81,13 +81,24 @@ class FormatterFunction(object):
|
|||||||
class BuiltinFormatterFunction(FormatterFunction):
|
class BuiltinFormatterFunction(FormatterFunction):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
formatter_functions.register_builtin(self)
|
formatter_functions.register_builtin(self)
|
||||||
|
try:
|
||||||
|
# strip off the first character, which is a newline
|
||||||
|
lines = self.program_text[1:]
|
||||||
|
except:
|
||||||
|
lines = ''
|
||||||
|
self.program_text = lines
|
||||||
|
|
||||||
|
# If we can get the source, check if it is the same as in the string.
|
||||||
|
# This is to give an indication during testing that the text is wrong.
|
||||||
eval_func = inspect.getmembers(self.__class__,
|
eval_func = inspect.getmembers(self.__class__,
|
||||||
lambda x: inspect.ismethod(x) and x.__name__ == 'evaluate')
|
lambda x: inspect.ismethod(x) and x.__name__ == 'evaluate')
|
||||||
try:
|
try:
|
||||||
lines = [l[4:] for l in inspect.getsourcelines(eval_func[0][1])[0]]
|
lines = [l[4:] for l in inspect.getsourcelines(eval_func[0][1])[0]]
|
||||||
except:
|
except:
|
||||||
lines = []
|
return
|
||||||
self.program_text = ''.join(lines)
|
lines = ''.join(lines)
|
||||||
|
if lines != self.program_text:
|
||||||
|
print 'mismatch in program text for function ', self.name
|
||||||
|
|
||||||
class BuiltinStrcmp(BuiltinFormatterFunction):
|
class BuiltinStrcmp(BuiltinFormatterFunction):
|
||||||
name = 'strcmp'
|
name = 'strcmp'
|
||||||
@ -95,6 +106,15 @@ class BuiltinStrcmp(BuiltinFormatterFunction):
|
|||||||
doc = _('strcmp(x, y, lt, eq, gt) -- does a case-insensitive comparison of x '
|
doc = _('strcmp(x, y, lt, eq, gt) -- does a case-insensitive comparison of x '
|
||||||
'and y as strings. Returns lt if x < y. Returns eq if x == y. '
|
'and y as strings. Returns lt if x < y. Returns eq if x == y. '
|
||||||
'Otherwise returns gt.')
|
'Otherwise returns gt.')
|
||||||
|
program_text = r'''
|
||||||
|
def evaluate(self, formatter, kwargs, mi, locals, x, y, lt, eq, gt):
|
||||||
|
v = strcmp(x, y)
|
||||||
|
if v < 0:
|
||||||
|
return lt
|
||||||
|
if v == 0:
|
||||||
|
return eq
|
||||||
|
return gt
|
||||||
|
'''
|
||||||
|
|
||||||
def evaluate(self, formatter, kwargs, mi, locals, x, y, lt, eq, gt):
|
def evaluate(self, formatter, kwargs, mi, locals, x, y, lt, eq, gt):
|
||||||
v = strcmp(x, y)
|
v = strcmp(x, y)
|
||||||
@ -109,6 +129,16 @@ class BuiltinCmp(BuiltinFormatterFunction):
|
|||||||
arg_count = 5
|
arg_count = 5
|
||||||
doc = _('cmp(x, y, lt, eq, gt) -- compares x and y after converting both to '
|
doc = _('cmp(x, y, lt, eq, gt) -- compares x and y after converting both to '
|
||||||
'numbers. Returns lt if x < y. Returns eq if x == y. Otherwise returns gt.')
|
'numbers. Returns lt if x < y. Returns eq if x == y. Otherwise returns gt.')
|
||||||
|
program_text = r'''
|
||||||
|
def evaluate(self, formatter, kwargs, mi, locals, x, y, lt, eq, gt):
|
||||||
|
x = float(x if x else 0)
|
||||||
|
y = float(y if y else 0)
|
||||||
|
if x < y:
|
||||||
|
return lt
|
||||||
|
if x == y:
|
||||||
|
return eq
|
||||||
|
return gt
|
||||||
|
'''
|
||||||
|
|
||||||
def evaluate(self, formatter, kwargs, mi, locals, x, y, lt, eq, gt):
|
def evaluate(self, formatter, kwargs, mi, locals, x, y, lt, eq, gt):
|
||||||
x = float(x if x else 0)
|
x = float(x if x else 0)
|
||||||
@ -124,6 +154,14 @@ class BuiltinStrcat(BuiltinFormatterFunction):
|
|||||||
arg_count = -1
|
arg_count = -1
|
||||||
doc = _('strcat(a, b, ...) -- can take any number of arguments. Returns a '
|
doc = _('strcat(a, b, ...) -- can take any number of arguments. Returns a '
|
||||||
'string formed by concatenating all the arguments')
|
'string formed by concatenating all the arguments')
|
||||||
|
program_text = r'''
|
||||||
|
def evaluate(self, formatter, kwargs, mi, locals, *args):
|
||||||
|
i = 0
|
||||||
|
res = ''
|
||||||
|
for i in range(0, len(args)):
|
||||||
|
res += args[i]
|
||||||
|
return res
|
||||||
|
'''
|
||||||
|
|
||||||
def evaluate(self, formatter, kwargs, mi, locals, *args):
|
def evaluate(self, formatter, kwargs, mi, locals, *args):
|
||||||
i = 0
|
i = 0
|
||||||
@ -136,6 +174,12 @@ class BuiltinAdd(BuiltinFormatterFunction):
|
|||||||
name = 'add'
|
name = 'add'
|
||||||
arg_count = 2
|
arg_count = 2
|
||||||
doc = _('add(x, y) -- returns x + y. Throws an exception if either x or y are not numbers.')
|
doc = _('add(x, y) -- returns x + y. Throws an exception if either x or y are not numbers.')
|
||||||
|
program_text = r'''
|
||||||
|
def evaluate(self, formatter, kwargs, mi, locals, x, y):
|
||||||
|
x = float(x if x else 0)
|
||||||
|
y = float(y if y else 0)
|
||||||
|
return unicode(x + y)
|
||||||
|
'''
|
||||||
|
|
||||||
def evaluate(self, formatter, kwargs, mi, locals, x, y):
|
def evaluate(self, formatter, kwargs, mi, locals, x, y):
|
||||||
x = float(x if x else 0)
|
x = float(x if x else 0)
|
||||||
@ -146,6 +190,12 @@ class BuiltinSubtract(BuiltinFormatterFunction):
|
|||||||
name = 'subtract'
|
name = 'subtract'
|
||||||
arg_count = 2
|
arg_count = 2
|
||||||
doc = _('subtract(x, y) -- returns x - y. Throws an exception if either x or y are not numbers.')
|
doc = _('subtract(x, y) -- returns x - y. Throws an exception if either x or y are not numbers.')
|
||||||
|
program_text = r'''
|
||||||
|
def evaluate(self, formatter, kwargs, mi, locals, x, y):
|
||||||
|
x = float(x if x else 0)
|
||||||
|
y = float(y if y else 0)
|
||||||
|
return unicode(x - y)
|
||||||
|
'''
|
||||||
|
|
||||||
def evaluate(self, formatter, kwargs, mi, locals, x, y):
|
def evaluate(self, formatter, kwargs, mi, locals, x, y):
|
||||||
x = float(x if x else 0)
|
x = float(x if x else 0)
|
||||||
@ -156,6 +206,12 @@ class BuiltinMultiply(BuiltinFormatterFunction):
|
|||||||
name = 'multiply'
|
name = 'multiply'
|
||||||
arg_count = 2
|
arg_count = 2
|
||||||
doc = _('multiply(x, y) -- returns x * y. Throws an exception if either x or y are not numbers.')
|
doc = _('multiply(x, y) -- returns x * y. Throws an exception if either x or y are not numbers.')
|
||||||
|
program_text = r'''
|
||||||
|
def evaluate(self, formatter, kwargs, mi, locals, x, y):
|
||||||
|
x = float(x if x else 0)
|
||||||
|
y = float(y if y else 0)
|
||||||
|
return unicode(x * y)
|
||||||
|
'''
|
||||||
|
|
||||||
def evaluate(self, formatter, kwargs, mi, locals, x, y):
|
def evaluate(self, formatter, kwargs, mi, locals, x, y):
|
||||||
x = float(x if x else 0)
|
x = float(x if x else 0)
|
||||||
@ -166,6 +222,12 @@ class BuiltinDivide(BuiltinFormatterFunction):
|
|||||||
name = 'divide'
|
name = 'divide'
|
||||||
arg_count = 2
|
arg_count = 2
|
||||||
doc = _('divide(x, y) -- returns x / y. Throws an exception if either x or y are not numbers.')
|
doc = _('divide(x, y) -- returns x / y. Throws an exception if either x or y are not numbers.')
|
||||||
|
program_text = r'''
|
||||||
|
def evaluate(self, formatter, kwargs, mi, locals, x, y):
|
||||||
|
x = float(x if x else 0)
|
||||||
|
y = float(y if y else 0)
|
||||||
|
return unicode(x / y)
|
||||||
|
'''
|
||||||
|
|
||||||
def evaluate(self, formatter, kwargs, mi, locals, x, y):
|
def evaluate(self, formatter, kwargs, mi, locals, x, y):
|
||||||
x = float(x if x else 0)
|
x = float(x if x else 0)
|
||||||
@ -182,6 +244,11 @@ class BuiltinTemplate(BuiltinFormatterFunction):
|
|||||||
']] for the } character; they are converted automatically. '
|
']] for the } character; they are converted automatically. '
|
||||||
'For example, template(\'[[title_sort]]\') will evaluate the '
|
'For example, template(\'[[title_sort]]\') will evaluate the '
|
||||||
'template {title_sort} and return its value.')
|
'template {title_sort} and return its value.')
|
||||||
|
program_text = r'''
|
||||||
|
def evaluate(self, formatter, kwargs, mi, locals, template):
|
||||||
|
template = template.replace('[[', '{').replace(']]', '}')
|
||||||
|
return formatter.safe_format(template, kwargs, 'TEMPLATE', mi)
|
||||||
|
'''
|
||||||
|
|
||||||
def evaluate(self, formatter, kwargs, mi, locals, template):
|
def evaluate(self, formatter, kwargs, mi, locals, template):
|
||||||
template = template.replace('[[', '{').replace(']]', '}')
|
template = template.replace('[[', '{').replace(']]', '}')
|
||||||
@ -194,6 +261,12 @@ class BuiltinEval(BuiltinFormatterFunction):
|
|||||||
'variables (those \'assign\'ed to) instead of the book metadata. '
|
'variables (those \'assign\'ed to) instead of the book metadata. '
|
||||||
' This permits using the template processor to construct complex '
|
' This permits using the template processor to construct complex '
|
||||||
'results from local variables.')
|
'results from local variables.')
|
||||||
|
program_text = r'''
|
||||||
|
def evaluate(self, formatter, kwargs, mi, locals, template):
|
||||||
|
from formatter import eval_formatter
|
||||||
|
template = template.replace('[[', '{').replace(']]', '}')
|
||||||
|
return eval_formatter.safe_format(template, locals, 'EVAL', None)
|
||||||
|
'''
|
||||||
|
|
||||||
def evaluate(self, formatter, kwargs, mi, locals, template):
|
def evaluate(self, formatter, kwargs, mi, locals, template):
|
||||||
from formatter import eval_formatter
|
from formatter import eval_formatter
|
||||||
@ -205,6 +278,11 @@ class BuiltinAssign(BuiltinFormatterFunction):
|
|||||||
arg_count = 2
|
arg_count = 2
|
||||||
doc = _('assign(id, val) -- assigns val to id, then returns val. '
|
doc = _('assign(id, val) -- assigns val to id, then returns val. '
|
||||||
'id must be an identifier, not an expression')
|
'id must be an identifier, not an expression')
|
||||||
|
program_text = r'''
|
||||||
|
def evaluate(self, formatter, kwargs, mi, locals, target, value):
|
||||||
|
locals[target] = value
|
||||||
|
return value
|
||||||
|
'''
|
||||||
|
|
||||||
def evaluate(self, formatter, kwargs, mi, locals, target, value):
|
def evaluate(self, formatter, kwargs, mi, locals, target, value):
|
||||||
locals[target] = value
|
locals[target] = value
|
||||||
@ -216,6 +294,11 @@ class BuiltinPrint(BuiltinFormatterFunction):
|
|||||||
doc = _('print(a, b, ...) -- prints the arguments to standard output. '
|
doc = _('print(a, b, ...) -- prints the arguments to standard output. '
|
||||||
'Unless you start calibre from the command line (calibre-debug -g), '
|
'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.')
|
||||||
|
program_text = r'''
|
||||||
|
def evaluate(self, formatter, kwargs, mi, locals, *args):
|
||||||
|
print args
|
||||||
|
return None
|
||||||
|
'''
|
||||||
|
|
||||||
def evaluate(self, formatter, kwargs, mi, locals, *args):
|
def evaluate(self, formatter, kwargs, mi, locals, *args):
|
||||||
print args
|
print args
|
||||||
@ -225,6 +308,10 @@ class BuiltinField(BuiltinFormatterFunction):
|
|||||||
name = 'field'
|
name = 'field'
|
||||||
arg_count = 1
|
arg_count = 1
|
||||||
doc = _('field(name) -- returns the metadata field named by name')
|
doc = _('field(name) -- returns the metadata field named by name')
|
||||||
|
program_text = r'''
|
||||||
|
def evaluate(self, formatter, kwargs, mi, locals, name):
|
||||||
|
return formatter.get_value(name, [], kwargs)
|
||||||
|
'''
|
||||||
|
|
||||||
def evaluate(self, formatter, kwargs, mi, locals, name):
|
def evaluate(self, formatter, kwargs, mi, locals, name):
|
||||||
return formatter.get_value(name, [], kwargs)
|
return formatter.get_value(name, [], kwargs)
|
||||||
@ -238,6 +325,10 @@ class BuiltinSubstr(BuiltinFormatterFunction):
|
|||||||
'characters counting from the right. If end is zero, then it '
|
'characters counting from the right. If end is zero, then it '
|
||||||
'indicates the last character. For example, substr(\'12345\', 1, 0) '
|
'indicates the last character. For example, substr(\'12345\', 1, 0) '
|
||||||
'returns \'2345\', and substr(\'12345\', 1, -1) returns \'234\'.')
|
'returns \'2345\', and substr(\'12345\', 1, -1) returns \'234\'.')
|
||||||
|
program_text = r'''
|
||||||
|
def evaluate(self, formatter, kwargs, mi, locals, str_, start_, end_):
|
||||||
|
return str_[int(start_): len(str_) if int(end_) == 0 else int(end_)]
|
||||||
|
'''
|
||||||
|
|
||||||
def evaluate(self, formatter, kwargs, mi, locals, str_, start_, end_):
|
def evaluate(self, formatter, kwargs, mi, locals, str_, start_, end_):
|
||||||
return str_[int(start_): len(str_) if int(end_) == 0 else int(end_)]
|
return str_[int(start_): len(str_) if int(end_) == 0 else int(end_)]
|
||||||
@ -252,6 +343,23 @@ class BuiltinLookup(BuiltinFormatterFunction):
|
|||||||
'function in one composite field to use the value of some other '
|
'function in one composite field to use the value of some other '
|
||||||
'composite field. This is extremely useful when constructing '
|
'composite field. This is extremely useful when constructing '
|
||||||
'variable save paths')
|
'variable save paths')
|
||||||
|
program_text = r'''
|
||||||
|
def evaluate(self, formatter, kwargs, mi, locals, val, *args):
|
||||||
|
if len(args) == 2: # here for backwards compatibility
|
||||||
|
if val:
|
||||||
|
return formatter.vformat('{'+args[0].strip()+'}', [], kwargs)
|
||||||
|
else:
|
||||||
|
return formatter.vformat('{'+args[1].strip()+'}', [], kwargs)
|
||||||
|
if (len(args) % 2) != 1:
|
||||||
|
raise ValueError(_('lookup requires either 2 or an odd number of arguments'))
|
||||||
|
i = 0
|
||||||
|
while i < len(args):
|
||||||
|
if i + 1 >= len(args):
|
||||||
|
return formatter.vformat('{' + args[i].strip() + '}', [], kwargs)
|
||||||
|
if re.search(args[i], val):
|
||||||
|
return formatter.vformat('{'+args[i+1].strip() + '}', [], kwargs)
|
||||||
|
i += 2
|
||||||
|
'''
|
||||||
|
|
||||||
def evaluate(self, formatter, kwargs, mi, locals, val, *args):
|
def evaluate(self, formatter, kwargs, mi, locals, val, *args):
|
||||||
if len(args) == 2: # here for backwards compatibility
|
if len(args) == 2: # here for backwards compatibility
|
||||||
@ -274,6 +382,13 @@ class BuiltinTest(BuiltinFormatterFunction):
|
|||||||
arg_count = 3
|
arg_count = 3
|
||||||
doc = _('test(val, text if not empty, text if empty) -- return `text if not '
|
doc = _('test(val, text if not empty, text if empty) -- return `text if not '
|
||||||
'empty` if the field is not empty, otherwise return `text if empty`')
|
'empty` if the field is not empty, otherwise return `text if empty`')
|
||||||
|
program_text = r'''
|
||||||
|
def evaluate(self, formatter, kwargs, mi, locals, val, value_if_set, value_not_set):
|
||||||
|
if val:
|
||||||
|
return value_if_set
|
||||||
|
else:
|
||||||
|
return value_not_set
|
||||||
|
'''
|
||||||
|
|
||||||
def evaluate(self, formatter, kwargs, mi, locals, val, value_if_set, value_not_set):
|
def evaluate(self, formatter, kwargs, mi, locals, val, value_if_set, value_not_set):
|
||||||
if val:
|
if val:
|
||||||
@ -288,6 +403,14 @@ class BuiltinContains(BuiltinFormatterFunction):
|
|||||||
'if field contains matches for the regular expression `pattern`. '
|
'if field contains matches for the regular expression `pattern`. '
|
||||||
'Returns `text if match` if matches are found, otherwise it returns '
|
'Returns `text if match` if matches are found, otherwise it returns '
|
||||||
'`text if no match`')
|
'`text if no match`')
|
||||||
|
program_text = r'''
|
||||||
|
def evaluate(self, formatter, kwargs, mi, locals,
|
||||||
|
val, test, value_if_present, value_if_not):
|
||||||
|
if re.search(test, val):
|
||||||
|
return value_if_present
|
||||||
|
else:
|
||||||
|
return value_if_not
|
||||||
|
'''
|
||||||
|
|
||||||
def evaluate(self, formatter, kwargs, mi, locals,
|
def evaluate(self, formatter, kwargs, mi, locals,
|
||||||
val, test, value_if_present, value_if_not):
|
val, test, value_if_present, value_if_not):
|
||||||
@ -304,6 +427,18 @@ class BuiltinSwitch(BuiltinFormatterFunction):
|
|||||||
'the regular expression `pattern` and if so, returns that '
|
'the regular expression `pattern` and if so, returns that '
|
||||||
'`value`. If no pattern matches, then else_value is returned. '
|
'`value`. If no pattern matches, then else_value is returned. '
|
||||||
'You can have as many `pattern, value` pairs as you want')
|
'You can have as many `pattern, value` pairs as you want')
|
||||||
|
program_text = r'''
|
||||||
|
def evaluate(self, formatter, kwargs, mi, locals, val, *args):
|
||||||
|
if (len(args) % 2) != 1:
|
||||||
|
raise ValueError(_('switch requires an odd number of arguments'))
|
||||||
|
i = 0
|
||||||
|
while i < len(args):
|
||||||
|
if i + 1 >= len(args):
|
||||||
|
return args[i]
|
||||||
|
if re.search(args[i], val):
|
||||||
|
return args[i+1]
|
||||||
|
i += 2
|
||||||
|
'''
|
||||||
|
|
||||||
def evaluate(self, formatter, kwargs, mi, locals, val, *args):
|
def evaluate(self, formatter, kwargs, mi, locals, val, *args):
|
||||||
if (len(args) % 2) != 1:
|
if (len(args) % 2) != 1:
|
||||||
@ -323,6 +458,10 @@ class BuiltinRe(BuiltinFormatterFunction):
|
|||||||
'the regular expression. All instances of `pattern` are replaced '
|
'the regular expression. All instances of `pattern` are replaced '
|
||||||
'with `replacement`. As in all of calibre, these are '
|
'with `replacement`. As in all of calibre, these are '
|
||||||
'python-compatible regular expressions')
|
'python-compatible regular expressions')
|
||||||
|
program_text = r'''
|
||||||
|
def evaluate(self, formatter, kwargs, mi, locals, val, pattern, replacement):
|
||||||
|
return re.sub(pattern, replacement, val)
|
||||||
|
'''
|
||||||
|
|
||||||
def evaluate(self, formatter, kwargs, mi, locals, val, pattern, replacement):
|
def evaluate(self, formatter, kwargs, mi, locals, val, pattern, replacement):
|
||||||
return re.sub(pattern, replacement, val)
|
return re.sub(pattern, replacement, val)
|
||||||
@ -332,6 +471,13 @@ class BuiltinIfempty(BuiltinFormatterFunction):
|
|||||||
arg_count = 2
|
arg_count = 2
|
||||||
doc = _('ifempty(val, text if empty) -- return val if val is not empty, '
|
doc = _('ifempty(val, text if empty) -- return val if val is not empty, '
|
||||||
'otherwise return `text if empty`')
|
'otherwise return `text if empty`')
|
||||||
|
program_text = r'''
|
||||||
|
def evaluate(self, formatter, kwargs, mi, locals, val, value_if_empty):
|
||||||
|
if val:
|
||||||
|
return val
|
||||||
|
else:
|
||||||
|
return value_if_empty
|
||||||
|
'''
|
||||||
|
|
||||||
def evaluate(self, formatter, kwargs, mi, locals, val, value_if_empty):
|
def evaluate(self, formatter, kwargs, mi, locals, val, value_if_empty):
|
||||||
if val:
|
if val:
|
||||||
@ -354,6 +500,16 @@ class BuiltinShorten(BuiltinFormatterFunction):
|
|||||||
'If the field\'s length is less than left chars + right chars + '
|
'If the field\'s length is less than left chars + right chars + '
|
||||||
'the length of `middle text`, then the field will be used '
|
'the length of `middle text`, then the field will be used '
|
||||||
'intact. For example, the title `The Dome` would not be changed.')
|
'intact. For example, the title `The Dome` would not be changed.')
|
||||||
|
program_text = r'''
|
||||||
|
def evaluate(self, formatter, kwargs, mi, locals,
|
||||||
|
val, leading, center_string, trailing):
|
||||||
|
l = max(0, int(leading))
|
||||||
|
t = max(0, int(trailing))
|
||||||
|
if len(val) > l + len(center_string) + t:
|
||||||
|
return val[0:l] + center_string + ('' if t == 0 else val[-t:])
|
||||||
|
else:
|
||||||
|
return val
|
||||||
|
'''
|
||||||
|
|
||||||
def evaluate(self, formatter, kwargs, mi, locals,
|
def evaluate(self, formatter, kwargs, mi, locals,
|
||||||
val, leading, center_string, trailing):
|
val, leading, center_string, trailing):
|
||||||
@ -371,6 +527,10 @@ class BuiltinCount(BuiltinFormatterFunction):
|
|||||||
'separated by `separator`, returning the number of items in the '
|
'separated by `separator`, returning the number of items in the '
|
||||||
'list. Most lists use a comma as the separator, but authors '
|
'list. Most lists use a comma as the separator, but authors '
|
||||||
'uses an ampersand. Examples: {tags:count(,)}, {authors:count(&)}')
|
'uses an ampersand. Examples: {tags:count(,)}, {authors:count(&)}')
|
||||||
|
program_text = r'''
|
||||||
|
def evaluate(self, formatter, kwargs, mi, locals, val, sep):
|
||||||
|
return unicode(len(val.split(sep)))
|
||||||
|
'''
|
||||||
|
|
||||||
def evaluate(self, formatter, kwargs, mi, locals, val, sep):
|
def evaluate(self, formatter, kwargs, mi, locals, val, sep):
|
||||||
return unicode(len(val.split(sep)))
|
return unicode(len(val.split(sep)))
|
||||||
@ -384,6 +544,17 @@ class BuiltinListitem(BuiltinFormatterFunction):
|
|||||||
'using `list_item(-1,separator)`. If the item is not in the list, '
|
'using `list_item(-1,separator)`. If the item is not in the list, '
|
||||||
'then the empty value is returned. The separator has the same '
|
'then the empty value is returned. The separator has the same '
|
||||||
'meaning as in the count function.')
|
'meaning as in the count function.')
|
||||||
|
program_text = r'''
|
||||||
|
def evaluate(self, formatter, kwargs, mi, locals, val, index, sep):
|
||||||
|
if not val:
|
||||||
|
return ''
|
||||||
|
index = int(index)
|
||||||
|
val = val.split(sep)
|
||||||
|
try:
|
||||||
|
return val[index]
|
||||||
|
except:
|
||||||
|
return ''
|
||||||
|
'''
|
||||||
|
|
||||||
def evaluate(self, formatter, kwargs, mi, locals, val, index, sep):
|
def evaluate(self, formatter, kwargs, mi, locals, val, index, sep):
|
||||||
if not val:
|
if not val:
|
||||||
@ -399,6 +570,10 @@ class BuiltinUppercase(BuiltinFormatterFunction):
|
|||||||
name = 'uppercase'
|
name = 'uppercase'
|
||||||
arg_count = 1
|
arg_count = 1
|
||||||
doc = _('uppercase(val) -- return value of the field in upper case')
|
doc = _('uppercase(val) -- return value of the field in upper case')
|
||||||
|
program_text = r'''
|
||||||
|
def evaluate(self, formatter, kwargs, mi, locals, val):
|
||||||
|
return val.upper()
|
||||||
|
'''
|
||||||
|
|
||||||
def evaluate(self, formatter, kwargs, mi, locals, val):
|
def evaluate(self, formatter, kwargs, mi, locals, val):
|
||||||
return val.upper()
|
return val.upper()
|
||||||
@ -407,6 +582,10 @@ class BuiltinLowercase(BuiltinFormatterFunction):
|
|||||||
name = 'lowercase'
|
name = 'lowercase'
|
||||||
arg_count = 1
|
arg_count = 1
|
||||||
doc = _('lowercase(val) -- return value of the field in lower case')
|
doc = _('lowercase(val) -- return value of the field in lower case')
|
||||||
|
program_text = r'''
|
||||||
|
def evaluate(self, formatter, kwargs, mi, locals, val):
|
||||||
|
return val.lower()
|
||||||
|
'''
|
||||||
|
|
||||||
def evaluate(self, formatter, kwargs, mi, locals, val):
|
def evaluate(self, formatter, kwargs, mi, locals, val):
|
||||||
return val.lower()
|
return val.lower()
|
||||||
@ -415,6 +594,10 @@ class BuiltinTitlecase(BuiltinFormatterFunction):
|
|||||||
name = 'titlecase'
|
name = 'titlecase'
|
||||||
arg_count = 1
|
arg_count = 1
|
||||||
doc = _('titlecase(val) -- return value of the field in title case')
|
doc = _('titlecase(val) -- return value of the field in title case')
|
||||||
|
program_text = r'''
|
||||||
|
def evaluate(self, formatter, kwargs, mi, locals, val):
|
||||||
|
return titlecase(val)
|
||||||
|
'''
|
||||||
|
|
||||||
def evaluate(self, formatter, kwargs, mi, locals, val):
|
def evaluate(self, formatter, kwargs, mi, locals, val):
|
||||||
return titlecase(val)
|
return titlecase(val)
|
||||||
@ -423,6 +606,10 @@ class BuiltinCapitalize(BuiltinFormatterFunction):
|
|||||||
name = 'capitalize'
|
name = 'capitalize'
|
||||||
arg_count = 1
|
arg_count = 1
|
||||||
doc = _('capitalize(val) -- return value of the field capitalized')
|
doc = _('capitalize(val) -- return value of the field capitalized')
|
||||||
|
program_text = r'''
|
||||||
|
def evaluate(self, formatter, kwargs, mi, locals, val):
|
||||||
|
return capitalize(val)
|
||||||
|
'''
|
||||||
|
|
||||||
def evaluate(self, formatter, kwargs, mi, locals, val):
|
def evaluate(self, formatter, kwargs, mi, locals, val):
|
||||||
return capitalize(val)
|
return capitalize(val)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user