##// END OF EJS Templates
templater: add support for keyword arguments...
Yuya Nishihara -
r31886:bdda942f default
parent child Browse files
Show More
@@ -234,7 +234,7 b' class templatefunc(_templateregistrarbas'
234
234
235 templatefunc = registrar.templatefunc()
235 templatefunc = registrar.templatefunc()
236
236
237 @templatefunc('myfunc(arg1, arg2[, arg3])')
237 @templatefunc('myfunc(arg1, arg2[, arg3])', argspec='arg1 arg2 arg3')
238 def myfuncfunc(context, mapping, args):
238 def myfuncfunc(context, mapping, args):
239 '''Explanation of this template function ....
239 '''Explanation of this template function ....
240 '''
240 '''
@@ -242,6 +242,10 b' class templatefunc(_templateregistrarbas'
242
242
243 The first string argument is used also in online help.
243 The first string argument is used also in online help.
244
244
245 If optional 'argspec' is defined, the function will receive 'args' as
246 a dict of named arguments. Otherwise 'args' is a list of positional
247 arguments.
248
245 'templatefunc' instance in example above can be used to
249 'templatefunc' instance in example above can be used to
246 decorate multiple functions.
250 decorate multiple functions.
247
251
@@ -252,3 +256,6 b' class templatefunc(_templateregistrarbas'
252 Otherwise, explicit 'templater.loadfunction()' is needed.
256 Otherwise, explicit 'templater.loadfunction()' is needed.
253 """
257 """
254 _getname = _funcregistrarbase._parsefuncdecl
258 _getname = _funcregistrarbase._parsefuncdecl
259
260 def _extrasetup(self, name, func, argspec=None):
261 func._argspec = argspec
@@ -370,14 +370,15 b' def runtemplate(context, mapping, templa'
370 yield func(context, mapping, data)
370 yield func(context, mapping, data)
371
371
372 def buildfilter(exp, context):
372 def buildfilter(exp, context):
373 arg = compileexp(exp[1], context, methods)
374 n = getsymbol(exp[2])
373 n = getsymbol(exp[2])
375 if n in context._filters:
374 if n in context._filters:
376 filt = context._filters[n]
375 filt = context._filters[n]
376 arg = compileexp(exp[1], context, methods)
377 return (runfilter, (arg, filt))
377 return (runfilter, (arg, filt))
378 if n in funcs:
378 if n in funcs:
379 f = funcs[n]
379 f = funcs[n]
380 return (f, [arg])
380 args = _buildfuncargs(exp[1], context, methods, n, f._argspec)
381 return (f, args)
381 raise error.ParseError(_("unknown function '%s'") % n)
382 raise error.ParseError(_("unknown function '%s'") % n)
382
383
383 def runfilter(context, mapping, data):
384 def runfilter(context, mapping, data):
@@ -452,17 +453,41 b' def runarithmetic(context, mapping, data'
452
453
453 def buildfunc(exp, context):
454 def buildfunc(exp, context):
454 n = getsymbol(exp[1])
455 n = getsymbol(exp[1])
455 args = [compileexp(x, context, exprmethods) for x in getlist(exp[2])]
456 if n in funcs:
456 if n in funcs:
457 f = funcs[n]
457 f = funcs[n]
458 args = _buildfuncargs(exp[2], context, exprmethods, n, f._argspec)
458 return (f, args)
459 return (f, args)
459 if n in context._filters:
460 if n in context._filters:
461 args = _buildfuncargs(exp[2], context, exprmethods, n, argspec=None)
460 if len(args) != 1:
462 if len(args) != 1:
461 raise error.ParseError(_("filter %s expects one argument") % n)
463 raise error.ParseError(_("filter %s expects one argument") % n)
462 f = context._filters[n]
464 f = context._filters[n]
463 return (runfilter, (args[0], f))
465 return (runfilter, (args[0], f))
464 raise error.ParseError(_("unknown function '%s'") % n)
466 raise error.ParseError(_("unknown function '%s'") % n)
465
467
468 def _buildfuncargs(exp, context, curmethods, funcname, argspec):
469 """Compile parsed tree of function arguments into list or dict of
470 (func, data) pairs"""
471 def compiledict(xs):
472 return dict((k, compileexp(x, context, curmethods))
473 for k, x in xs.iteritems())
474 def compilelist(xs):
475 return [compileexp(x, context, curmethods) for x in xs]
476
477 if not argspec:
478 # filter or function with no argspec: return list of positional args
479 return compilelist(getlist(exp))
480
481 # function with argspec: return dict of named args
482 _poskeys, varkey, _keys = argspec = parser.splitargspec(argspec)
483 treeargs = parser.buildargsdict(getlist(exp), funcname, argspec,
484 keyvaluenode='keyvalue', keynode='symbol')
485 compargs = {}
486 if varkey:
487 compargs[varkey] = compilelist(treeargs.pop(varkey))
488 compargs.update(compiledict(treeargs))
489 return compargs
490
466 def buildkeyvaluepair(exp, content):
491 def buildkeyvaluepair(exp, content):
467 raise error.ParseError(_("can't use a key-value pair in this context"))
492 raise error.ParseError(_("can't use a key-value pair in this context"))
468
493
@@ -832,16 +857,16 b' def rstdoc(context, mapping, args):'
832
857
833 return minirst.format(text, style=style, keep=['verbose'])
858 return minirst.format(text, style=style, keep=['verbose'])
834
859
835 @templatefunc('separate(sep, args)')
860 @templatefunc('separate(sep, args)', argspec='sep *args')
836 def separate(context, mapping, args):
861 def separate(context, mapping, args):
837 """Add a separator between non-empty arguments."""
862 """Add a separator between non-empty arguments."""
838 if not args:
863 if 'sep' not in args:
839 # i18n: "separate" is a keyword
864 # i18n: "separate" is a keyword
840 raise error.ParseError(_("separate expects at least one argument"))
865 raise error.ParseError(_("separate expects at least one argument"))
841
866
842 sep = evalstring(context, mapping, args[0])
867 sep = evalstring(context, mapping, args['sep'])
843 first = True
868 first = True
844 for arg in args[1:]:
869 for arg in args['args']:
845 argstr = evalstring(context, mapping, arg)
870 argstr = evalstring(context, mapping, arg)
846 if not argstr:
871 if not argstr:
847 continue
872 continue
@@ -146,6 +146,13 b' Keyword arguments:'
146 hg: parse error: can't use a key-value pair in this context
146 hg: parse error: can't use a key-value pair in this context
147 [255]
147 [255]
148
148
149 Call function which takes named arguments by filter syntax:
150
151 $ hg debugtemplate '{" "|separate}'
152 $ hg debugtemplate '{("not", "an", "argument", "list")|separate}'
153 hg: parse error: unknown method 'list'
154 [255]
155
149 Second branch starting at nullrev:
156 Second branch starting at nullrev:
150
157
151 $ hg update null
158 $ hg update null
General Comments 0
You need to be logged in to leave comments. Login now