Mercurial > hg
changeset 10845:9d8194c2fcbd
templater: preparse templates and cache
This breaks templates down into a list of literal and {} groups, with
group types preidentified.
author | Matt Mackall <mpm@selenic.com> |
---|---|
date | Mon, 05 Apr 2010 15:25:08 -0500 |
parents | 6722ba3bf80b |
children | 594140b1e12d |
files | mercurial/templater.py |
diffstat | 1 files changed, 53 insertions(+), 33 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/templater.py Mon Apr 05 15:25:08 2010 -0500 +++ b/mercurial/templater.py Mon Apr 05 15:25:08 2010 -0500 @@ -47,12 +47,16 @@ self.filters = filters self.defaults = defaults self.cache = {} + self.parsecache = {} def process(self, t, map): '''Perform expansion. t is name of map element to expand. map contains added elements for use during expansion. Is a generator.''' - tmpl = self.loader(t) - iters = [self._process(tmpl, map)] + if t not in self.parsecache: + tmpl = self.loader(t) + self.parsecache[t] = self._parse(tmpl) + parsed = self.parsecache[t] + iters = [self._process(parsed, map)] while iters: try: item = iters[0].next() @@ -100,7 +104,44 @@ self.cache[expr] = apply return self.cache[expr](get) - def _process(self, tmpl, map): + def _parse(self, tmpl): + '''preparse a template''' + + parsed = [] + pos, stop = 0, len(tmpl) + while pos < stop: + n = tmpl.find('{', pos) + if n < 0: + parsed.append(('', tmpl[pos:stop])) + break + if n > 0 and tmpl[n - 1] == '\\': + # escaped + parsed.append(('', tmpl[pos:n + 1])) + pos = n + 1 + continue + if n > pos: + parsed.append(('', tmpl[pos:n])) + + pos = n + n = tmpl.find('}', pos) + if n < 0: + # no closing + parsed.append(('', tmpl[pos:stop])) + break + + expr = tmpl[pos + 1:n] + pos = n + 1 + + if '%' in expr: + parsed.append(('%', expr)) + elif '|' in expr: + parsed.append(('|', expr)) + else: + parsed.append(('g', expr)) + + return parsed + + def _process(self, parsed, map): '''Render a template. Returns a generator.''' def get(key): @@ -111,36 +152,15 @@ v = v(**map) return v - pos, stop = 0, len(tmpl) - while pos < stop: - n = tmpl.find('{', pos) - 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 - - expr = tmpl[pos + 1:n] - pos = n + 1 - - if '%' in expr: - yield self._format(expr, get, map) - elif '|' in expr: - yield self._filter(expr, get, map) - else: - yield get(expr) + for t, e in parsed: + if not t: + yield e + elif t is '|': + yield self._filter(e, get, map) + elif t is '%': + yield self._format(e, get, map) + elif t is 'g': + yield get(e) engines = {'default': engine}