##// END OF EJS Templates
templater: lift parsed and compiled templates to generic data types...
Yuya Nishihara -
r28545:1d461ee2 default
parent child Browse files
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 [compileexp(e, context, methods) for e in exp[1]]
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 ctmpl = gettemplate(exp[2], context)
319 tfunc, tdata = gettemplate(exp[2], context)
312 return (runmap, (func, data, ctmpl))
320 return (runmap, (func, data, tfunc, tdata))
313
321
314 def runmap(context, mapping, data):
322 def runmap(context, mapping, data):
315 func, data, ctmpl = 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 runtemplate(context, lm, ctmpl)
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] = [(_runrecursivesymbol, 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