mercurial/templater.py
changeset 31886 bdda942f4b9c
parent 31885 d18b624c1c06
child 31887 f7b3677f66cd
equal deleted inserted replaced
31885:d18b624c1c06 31886:bdda942f4b9c
   368 def runtemplate(context, mapping, template):
   368 def runtemplate(context, mapping, template):
   369     for func, data in template:
   369     for func, data in template:
   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):
   384     arg, filt = data
   385     arg, filt = data
   385     thing = evalfuncarg(context, mapping, arg)
   386     thing = evalfuncarg(context, mapping, arg)
   450     except ZeroDivisionError:
   451     except ZeroDivisionError:
   451         raise error.Abort(_('division by zero is not defined'))
   452         raise error.Abort(_('division by zero is not defined'))
   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)
       
   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
   465 
   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 
   469 # dict of template built-in functions
   494 # dict of template built-in functions
   830     text = evalstring(context, mapping, args[0])
   855     text = evalstring(context, mapping, args[0])
   831     style = evalstring(context, mapping, args[1])
   856     style = evalstring(context, mapping, args[1])
   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
   848         if first:
   873         if first:
   849             first = False
   874             first = False