##// END OF EJS Templates
templater: extend preparsing...
Matt Mackall -
r10846:594140b1 default
parent child Browse files
Show More
@@ -72,95 +72,86 b' class engine(object):'
72 else:
72 else:
73 yield str(item)
73 yield str(item)
74
74
75 def _format(self, expr, get, map):
76 key, format = expr.split('%')
77 v = get(key)
78 if not hasattr(v, '__iter__'):
79 raise SyntaxError(_("error expanding '%s%%%s'") % (key, format))
80 lm = map.copy()
81 for i in v:
82 if isinstance(i, dict):
83 lm.update(i)
84 yield self.process(format, lm)
85 else:
86 # v is not an iterable of dicts, this happen when 'key'
87 # has been fully expanded already and format is useless.
88 # If so, return the expanded value.
89 yield i
90
91 def _filter(self, expr, get, map):
92 if expr not in self.cache:
93 parts = expr.split('|')
94 val = parts[0]
95 try:
96 filters = [self.filters[f] for f in parts[1:]]
97 except KeyError, i:
98 raise SyntaxError(_("unknown filter '%s'") % i[0])
99 def apply(get):
100 x = get(val)
101 for f in filters:
102 x = f(x)
103 return x
104 self.cache[expr] = apply
105 return self.cache[expr](get)
106
107 def _parse(self, tmpl):
75 def _parse(self, tmpl):
108 '''preparse a template'''
76 '''preparse a template'''
109
77
78 def getter(mapping, key):
79 v = mapping.get(key)
80 if v is None:
81 v = self.defaults.get(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
110 parsed = []
111 parsed = []
111 pos, stop = 0, len(tmpl)
112 pos, stop = 0, len(tmpl)
112 while pos < stop:
113 while pos < stop:
113 n = tmpl.find('{', pos)
114 n = tmpl.find('{', pos)
114 if n < 0:
115 if n < 0:
115 parsed.append(('', tmpl[pos:stop]))
116 parsed.append((raw, tmpl[pos:stop]))
116 break
117 break
117 if n > 0 and tmpl[n - 1] == '\\':
118 if n > 0 and tmpl[n - 1] == '\\':
118 # escaped
119 # escaped
119 parsed.append(('', tmpl[pos:n + 1]))
120 parsed.append((raw, tmpl[pos:n + 1]))
120 pos = n + 1
121 pos = n + 1
121 continue
122 continue
122 if n > pos:
123 if n > pos:
123 parsed.append(('', tmpl[pos:n]))
124 parsed.append((raw, tmpl[pos:n]))
124
125
125 pos = n
126 pos = n
126 n = tmpl.find('}', pos)
127 n = tmpl.find('}', pos)
127 if n < 0:
128 if n < 0:
128 # no closing
129 # no closing
129 parsed.append(('', tmpl[pos:stop]))
130 parsed.append((raw, tmpl[pos:stop]))
130 break
131 break
131
132
132 expr = tmpl[pos + 1:n]
133 expr = tmpl[pos + 1:n]
133 pos = n + 1
134 pos = n + 1
134
135
135 if '%' in expr:
136 if '%' in expr:
136 parsed.append(('%', expr))
137 parsed.append((formatter, expr.split('%')))
137 elif '|' in expr:
138 elif '|' in expr:
138 parsed.append(('|', expr))
139 parts = expr.split('|')
140 val = parts[0]
141 try:
142 filters = [self.filters[f] for f in parts[1:]]
143 except KeyError, i:
144 raise SyntaxError(_("unknown filter '%s'") % i[0])
145 parsed.append((filt, (filters, val)))
139 else:
146 else:
140 parsed.append(('g', expr))
147 parsed.append((getter, expr))
141
148
142 return parsed
149 return parsed
143
150
144 def _process(self, parsed, map):
151 def _process(self, parsed, mapping):
145 '''Render a template. Returns a generator.'''
152 '''Render a template. Returns a generator.'''
146
153 for f, e in parsed:
147 def get(key):
154 yield f(mapping, e)
148 v = map.get(key)
149 if v is None:
150 v = self.defaults.get(key, '')
151 if hasattr(v, '__call__'):
152 v = v(**map)
153 return v
154
155 for t, e in parsed:
156 if not t:
157 yield e
158 elif t is '|':
159 yield self._filter(e, get, map)
160 elif t is '%':
161 yield self._format(e, get, map)
162 elif t is 'g':
163 yield get(e)
164
155
165 engines = {'default': engine}
156 engines = {'default': engine}
166
157
General Comments 0
You need to be logged in to leave comments. Login now