Show More
@@ -178,8 +178,14 b' def _parsetemplate(tmpl, start, stop, qu' | |||||
178 | raise error.ProgrammingError('unexpected type: %s' % typ) |
|
178 | raise error.ProgrammingError('unexpected type: %s' % typ) | |
179 | raise error.ProgrammingError('unterminated scanning of template') |
|
179 | raise error.ProgrammingError('unterminated scanning of template') | |
180 |
|
180 | |||
181 | def scantemplate(tmpl): |
|
181 | def scantemplate(tmpl, raw=False): | |
182 | """Scan (type, start, end) positions of outermost elements in template |
|
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 | >>> list(scantemplate(b'foo{bar}"baz')) |
|
190 | >>> list(scantemplate(b'foo{bar}"baz')) | |
185 | [('string', 0, 3), ('template', 3, 8), ('string', 8, 12)] |
|
191 | [('string', 0, 3), ('template', 3, 8), ('string', 8, 12)] | |
@@ -187,9 +193,11 b' def scantemplate(tmpl):' | |||||
187 | [('string', 0, 5), ('template', 5, 14), ('string', 14, 19)] |
|
193 | [('string', 0, 5), ('template', 5, 14), ('string', 14, 19)] | |
188 | >>> list(scantemplate(b'foo\\{escaped}')) |
|
194 | >>> list(scantemplate(b'foo\\{escaped}')) | |
189 | [('string', 0, 5), ('string', 5, 13)] |
|
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 | last = None |
|
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 | if last: |
|
201 | if last: | |
194 | yield last + (pos,) |
|
202 | yield last + (pos,) | |
195 | if typ == 'end': |
|
203 | if typ == 'end': | |
@@ -198,27 +206,30 b' def scantemplate(tmpl):' | |||||
198 | last = (typ, pos) |
|
206 | last = (typ, pos) | |
199 | raise error.ProgrammingError('unterminated scanning of template') |
|
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 | """Parse template string into chunks of strings and template expressions""" |
|
210 | """Parse template string into chunks of strings and template expressions""" | |
203 | sepchars = '{' + quote |
|
211 | sepchars = '{' + quote | |
|
212 | unescape = [parser.unescapestr, pycompat.identity][raw] | |||
204 | pos = start |
|
213 | pos = start | |
205 | p = parser.parser(elements) |
|
214 | p = parser.parser(elements) | |
206 | while pos < stop: |
|
215 | while pos < stop: | |
207 | n = min((tmpl.find(c, pos, stop) for c in sepchars), |
|
216 | n = min((tmpl.find(c, pos, stop) for c in sepchars), | |
208 | key=lambda n: (n < 0, n)) |
|
217 | key=lambda n: (n < 0, n)) | |
209 | if n < 0: |
|
218 | if n < 0: | |
210 |
yield ('string', |
|
219 | yield ('string', unescape(tmpl[pos:stop]), pos) | |
211 | pos = stop |
|
220 | pos = stop | |
212 | break |
|
221 | break | |
213 | c = tmpl[n:n + 1] |
|
222 | c = tmpl[n:n + 1] | |
|
223 | bs = 0 # count leading backslashes | |||
|
224 | if not raw: | |||
214 | bs = (n - pos) - len(tmpl[pos:n].rstrip('\\')) |
|
225 | bs = (n - pos) - len(tmpl[pos:n].rstrip('\\')) | |
215 | if bs % 2 == 1: |
|
226 | if bs % 2 == 1: | |
216 | # escaped (e.g. '\{', '\\\{', but not '\\{') |
|
227 | # escaped (e.g. '\{', '\\\{', but not '\\{') | |
217 |
yield ('string', |
|
228 | yield ('string', unescape(tmpl[pos:n - 1]) + c, pos) | |
218 | pos = n + 1 |
|
229 | pos = n + 1 | |
219 | continue |
|
230 | continue | |
220 | if n > pos: |
|
231 | if n > pos: | |
221 |
yield ('string', |
|
232 | yield ('string', unescape(tmpl[pos:n]), pos) | |
222 | if c == quote: |
|
233 | if c == quote: | |
223 | yield ('end', None, n + 1) |
|
234 | yield ('end', None, n + 1) | |
224 | return |
|
235 | return |
General Comments 0
You need to be logged in to leave comments.
Login now