mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-06-23 15:30:45 -04:00
Template language: Add strcat and strlen builtin functions. Fixes #821935 ([enhancement] priority rule for tailoring too-long filenames)
This commit is contained in:
commit
c8011b48c7
@ -273,7 +273,9 @@ The following functions are available in addition to those described in single-f
|
||||
* ``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.
|
||||
* ``raw_field(name)`` -- returns the metadata field named by name without applying any formatting.
|
||||
* ``strcat(a, b, ...)`` -- can take any number of arguments. Returns a string formed by concatenating all the arguments.
|
||||
* ``strcat_max(max, string1, prefix2, string2, ...)`` -- Returns a string formed by concatenating the arguments. The returned value is initialized to string1. `Prefix, string` pairs are added to the end of the value as long as the resulting string length is less than `max`. String1 is returned even if string1 is longer than max. You can pass as many `prefix, string` pairs as you wish.
|
||||
* ``strcmp(x, y, lt, eq, gt)`` -- does a case-insensitive comparison x and y as strings. Returns ``lt`` if x < y. Returns ``eq`` if x == y. Otherwise returns ``gt``.
|
||||
* ``strlen(a)`` -- Returns the length of the string passed as the argument.
|
||||
* ``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. If end is negative, then it indicates that many characters counting from the 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'``.
|
||||
* ``subtract(x, y)`` -- returns x - y. Throws an exception if either x or y are not numbers.
|
||||
* ``today()`` -- return a date string for today. This value is designed for use in format_date or days_between, but can be manipulated like any other string. The date is in ISO format.
|
||||
|
@ -136,6 +136,19 @@ class BuiltinStrcat(BuiltinFormatterFunction):
|
||||
res += args[i]
|
||||
return res
|
||||
|
||||
class BuiltinStrlen(BuiltinFormatterFunction):
|
||||
name = 'strlen'
|
||||
arg_count = 1
|
||||
category = 'String Manipulation'
|
||||
__doc__ = doc = _('strlen(a) -- Returns the length of the string passed as '
|
||||
'the argument')
|
||||
|
||||
def evaluate(self, formatter, kwargs, mi, locals, a):
|
||||
try:
|
||||
return len(a)
|
||||
except:
|
||||
return -1
|
||||
|
||||
class BuiltinAdd(BuiltinFormatterFunction):
|
||||
name = 'add'
|
||||
arg_count = 2
|
||||
@ -345,6 +358,40 @@ class BuiltinSwitch(BuiltinFormatterFunction):
|
||||
return args[i+1]
|
||||
i += 2
|
||||
|
||||
class BuiltinStrcatMax(BuiltinFormatterFunction):
|
||||
name = 'strcat_max'
|
||||
arg_count = -1
|
||||
category = 'String Manipulation'
|
||||
__doc__ = doc = _('strcat_max(max, string1, prefix2, string2, ...) -- '
|
||||
'Returns a string formed by concatenating the arguments. The '
|
||||
'returned value is initialized to string1. `Prefix, string` '
|
||||
'pairs are added to the end of the value as long as the '
|
||||
'resulting string length is less than `max`. String1 is returned '
|
||||
'even if string1 is longer than max. You can pass as many '
|
||||
'`prefix, string` pairs as you wish.')
|
||||
|
||||
def evaluate(self, formatter, kwargs, mi, locals, *args):
|
||||
if len(args) < 2:
|
||||
raise ValueError(_('strcat_max requires 2 or more arguments'))
|
||||
if (len(args) % 2) != 0:
|
||||
raise ValueError(_('strcat_max requires an even number of arguments'))
|
||||
try:
|
||||
max = int(args[0])
|
||||
except:
|
||||
raise ValueError(_('first argument to strcat_max must be an integer'))
|
||||
|
||||
i = 2
|
||||
result = args[1]
|
||||
try:
|
||||
while i < len(args):
|
||||
if (len(result) + len(args[i]) + len(args[i+1])) > max:
|
||||
break
|
||||
result = result + args[i] + args[i+1]
|
||||
i += 2
|
||||
except:
|
||||
pass
|
||||
return result.strip()
|
||||
|
||||
class BuiltinInList(BuiltinFormatterFunction):
|
||||
name = 'in_list'
|
||||
arg_count = 5
|
||||
@ -432,7 +479,7 @@ class BuiltinSwapAroundComma(BuiltinFormatterFunction):
|
||||
'returns val unchanged')
|
||||
|
||||
def evaluate(self, formatter, kwargs, mi, locals, val):
|
||||
return re.sub(r'^(.*?),(.*$)', r'\2 \1', val, flags=re.I)
|
||||
return re.sub(r'^(.*?),\s*(.*$)', r'\2 \1', val, flags=re.I).strip()
|
||||
|
||||
class BuiltinIfempty(BuiltinFormatterFunction):
|
||||
name = 'ifempty'
|
||||
@ -502,7 +549,7 @@ class BuiltinListitem(BuiltinFormatterFunction):
|
||||
index = int(index)
|
||||
val = val.split(sep)
|
||||
try:
|
||||
return val[index]
|
||||
return val[index].strip()
|
||||
except:
|
||||
return ''
|
||||
|
||||
@ -620,7 +667,8 @@ class BuiltinSublist(BuiltinFormatterFunction):
|
||||
return ''
|
||||
si = int(start_index)
|
||||
ei = int(end_index)
|
||||
val = val.split(sep)
|
||||
# allow empty list items so counts are what the user expects
|
||||
val = [v.strip() for v in val.split(sep)]
|
||||
try:
|
||||
if ei == 0:
|
||||
return sep.join(val[si:])
|
||||
@ -955,7 +1003,8 @@ _formatter_builtins = [
|
||||
BuiltinLowercase(), BuiltinMultiply(), BuiltinNot(),
|
||||
BuiltinOndevice(), BuiltinOr(), BuiltinPrint(), BuiltinRawField(),
|
||||
BuiltinRe(), BuiltinSelect(), BuiltinShorten(), BuiltinStrcat(),
|
||||
BuiltinStrcmp(), BuiltinStrInList(), BuiltinSubitems(),
|
||||
BuiltinStrcatMax(),
|
||||
BuiltinStrcmp(), BuiltinStrInList(), BuiltinStrlen(), BuiltinSubitems(),
|
||||
BuiltinSublist(),BuiltinSubstr(), BuiltinSubtract(), BuiltinSwapAroundComma(),
|
||||
BuiltinSwitch(), BuiltinTemplate(), BuiltinTest(), BuiltinTitlecase(),
|
||||
BuiltinToday(), BuiltinUppercase(),
|
||||
|
Loading…
x
Reference in New Issue
Block a user