templater: directly parse templates, no regexes

This commit is contained in:
Matt Mackall 2010-04-05 14:33:41 -05:00
parent a08ba2f39f
commit 7455c67fcd

View File

@ -6,7 +6,7 @@
# GNU General Public License version 2 or any later version. # GNU General Public License version 2 or any later version.
from i18n import _ from i18n import _
import re, sys, os import sys, os
import util, config, templatefilters import util, config, templatefilters
path = ['templates', '../templates'] path = ['templates', '../templates']
@ -42,8 +42,6 @@ class engine(object):
filter uses function to transform value. syntax is filter uses function to transform value. syntax is
{key|filter1|filter2|...}.''' {key|filter1|filter2|...}.'''
template_re = re.compile(r'{([\w\|%]+)}')
def __init__(self, loader, filters={}, defaults={}): def __init__(self, loader, filters={}, defaults={}):
self.loader = loader self.loader = loader
self.filters = filters self.filters = filters
@ -113,19 +111,29 @@ class engine(object):
v = v(**map) v = v(**map)
return v return v
while tmpl: pos, stop = 0, len(tmpl)
m = self.template_re.search(tmpl) while pos < stop:
if not m: n = tmpl.find('{', pos)
yield tmpl if n < 0:
yield tmpl[pos:stop]
break
if n > 0 and tmpl[n - 1] == '\\':
# escaped
yield tmpl[pos:n + 1]
pos = n + 1
continue
if n > pos:
yield tmpl[pos:n]
pos = n
n = tmpl.find('}', pos)
if n < 0:
# no closing
yield tmpl[pos:stop]
break break
start, end = m.span(0) expr = tmpl[pos + 1:n]
variants = m.groups() pos = n + 1
expr = variants[0] or variants[1]
if start:
yield tmpl[:start]
tmpl = tmpl[end:]
if '%' in expr: if '%' in expr:
yield self._format(expr, get, map) yield self._format(expr, get, map)