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', |
|
|
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', |
|
|
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', |
|
|
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