--- a/mercurial/templater.py Mon Apr 27 11:35:18 2009 +0200
+++ b/mercurial/templater.py Mon Apr 06 15:09:54 2009 +0200
@@ -21,7 +21,7 @@
return s.decode('string_escape')
-class templater(object):
+class engine(object):
'''template expansion engine.
template expansion works like this. a map file contains key=value
@@ -44,6 +44,68 @@
template_re = re.compile(r"(?:(?:#(?=[\w\|%]+#))|(?:{(?=[\w\|%]+})))"
r"(\w+)(?:(?:%(\w+))|((?:\|\w+)*))[#}]")
+ def __init__(self, loader, filters={}, defaults={}):
+ self.loader = loader
+ self.filters = filters
+ self.defaults = defaults
+
+ 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)]
+ while iters:
+ try:
+ item = iters[0].next()
+ except StopIteration:
+ iters.pop(0)
+ continue
+ if isinstance(item, str):
+ yield item
+ elif item is None:
+ yield ''
+ elif hasattr(item, '__iter__'):
+ iters.insert(0, iter(item))
+ else:
+ yield str(item)
+
+ def _process(self, tmpl, map):
+ '''Render a template. Returns a generator.'''
+ while tmpl:
+ m = self.template_re.search(tmpl)
+ if not m:
+ yield tmpl
+ break
+
+ start, end = m.span(0)
+ key, format, fl = m.groups()
+
+ if start:
+ yield tmpl[:start]
+ tmpl = tmpl[end:]
+
+ if key in map:
+ v = map[key]
+ else:
+ v = self.defaults.get(key, "")
+ if callable(v):
+ v = v(**map)
+ if format:
+ if not hasattr(v, '__iter__'):
+ raise SyntaxError(_("Error expanding '%s%%%s'")
+ % (key, format))
+ lm = map.copy()
+ for i in v:
+ lm.update(i)
+ yield self.process(format, lm)
+ else:
+ if fl:
+ for f in fl.split("|")[1:]:
+ v = self.filters[f](v)
+ yield v
+
+class templater(object):
+
def __init__(self, mapfile, filters={}, defaults={}, cache={},
minchunk=1024, maxchunk=65536):
'''set up template engine.
@@ -79,7 +141,7 @@
def __contains__(self, key):
return key in self.cache or key in self.map
- def _template(self, t):
+ def load(self, t):
'''Get the template for the given template name. Use a local cache.'''
if not t in self.cache:
try:
@@ -89,69 +151,14 @@
(self.map[t], inst.args[1]))
return self.cache[t]
- def _process(self, tmpl, map):
- '''Render a template. Returns a generator.'''
- while tmpl:
- m = self.template_re.search(tmpl)
- if not m:
- yield tmpl
- break
-
- start, end = m.span(0)
- key, format, fl = m.groups()
-
- if start:
- yield tmpl[:start]
- tmpl = tmpl[end:]
-
- if key in map:
- v = map[key]
- else:
- v = self.defaults.get(key, "")
- if callable(v):
- v = v(**map)
- if format:
- if not hasattr(v, '__iter__'):
- raise SyntaxError(_("Error expanding '%s%%%s'")
- % (key, format))
- lm = map.copy()
- for i in v:
- lm.update(i)
- t = self._template(format)
- yield self._process(t, lm)
- else:
- if fl:
- for f in fl.split("|")[1:]:
- v = self.filters[f](v)
- yield v
-
def __call__(self, t, **map):
- stream = self.expand(t, **map)
+ proc = engine(self.load, self.filters, self.defaults)
+ stream = proc.process(t, map)
if self.minchunk:
stream = util.increasingchunks(stream, min=self.minchunk,
max=self.maxchunk)
return stream
- def expand(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._template(t)
- iters = [self._process(tmpl, map)]
- while iters:
- try:
- item = iters[0].next()
- except StopIteration:
- iters.pop(0)
- continue
- if isinstance(item, str):
- yield item
- elif item is None:
- yield ''
- elif hasattr(item, '__iter__'):
- iters.insert(0, iter(item))
- else:
- yield str(item)
-
def templatepath(name=None):
'''return location of template file or directory (if no name).
returns None if not found.'''