20 "|": (5, None, ("|", 5)), |
20 "|": (5, None, ("|", 5)), |
21 "%": (6, None, ("%", 6)), |
21 "%": (6, None, ("%", 6)), |
22 ")": (0, None, None), |
22 ")": (0, None, None), |
23 "integer": (0, ("integer",), None), |
23 "integer": (0, ("integer",), None), |
24 "symbol": (0, ("symbol",), None), |
24 "symbol": (0, ("symbol",), None), |
25 "rawstring": (0, ("rawstring",), None), |
25 "string": (0, ("string",), None), |
26 "template": (0, ("template",), None), |
26 "template": (0, ("template",), None), |
27 "end": (0, None, None), |
27 "end": (0, None, None), |
28 } |
28 } |
29 |
29 |
30 def tokenize(program, start, end): |
30 def tokenize(program, start, end): |
134 >>> _parsetemplate('foo"{bar}', 0, 9, quote='"') |
134 >>> _parsetemplate('foo"{bar}', 0, 9, quote='"') |
135 ([('string', 'foo')], 4) |
135 ([('string', 'foo')], 4) |
136 >>> _parsetemplate(r'foo\"bar"baz', 0, 12, quote='"') |
136 >>> _parsetemplate(r'foo\"bar"baz', 0, 12, quote='"') |
137 ([('string', 'foo"'), ('string', 'bar')], 9) |
137 ([('string', 'foo"'), ('string', 'bar')], 9) |
138 >>> _parsetemplate(r'foo\\"bar', 0, 10, quote='"') |
138 >>> _parsetemplate(r'foo\\"bar', 0, 10, quote='"') |
139 ([('string', 'foo\\\\')], 6) |
139 ([('string', 'foo\\')], 6) |
140 """ |
140 """ |
141 parsed = [] |
141 parsed = [] |
142 sepchars = '{' + quote |
142 sepchars = '{' + quote |
143 pos = start |
143 pos = start |
144 p = parser.parser(elements) |
144 p = parser.parser(elements) |
145 while pos < stop: |
145 while pos < stop: |
146 n = min((tmpl.find(c, pos, stop) for c in sepchars), |
146 n = min((tmpl.find(c, pos, stop) for c in sepchars), |
147 key=lambda n: (n < 0, n)) |
147 key=lambda n: (n < 0, n)) |
148 if n < 0: |
148 if n < 0: |
149 parsed.append(('string', tmpl[pos:stop])) |
149 parsed.append(('string', tmpl[pos:stop].decode('string-escape'))) |
150 pos = stop |
150 pos = stop |
151 break |
151 break |
152 c = tmpl[n] |
152 c = tmpl[n] |
153 bs = (n - pos) - len(tmpl[pos:n].rstrip('\\')) |
153 bs = (n - pos) - len(tmpl[pos:n].rstrip('\\')) |
154 if bs % 2 == 1: |
154 if bs % 2 == 1: |
155 # escaped (e.g. '\{', '\\\{', but not '\\{') |
155 # escaped (e.g. '\{', '\\\{', but not '\\{') |
156 parsed.append(('string', (tmpl[pos:n - 1] + c))) |
156 parsed.append(('string', |
|
157 tmpl[pos:n - 1].decode('string-escape') + c)) |
157 pos = n + 1 |
158 pos = n + 1 |
158 continue |
159 continue |
159 if n > pos: |
160 if n > pos: |
160 parsed.append(('string', tmpl[pos:n])) |
161 parsed.append(('string', tmpl[pos:n].decode('string-escape'))) |
161 if c == quote: |
162 if c == quote: |
162 return parsed, n + 1 |
163 return parsed, n + 1 |
163 |
164 |
164 parseres, pos = p.parse(tokenize(tmpl, n + 1, stop)) |
165 parseres, pos = p.parse(tokenize(tmpl, n + 1, stop)) |
165 parsed.append(parseres) |
166 parsed.append(parseres) |
210 |
211 |
211 def runinteger(context, mapping, data): |
212 def runinteger(context, mapping, data): |
212 return int(data) |
213 return int(data) |
213 |
214 |
214 def runstring(context, mapping, data): |
215 def runstring(context, mapping, data): |
215 return data.decode("string-escape") |
|
216 |
|
217 def runrawstring(context, mapping, data): |
|
218 return data |
216 return data |
219 |
217 |
220 def runsymbol(context, mapping, key): |
218 def runsymbol(context, mapping, key): |
221 v = mapping.get(key) |
219 v = mapping.get(key) |
222 if v is None: |
220 if v is None: |
657 |
655 |
658 # methods to interpret function arguments or inner expressions (e.g. {_(x)}) |
656 # methods to interpret function arguments or inner expressions (e.g. {_(x)}) |
659 exprmethods = { |
657 exprmethods = { |
660 "integer": lambda e, c: (runinteger, e[1]), |
658 "integer": lambda e, c: (runinteger, e[1]), |
661 "string": lambda e, c: (runstring, e[1]), |
659 "string": lambda e, c: (runstring, e[1]), |
662 "rawstring": lambda e, c: (runrawstring, e[1]), |
|
663 "symbol": lambda e, c: (runsymbol, e[1]), |
660 "symbol": lambda e, c: (runsymbol, e[1]), |
664 "template": buildtemplate, |
661 "template": buildtemplate, |
665 "group": lambda e, c: compileexp(e[1], c, exprmethods), |
662 "group": lambda e, c: compileexp(e[1], c, exprmethods), |
666 # ".": buildmember, |
663 # ".": buildmember, |
667 "|": buildfilter, |
664 "|": buildfilter, |