##// END OF EJS Templates
templater: raise nested functions
Matt Mackall -
r10852:0d50586a default
parent child Browse files
Show More
@@ -17,13 +17,15 b' def _flatten(thing):'
17 17 if isinstance(thing, str):
18 18 yield thing
19 19 elif not hasattr(thing, '__iter__'):
20 yield str(thing)
21 elif thing is not None:
20 if i is not None:
21 yield str(thing)
22 else:
22 23 for i in thing:
23 24 if isinstance(i, str):
24 25 yield i
25 26 elif not hasattr(i, '__iter__'):
26 yield str(i)
27 if i is not None:
28 yield str(i)
27 29 elif i is not None:
28 30 for j in _flatten(i):
29 31 yield j
@@ -64,77 +66,85 b' class engine(object):'
64 66 self._defaults = defaults
65 67 self._cache = {}
66 68
67 def process(self, t, mapping):
68 '''Perform expansion. t is name of map element to expand. mapping contains
69 added elements for use during expansion. Is a generator.'''
69 def _load(self, t):
70 '''load, parse, and cache a template'''
70 71 if t not in self._cache:
71 72 self._cache[t] = self._parse(self._loader(t))
72 return _flatten(self._process(self._cache[t], mapping))
73 return self._cache[t]
74
75 def process(self, t, mapping):
76 '''Perform expansion. t is name of map element to expand.
77 mapping contains added elements for use during expansion. Is a
78 generator.'''
79
80 return _flatten(self._process(self._load(t), mapping))
81
82 def _get(self, mapping, key):
83 v = mapping.get(key)
84 if v is None:
85 v = self._defaults.get(key, '')
86 if hasattr(v, '__call__'):
87 v = v(**mapping)
88 return v
89
90 def _raw(self, mapping, x):
91 return x
92
93 def _filter(self, mapping, parts):
94 filters, val = parts
95 x = self._get(mapping, val)
96 for f in filters:
97 x = f(x)
98 return x
99
100 def _format(self, mapping, args):
101 key, parsed = args
102 v = self._get(mapping, key)
103 if not hasattr(v, '__iter__'):
104 raise SyntaxError(_("error expanding '%s%%%s'")
105 % (key, format))
106 lm = mapping.copy()
107 for i in v:
108 if isinstance(i, dict):
109 lm.update(i)
110 yield self._process(parsed, lm)
111 else:
112 # v is not an iterable of dicts, this happen when 'key'
113 # has been fully expanded already and format is useless.
114 # If so, return the expanded value.
115 yield i
73 116
74 117 def _parse(self, tmpl):
75 118 '''preparse a template'''
76 119
77 defget = self._defaults.get
78 def getter(mapping, key):
79 v = mapping.get(key)
80 if v is None:
81 v = defget(key, '')
82 if hasattr(v, '__call__'):
83 v = v(**mapping)
84 return v
85
86 def raw(mapping, x):
87 return x
88 def filt(mapping, parts):
89 filters, val = parts
90 x = getter(mapping, val)
91 for f in filters:
92 x = f(x)
93 return x
94 def formatter(mapping, args):
95 key, format = args
96 v = getter(mapping, key)
97 if not hasattr(v, '__iter__'):
98 raise SyntaxError(_("error expanding '%s%%%s'")
99 % (key, format))
100 lm = mapping.copy()
101 for i in v:
102 if isinstance(i, dict):
103 lm.update(i)
104 yield self.process(format, lm)
105 else:
106 # v is not an iterable of dicts, this happen when 'key'
107 # has been fully expanded already and format is useless.
108 # If so, return the expanded value.
109 yield i
110
111 120 parsed = []
112 121 pos, stop = 0, len(tmpl)
113 122 while pos < stop:
114 123 n = tmpl.find('{', pos)
115 124 if n < 0:
116 parsed.append((raw, tmpl[pos:stop]))
125 parsed.append((self._raw, tmpl[pos:stop]))
117 126 break
118 127 if n > 0 and tmpl[n - 1] == '\\':
119 128 # escaped
120 parsed.append((raw, tmpl[pos:n + 1]))
129 parsed.append((self._raw, tmpl[pos:n + 1]))
121 130 pos = n + 1
122 131 continue
123 132 if n > pos:
124 parsed.append((raw, tmpl[pos:n]))
133 parsed.append((self._raw, tmpl[pos:n]))
125 134
126 135 pos = n
127 136 n = tmpl.find('}', pos)
128 137 if n < 0:
129 138 # no closing
130 parsed.append((raw, tmpl[pos:stop]))
139 parsed.append((self._raw, tmpl[pos:stop]))
131 140 break
132 141
133 142 expr = tmpl[pos + 1:n]
134 143 pos = n + 1
135 144
136 145 if '%' in expr:
137 parsed.append((formatter, expr.split('%')))
146 key, t = expr.split('%')
147 parsed.append((self._format, (key, self._load(t))))
138 148 elif '|' in expr:
139 149 parts = expr.split('|')
140 150 val = parts[0]
@@ -142,9 +152,9 b' class engine(object):'
142 152 filters = [self._filters[f] for f in parts[1:]]
143 153 except KeyError, i:
144 154 raise SyntaxError(_("unknown filter '%s'") % i[0])
145 parsed.append((filt, (filters, val)))
155 parsed.append((self._filter, (filters, val)))
146 156 else:
147 parsed.append((getter, expr))
157 parsed.append((self._get, expr))
148 158
149 159 return parsed
150 160
General Comments 0
You need to be logged in to leave comments. Login now