Change formatter functions to support aliases instead of requiring a new class instance. Change document generators to use the right accessor to get functions, ignoring aliases.

This commit is contained in:
Charles Haley 2011-08-02 11:37:40 +01:00
parent eac84f0641
commit af3169a29b
3 changed files with 26 additions and 28 deletions

View File

@ -205,8 +205,8 @@ class Resources(Command):
dest = self.j(self.RESOURCES, 'template-functions.json') dest = self.j(self.RESOURCES, 'template-functions.json')
function_dict = {} function_dict = {}
import inspect import inspect
from calibre.utils.formatter_functions import all_builtin_functions from calibre.utils.formatter_functions import formatter_functions
for obj in all_builtin_functions: for obj in formatter_functions.get_builtins().values():
eval_func = inspect.getmembers(obj, eval_func = inspect.getmembers(obj,
lambda x: inspect.ismethod(x) and x.__name__ == 'evaluate') lambda x: inspect.ismethod(x) and x.__name__ == 'evaluate')
try: try:

View File

@ -61,21 +61,17 @@ The python implementation of the template functions is passed in a Metadata obje
def generate_template_language_help(): def generate_template_language_help():
from calibre.utils.formatter_functions import all_builtin_functions from calibre.utils.formatter_functions import formatter_functions
funcs = defaultdict(dict) funcs = defaultdict(dict)
for func in all_builtin_functions: for func in formatter_functions.get_builtins().values():
class_name = func.__class__.__name__ class_name = func.__class__.__name__
if class_name == 'BuiltinMergeLists':
class_name = 'BuiltinListUnion'
func_sig = getattr(func, 'doc') func_sig = getattr(func, 'doc')
x = func_sig.find(' -- ') x = func_sig.find(' -- ')
if x < 0: if x < 0:
print 'No sig for ', class_name print 'No sig for ', class_name
continue continue
if func_sig.startswith('merge_lists('):
continue
func_sig = func_sig[:x] func_sig = func_sig[:x]
func_cat = getattr(func, 'category') func_cat = getattr(func, 'category')
funcs[func_cat][func_sig] = class_name funcs[func_cat][func_sig] = class_name

View File

@ -19,47 +19,53 @@ from calibre.utils.date import parse_date, format_date, now, UNDEFINED_DATE
class FormatterFunctions(object): class FormatterFunctions(object):
def __init__(self): def __init__(self):
self.builtins = {} self._builtins = {}
self.functions = {} self._functions = {}
def register_builtin(self, func_class): def register_builtin(self, func_class):
if not isinstance(func_class, FormatterFunction): if not isinstance(func_class, FormatterFunction):
raise ValueError('Class %s is not an instance of FormatterFunction'%( raise ValueError('Class %s is not an instance of FormatterFunction'%(
func_class.__class__.__name__)) func_class.__class__.__name__))
name = func_class.name name = func_class.name
if name in self.functions: if name in self._functions:
raise ValueError('Name %s already used'%name) raise ValueError('Name %s already used'%name)
self.builtins[name] = func_class self._builtins[name] = func_class
self.functions[name] = func_class self._functions[name] = func_class
for a in func_class.aliases:
self._functions[a] = func_class
def register_function(self, func_class): def register_function(self, func_class):
if not isinstance(func_class, FormatterFunction): if not isinstance(func_class, FormatterFunction):
raise ValueError('Class %s is not an instance of FormatterFunction'%( raise ValueError('Class %s is not an instance of FormatterFunction'%(
func_class.__class__.__name__)) func_class.__class__.__name__))
name = func_class.name name = func_class.name
if name in self.functions: if name in self._functions:
raise ValueError('Name %s already used'%name) raise ValueError('Name %s already used'%name)
self.functions[name] = func_class self._functions[name] = func_class
def get_builtins(self): def get_builtins(self):
return self.builtins return self._builtins
def get_functions(self): def get_functions(self):
return self.functions return self._functions
def reset_to_builtins(self): def reset_to_builtins(self):
self.functions = dict([t for t in self.builtins.items()]) self._functions = {}
for n,c in self._builtins.items():
self._functions[n] = c
for a in c.aliases:
self._functions[a] = c
formatter_functions = FormatterFunctions() formatter_functions = FormatterFunctions()
class FormatterFunction(object): class FormatterFunction(object):
doc = _('No documentation provided') doc = _('No documentation provided')
name = 'no name provided' name = 'no name provided'
category = 'Unknown' category = 'Unknown'
arg_count = 0 arg_count = 0
aliases = []
def evaluate(self, formatter, kwargs, mi, locals, *args): def evaluate(self, formatter, kwargs, mi, locals, *args):
raise NotImplementedError() raise NotImplementedError()
@ -73,7 +79,6 @@ class FormatterFunction(object):
if isinstance(ret, list): if isinstance(ret, list):
return ','.join(list) return ','.join(list)
all_builtin_functions = []
class BuiltinFormatterFunction(FormatterFunction): class BuiltinFormatterFunction(FormatterFunction):
def __init__(self): def __init__(self):
formatter_functions.register_builtin(self) formatter_functions.register_builtin(self)
@ -84,7 +89,6 @@ class BuiltinFormatterFunction(FormatterFunction):
except: except:
lines = [] lines = []
self.program_text = ''.join(lines) self.program_text = ''.join(lines)
all_builtin_functions.append(self)
class BuiltinStrcmp(BuiltinFormatterFunction): class BuiltinStrcmp(BuiltinFormatterFunction):
name = 'strcmp' name = 'strcmp'
@ -839,6 +843,7 @@ class BuiltinListUnion(BuiltinFormatterFunction):
'items differ in case, the one in list1 is used. ' 'items differ in case, the one in list1 is used. '
'The items in list1 and list2 are separated by separator, as are ' 'The items in list1 and list2 are separated by separator, as are '
'the items in the returned list.') 'the items in the returned list.')
aliases = ['merge_lists']
def evaluate(self, formatter, kwargs, mi, locals, list1, list2, separator): def evaluate(self, formatter, kwargs, mi, locals, list1, list2, separator):
l1 = [l.strip() for l in list1.split(separator) if l.strip()] l1 = [l.strip() for l in list1.split(separator) if l.strip()]
@ -853,9 +858,6 @@ class BuiltinListUnion(BuiltinFormatterFunction):
res.append(i) res.append(i)
return ', '.join(res) return ', '.join(res)
class BuiltinMergeLists(BuiltinListUnion):
name = 'merge_lists'
class BuiltinListDifference(BuiltinFormatterFunction): class BuiltinListDifference(BuiltinFormatterFunction):
name = 'list_difference' name = 'list_difference'
arg_count = 3 arg_count = 3
@ -910,7 +912,7 @@ class BuiltinListSort(BuiltinFormatterFunction):
class BuiltinToday(BuiltinFormatterFunction): class BuiltinToday(BuiltinFormatterFunction):
name = 'today' name = 'today'
arg_count = 0 arg_count = 0
category = 'Date functions' category = 'Date _functions'
__doc__ = doc = _('today() -- ' __doc__ = doc = _('today() -- '
'return a date string for today. This value is designed for use in ' 'return a date string for today. This value is designed for use in '
'format_date or days_between, but can be manipulated like any ' 'format_date or days_between, but can be manipulated like any '
@ -921,7 +923,7 @@ class BuiltinToday(BuiltinFormatterFunction):
class BuiltinDaysBetween(BuiltinFormatterFunction): class BuiltinDaysBetween(BuiltinFormatterFunction):
name = 'days_between' name = 'days_between'
arg_count = 2 arg_count = 2
category = 'Date functions' category = 'Date _functions'
__doc__ = doc = _('days_between(date1, date2) -- ' __doc__ = doc = _('days_between(date1, date2) -- '
'return the number of days between date1 and date2. The number is ' 'return the number of days between date1 and date2. The number is '
'positive if date1 is greater than date2, otherwise negative. If ' 'positive if date1 is greater than date2, otherwise negative. If '
@ -940,7 +942,7 @@ class BuiltinDaysBetween(BuiltinFormatterFunction):
i = d1 - d2 i = d1 - d2
return str('%d.%d'%(i.days, i.seconds/8640)) return str('%d.%d'%(i.days, i.seconds/8640))
formatter_builtins = [ _formatter_builtins = [
BuiltinAdd(), BuiltinAnd(), BuiltinAssign(), BuiltinBooksize(), BuiltinAdd(), BuiltinAnd(), BuiltinAssign(), BuiltinBooksize(),
BuiltinCapitalize(), BuiltinCmp(), BuiltinContains(), BuiltinCount(), BuiltinCapitalize(), BuiltinCmp(), BuiltinContains(), BuiltinCount(),
BuiltinDaysBetween(), BuiltinDivide(), BuiltinEval(), BuiltinDaysBetween(), BuiltinDivide(), BuiltinEval(),
@ -950,7 +952,7 @@ formatter_builtins = [
BuiltinIfempty(), BuiltinInList(), BuiltinListDifference(), BuiltinIfempty(), BuiltinInList(), BuiltinListDifference(),
BuiltinListIntersection(), BuiltinListitem(), BuiltinListSort(), BuiltinListIntersection(), BuiltinListitem(), BuiltinListSort(),
BuiltinListUnion(), BuiltinLookup(), BuiltinListUnion(), BuiltinLookup(),
BuiltinLowercase(), BuiltinMergeLists(), BuiltinMultiply(), BuiltinNot(), BuiltinLowercase(), BuiltinMultiply(), BuiltinNot(),
BuiltinOndevice(), BuiltinOr(), BuiltinPrint(), BuiltinRawField(), BuiltinOndevice(), BuiltinOr(), BuiltinPrint(), BuiltinRawField(),
BuiltinRe(), BuiltinSelect(), BuiltinShorten(), BuiltinStrcat(), BuiltinRe(), BuiltinSelect(), BuiltinShorten(), BuiltinStrcat(),
BuiltinStrcmp(), BuiltinStrInList(), BuiltinSubitems(), BuiltinStrcmp(), BuiltinStrInList(), BuiltinSubitems(),