mercurial/templater.py
changeset 3641 7b064d8bac5e
parent 3640 e7639888bb2f
child 3642 5c9a36210662
equal deleted inserted replaced
3640:e7639888bb2f 3641:7b064d8bac5e
    41     format uses key to expand each item in list. syntax is
    41     format uses key to expand each item in list. syntax is
    42     {key%format}.
    42     {key%format}.
    43 
    43 
    44     filter uses function to transform value. syntax is
    44     filter uses function to transform value. syntax is
    45     {key|filter1|filter2|...}.'''
    45     {key|filter1|filter2|...}.'''
       
    46 
       
    47     template_re = re.compile(r"(?:(?:#(?=[\w\|%]+#))|(?:{(?=[\w\|%]+})))"
       
    48                              r"(\w+)(?:(?:%(\w+))|((?:\|\w+)*))[#}]")
    46 
    49 
    47     def __init__(self, mapfile, filters={}, defaults={}, cache={}):
    50     def __init__(self, mapfile, filters={}, defaults={}, cache={}):
    48         '''set up template engine.
    51         '''set up template engine.
    49         mapfile is name of file to read map definitions from.
    52         mapfile is name of file to read map definitions from.
    50         filters is dict of functions. each transforms a value into another.
    53         filters is dict of functions. each transforms a value into another.
    82 
    85 
    83     def __call__(self, t, **map):
    86     def __call__(self, t, **map):
    84         '''perform expansion.
    87         '''perform expansion.
    85         t is name of map element to expand.
    88         t is name of map element to expand.
    86         map is added elements to use during expansion.'''
    89         map is added elements to use during expansion.'''
    87         m = self.defaults.copy()
       
    88         m.update(map)
       
    89         if not self.cache.has_key(t):
    90         if not self.cache.has_key(t):
    90             try:
    91             try:
    91                 self.cache[t] = file(self.map[t]).read()
    92                 self.cache[t] = file(self.map[t]).read()
    92             except IOError, inst:
    93             except IOError, inst:
    93                 raise IOError(inst.args[0], _('template file %s: %s') %
    94                 raise IOError(inst.args[0], _('template file %s: %s') %
    94                               (self.map[t], inst.args[1]))
    95                               (self.map[t], inst.args[1]))
    95         return self.template(self.cache[t], **m)
    96         tmpl = self.cache[t]
    96 
    97 
    97     template_re = re.compile(r"(?:(?:#(?=[\w\|%]+#))|(?:{(?=[\w\|%]+})))"
       
    98                              r"(\w+)((%\w+)*)((\|\w+)*)[#}]")
       
    99 
       
   100     def template(self, tmpl, **map):
       
   101         while tmpl:
    98         while tmpl:
   102             m = self.template_re.search(tmpl)
    99             m = self.template_re.search(tmpl)
   103             if m:
   100             if not m:
   104                 start, end = m.span(0)
   101                 yield tmpl
   105                 key = m.group(1)
   102                 break
   106                 format = m.group(2)
   103 
   107                 fl = m.group(4)
   104             start, end = m.span(0)
   108 
   105             key, format, fl = m.groups()
   109                 if start:
   106 
   110                     yield tmpl[:start]
   107             if start:
   111 
   108                 yield tmpl[:start]
   112                 v = map.get(key, "")
   109             tmpl = tmpl[end:]
   113                 if callable(v):
   110 
   114                     v = v(**map)
   111             if key in map:
   115 
   112                 v = map[key]
   116                 if format:
   113             else:
   117                     if not hasattr(v, '__iter__'):
   114                 v = self.defaults.get(key, "")
   118                         raise SyntaxError(_("Error expanding '%s%s'")
   115             if callable(v):
   119                                           % (key, format))
   116                 v = v(**map)
   120                     lm = map.copy()
   117             if format:
   121                     for i in v:
   118                 if not hasattr(v, '__iter__'):
   122                         lm.update(i)
   119                     raise SyntaxError(_("Error expanding '%s%s'")
   123                         yield self(format[1:], **lm)
   120                                       % (key, format))
   124 
   121                 lm = map.copy()
   125                     v = ""
   122                 for i in v:
   126 
   123                     lm.update(i)
   127                 elif fl:
   124                     yield self(format, **lm)
       
   125             else:
       
   126                 if fl:
   128                     for f in fl.split("|")[1:]:
   127                     for f in fl.split("|")[1:]:
   129                         v = self.filters[f](v)
   128                         v = self.filters[f](v)
   130 
       
   131                 yield v
   129                 yield v
   132                 tmpl = tmpl[end:]
       
   133             else:
       
   134                 yield tmpl
       
   135                 break
       
   136 
   130 
   137 agescales = [("second", 1),
   131 agescales = [("second", 1),
   138              ("minute", 60),
   132              ("minute", 60),
   139              ("hour", 3600),
   133              ("hour", 3600),
   140              ("day", 3600 * 24),
   134              ("day", 3600 * 24),