Mercurial > hg
comparison mercurial/templater.py @ 3638:7b064d8bac5e
template: fold template() into __call__, minor optimizations
- use non-grouping operator to avoid some extra processing
- avoid copying and updating defaults
- unnest main template body
- avoid returning extra empty string if format
author | Matt Mackall <mpm@selenic.com> |
---|---|
date | Mon, 13 Nov 2006 13:26:57 -0600 |
parents | e7639888bb2f |
children | 5c9a36210662 |
comparison
equal
deleted
inserted
replaced
3637:e7639888bb2f | 3638: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), |