Show More
@@ -177,9 +177,15 b' def _parsetemplate(tmpl, start, stop, qu' | |||||
177 | raise error.ParseError(_("unterminated string"), start) |
|
177 | raise error.ParseError(_("unterminated string"), start) | |
178 | return parsed, pos |
|
178 | return parsed, pos | |
179 |
|
179 | |||
180 | def compiletemplate(tmpl, context): |
|
180 | def parse(tmpl): | |
|
181 | """Parse template string into tree""" | |||
181 | parsed, pos = _parsetemplate(tmpl, 0, len(tmpl)) |
|
182 | parsed, pos = _parsetemplate(tmpl, 0, len(tmpl)) | |
182 | return [compileexp(e, context, methods) for e in parsed] |
|
183 | assert pos == len(tmpl), 'unquoted template should be consumed' | |
|
184 | return ('template', parsed) | |||
|
185 | ||||
|
186 | def compiletemplate(tmpl, context): | |||
|
187 | """Parse and compile template string to (func, data) pair""" | |||
|
188 | return compileexp(parse(tmpl), context, methods) | |||
183 |
|
189 | |||
184 | def compileexp(exp, context, curmethods): |
|
190 | def compileexp(exp, context, curmethods): | |
185 | t = exp[0] |
|
191 | t = exp[0] | |
@@ -202,8 +208,10 b' def getlist(x):' | |||||
202 | return [x] |
|
208 | return [x] | |
203 |
|
209 | |||
204 | def gettemplate(exp, context): |
|
210 | def gettemplate(exp, context): | |
|
211 | """Compile given template tree or load named template from map file; | |||
|
212 | returns (func, data) pair""" | |||
205 | if exp[0] == 'template': |
|
213 | if exp[0] == 'template': | |
206 |
return |
|
214 | return compileexp(exp, context, methods) | |
207 | if exp[0] == 'symbol': |
|
215 | if exp[0] == 'symbol': | |
208 | # unlike runsymbol(), here 'symbol' is always taken as template name |
|
216 | # unlike runsymbol(), here 'symbol' is always taken as template name | |
209 | # even if it exists in mapping. this allows us to override mapping |
|
217 | # even if it exists in mapping. this allows us to override mapping | |
@@ -308,11 +316,11 b' def runfilter(context, mapping, data):' | |||||
308 |
|
316 | |||
309 | def buildmap(exp, context): |
|
317 | def buildmap(exp, context): | |
310 | func, data = compileexp(exp[1], context, methods) |
|
318 | func, data = compileexp(exp[1], context, methods) | |
311 |
|
|
319 | tfunc, tdata = gettemplate(exp[2], context) | |
312 |
return (runmap, (func, data, |
|
320 | return (runmap, (func, data, tfunc, tdata)) | |
313 |
|
321 | |||
314 | def runmap(context, mapping, data): |
|
322 | def runmap(context, mapping, data): | |
315 |
func, data, |
|
323 | func, data, tfunc, tdata = data | |
316 | d = func(context, mapping, data) |
|
324 | d = func(context, mapping, data) | |
317 | if util.safehasattr(d, 'itermaps'): |
|
325 | if util.safehasattr(d, 'itermaps'): | |
318 | diter = d.itermaps() |
|
326 | diter = d.itermaps() | |
@@ -330,7 +338,7 b' def runmap(context, mapping, data):' | |||||
330 | if isinstance(i, dict): |
|
338 | if isinstance(i, dict): | |
331 | lm.update(i) |
|
339 | lm.update(i) | |
332 | lm['originalnode'] = mapping.get('node') |
|
340 | lm['originalnode'] = mapping.get('node') | |
333 |
yield |
|
341 | yield tfunc(context, lm, tdata) | |
334 | else: |
|
342 | else: | |
335 | # v is not an iterable of dicts, this happen when 'key' |
|
343 | # v is not an iterable of dicts, this happen when 'key' | |
336 | # has been fully expanded already and format is useless. |
|
344 | # has been fully expanded already and format is useless. | |
@@ -857,13 +865,13 b' class engine(object):' | |||||
857 | if defaults is None: |
|
865 | if defaults is None: | |
858 | defaults = {} |
|
866 | defaults = {} | |
859 | self._defaults = defaults |
|
867 | self._defaults = defaults | |
860 | self._cache = {} |
|
868 | self._cache = {} # key: (func, data) | |
861 |
|
869 | |||
862 | def _load(self, t): |
|
870 | def _load(self, t): | |
863 | '''load, parse, and cache a template''' |
|
871 | '''load, parse, and cache a template''' | |
864 | if t not in self._cache: |
|
872 | if t not in self._cache: | |
865 | # put poison to cut recursion while compiling 't' |
|
873 | # put poison to cut recursion while compiling 't' | |
866 |
self._cache[t] = |
|
874 | self._cache[t] = (_runrecursivesymbol, t) | |
867 | try: |
|
875 | try: | |
868 | self._cache[t] = compiletemplate(self._loader(t), self) |
|
876 | self._cache[t] = compiletemplate(self._loader(t), self) | |
869 | except: # re-raises |
|
877 | except: # re-raises | |
@@ -875,7 +883,8 b' class engine(object):' | |||||
875 | '''Perform expansion. t is name of map element to expand. |
|
883 | '''Perform expansion. t is name of map element to expand. | |
876 | mapping contains added elements for use during expansion. Is a |
|
884 | mapping contains added elements for use during expansion. Is a | |
877 | generator.''' |
|
885 | generator.''' | |
878 | return _flatten(runtemplate(self, mapping, self._load(t))) |
|
886 | func, data = self._load(t) | |
|
887 | return _flatten(func(self, mapping, data)) | |||
879 |
|
888 | |||
880 | engines = {'default': engine} |
|
889 | engines = {'default': engine} | |
881 |
|
890 |
General Comments 0
You need to be logged in to leave comments.
Login now