##// END OF EJS Templates
templater: add option to parse template string just like raw string literal...
Yuya Nishihara -
r36527:638c012a default
parent child Browse files
Show More
@@ -178,8 +178,14 b' def _parsetemplate(tmpl, start, stop, qu'
178 178 raise error.ProgrammingError('unexpected type: %s' % typ)
179 179 raise error.ProgrammingError('unterminated scanning of template')
180 180
181 def scantemplate(tmpl):
182 """Scan (type, start, end) positions of outermost elements in template
181 def scantemplate(tmpl, raw=False):
182 r"""Scan (type, start, end) positions of outermost elements in template
183
184 If raw=True, a backslash is not taken as an escape character just like
185 r'' string in Python. Note that this is different from r'' literal in
186 template in that no template fragment can appear in r'', e.g. r'{foo}'
187 is a literal '{foo}', but ('{foo}', raw=True) is a template expression
188 'foo'.
183 189
184 190 >>> list(scantemplate(b'foo{bar}"baz'))
185 191 [('string', 0, 3), ('template', 3, 8), ('string', 8, 12)]
@@ -187,9 +193,11 b' def scantemplate(tmpl):'
187 193 [('string', 0, 5), ('template', 5, 14), ('string', 14, 19)]
188 194 >>> list(scantemplate(b'foo\\{escaped}'))
189 195 [('string', 0, 5), ('string', 5, 13)]
196 >>> list(scantemplate(b'foo\\{escaped}', raw=True))
197 [('string', 0, 4), ('template', 4, 13)]
190 198 """
191 199 last = None
192 for typ, val, pos in _scantemplate(tmpl, 0, len(tmpl)):
200 for typ, val, pos in _scantemplate(tmpl, 0, len(tmpl), raw=raw):
193 201 if last:
194 202 yield last + (pos,)
195 203 if typ == 'end':
@@ -198,27 +206,30 b' def scantemplate(tmpl):'
198 206 last = (typ, pos)
199 207 raise error.ProgrammingError('unterminated scanning of template')
200 208
201 def _scantemplate(tmpl, start, stop, quote=''):
209 def _scantemplate(tmpl, start, stop, quote='', raw=False):
202 210 """Parse template string into chunks of strings and template expressions"""
203 211 sepchars = '{' + quote
212 unescape = [parser.unescapestr, pycompat.identity][raw]
204 213 pos = start
205 214 p = parser.parser(elements)
206 215 while pos < stop:
207 216 n = min((tmpl.find(c, pos, stop) for c in sepchars),
208 217 key=lambda n: (n < 0, n))
209 218 if n < 0:
210 yield ('string', parser.unescapestr(tmpl[pos:stop]), pos)
219 yield ('string', unescape(tmpl[pos:stop]), pos)
211 220 pos = stop
212 221 break
213 222 c = tmpl[n:n + 1]
223 bs = 0 # count leading backslashes
224 if not raw:
214 225 bs = (n - pos) - len(tmpl[pos:n].rstrip('\\'))
215 226 if bs % 2 == 1:
216 227 # escaped (e.g. '\{', '\\\{', but not '\\{')
217 yield ('string', parser.unescapestr(tmpl[pos:n - 1]) + c, pos)
228 yield ('string', unescape(tmpl[pos:n - 1]) + c, pos)
218 229 pos = n + 1
219 230 continue
220 231 if n > pos:
221 yield ('string', parser.unescapestr(tmpl[pos:n]), pos)
232 yield ('string', unescape(tmpl[pos:n]), pos)
222 233 if c == quote:
223 234 yield ('end', None, n + 1)
224 235 return
General Comments 0
You need to be logged in to leave comments. Login now