summaryrefslogtreecommitdiff
path: root/coverage/templite.py
diff options
context:
space:
mode:
authorNed Batchelder <ned@nedbatchelder.com>2009-10-26 06:44:48 -0400
committerNed Batchelder <ned@nedbatchelder.com>2009-10-26 06:44:48 -0400
commit2b844b45cce89e0373eefbba5d929f5991b35190 (patch)
tree3a2e21120c3d67e431275f3512fe99bec67e4827 /coverage/templite.py
parent5ea96997a9b50786d41cbbcb579151b80a718cb2 (diff)
downloadpython-coveragepy-git-2b844b45cce89e0373eefbba5d929f5991b35190.tar.gz
Cleanup and commenting in Templite.
Diffstat (limited to 'coverage/templite.py')
-rw-r--r--coverage/templite.py40
1 files changed, 26 insertions, 14 deletions
diff --git a/coverage/templite.py b/coverage/templite.py
index c0c1b1da..258f3fa6 100644
--- a/coverage/templite.py
+++ b/coverage/templite.py
@@ -38,40 +38,51 @@ class Templite(object):
self.context.update(context)
# Split the text to form a list of tokens.
- toks = re.split(
- r"(?s)({{.*?}}|{%.*?%}|{#.*?#})", text
- )
+ toks = re.split(r"(?s)({{.*?}}|{%.*?%}|{#.*?#})", text)
- # Parse the tokens into a nested list of operations.
- stack = []
+ # Parse the tokens into a nested list of operations. Each item in the
+ # list is a tuple with an opcode, and arguments. They'll be
+ # interpreted by TempliteEngine.
+ #
+ # When parsing an action tag with nested content (if, for), the current
+ # ops list is pushed onto ops_stack, and the parsing continues in a new
+ # ops list that is part of the arguments to the if or for op.
ops = []
+ ops_stack = []
for tok in toks:
if tok.startswith('{{'):
- ops.append(('var', tok[2:-2].strip()))
+ # Expression: ('exp', expr)
+ ops.append(('exp', tok[2:-2].strip()))
elif tok.startswith('{#'):
+ # Comment: ignore it and move on.
continue
elif tok.startswith('{%'):
+ # Action tag: split into words and parse further.
words = tok[2:-2].strip().split()
if words[0] == 'if':
+ # If: ('if', (expr, body_ops))
if_ops = []
assert len(words) == 2
ops.append(('if', (words[1], if_ops)))
- stack.append(ops)
+ ops_stack.append(ops)
ops = if_ops
elif words[0] == 'for':
+ # For: ('for', (varname, listexpr, body_ops))
assert len(words) == 4 and words[2] == 'in'
for_ops = []
ops.append(('for', (words[1], words[3], for_ops)))
- stack.append(ops)
+ ops_stack.append(ops)
ops = for_ops
elif words[0].startswith('end'):
- ops = stack.pop()
+ # Endsomething. Pop the ops stack
+ ops = ops_stack.pop()
assert ops[-1][0] == words[0][3:]
+ else:
+ raise Exception("Don't understand tag %r" % words)
else:
ops.append(('lit', tok))
- assert not stack
-
+ assert not ops_stack, "Unmatched action tag: %r" % ops_stack[-1][0]
self.ops = ops
def render(self, context=None):
@@ -84,7 +95,8 @@ class Templite(object):
ctx = dict(self.context)
if context:
ctx.update(context)
-
+
+ # Run it through an engine, and return the result.
engine = _TempliteEngine(ctx)
engine.execute(self.ops)
return engine.result
@@ -105,7 +117,7 @@ class _TempliteEngine(object):
for op, args in ops:
if op == 'lit':
self.result += args
- elif op == 'var':
+ elif op == 'exp':
self.result += str(self.evaluate(args))
elif op == 'if':
expr, body = args
@@ -118,7 +130,7 @@ class _TempliteEngine(object):
self.context[var] = val
self.execute(body)
else:
- self.result += "???"
+ raise Exception("TempliteEngine doesn't grok op %r" % op)
def evaluate(self, expr):
"""Evaluate an expression.