summaryrefslogtreecommitdiff
path: root/pystache
diff options
context:
space:
mode:
authorChris Jerdonek <chris.jerdonek@gmail.com>2012-05-05 13:26:22 -0700
committerChris Jerdonek <chris.jerdonek@gmail.com>2012-05-05 13:26:22 -0700
commita3999641857c1e7b620f3a2513576b493a6101d8 (patch)
tree4db7ec79b404dcb3198b65d7346b1251f86db139 /pystache
parentf94aa621f125d59ebaf19e9bf110e23a04a10637 (diff)
downloadpystache-a3999641857c1e7b620f3a2513576b493a6101d8.tar.gz
More progress on removing RenderEngine from Parser.
Diffstat (limited to 'pystache')
-rw-r--r--pystache/parser.py62
-rw-r--r--pystache/renderengine.py37
2 files changed, 57 insertions, 42 deletions
diff --git a/pystache/parser.py b/pystache/parser.py
index cb12306..ad542c3 100644
--- a/pystache/parser.py
+++ b/pystache/parser.py
@@ -14,6 +14,7 @@ from pystache.parsed import ParsedTemplate
DEFAULT_DELIMITERS = (u'{{', u'}}')
END_OF_LINE_CHARACTERS = [u'\r', u'\n']
+NON_BLANK_RE = re.compile(ur'^(.)', re.M)
def _compile_template_re(delimiters=None):
@@ -52,13 +53,31 @@ class ParsingError(Exception):
pass
+## Node types
+
+
+class CommentNode(object):
+
+ def render(self, engine, context):
+ return u''
+
+
+class ChangeNode(object):
+
+ def __init__(self, delimiters):
+ self.delimiters = delimiters
+
+ def render(self, engine, context):
+ return u''
+
+
class VariableNode(object):
def __init__(self, key):
self.key = key
def render(self, engine, context):
- s = engine._get_string_value(context, self.key)
+ s = engine.fetch_string(context, self.key)
return engine.escape(s)
@@ -68,10 +87,41 @@ class LiteralNode(object):
self.key = key
def render(self, engine, context):
- s = engine._get_string_value(context, self.key)
+ s = engine.fetch_string(context, self.key)
return engine.literal(s)
+class PartialNode(object):
+
+ def __init__(self, key, indent):
+ self.key = key
+ self.indent = indent
+
+ def render(self, engine, context):
+ template = engine.resolve_partial(self.key)
+ # Indent before rendering.
+ template = re.sub(NON_BLANK_RE, self.indent + ur'\1', template)
+
+ return engine.render(template, context)
+
+
+class InvertedNode(object):
+
+ def __init__(self, key, parsed_section):
+ self.key = key
+ self.parsed_section = parsed_section
+
+ def render(self, engine, context):
+ # TODO: is there a bug because we are not using the same
+ # logic as in fetch_string()?
+ data = engine.resolve_context(context, self.key)
+ # Note that lambdas are considered truthy for inverted sections
+ # per the spec.
+ if data:
+ return u''
+ return engine._render_parsed(self.parsed_section, context)
+
+
class Parser(object):
_delimiters = None
@@ -204,12 +254,12 @@ class Parser(object):
"""
# TODO: switch to using a dictionary instead of a bunch of ifs and elifs.
if tag_type == '!':
- return u''
+ return CommentNode()
if tag_type == '=':
delimiters = tag_key.split()
self._change_delimiters(delimiters)
- return u''
+ return ChangeNode(delimiters)
if tag_type == '':
return VariableNode(tag_key)
@@ -218,7 +268,7 @@ class Parser(object):
return LiteralNode(tag_key)
if tag_type == '>':
- return self.engine._make_get_partial(tag_key, leading_whitespace)
+ return PartialNode(tag_key, leading_whitespace)
raise Exception("Invalid symbol for interpolation tag: %s" % repr(tag_type))
@@ -233,6 +283,6 @@ class Parser(object):
template, section_start_index, section_end_index)
if tag_type == '^':
- return self.engine._make_get_inverse(tag_key, parsed_section)
+ return InvertedNode(tag_key, parsed_section)
raise Exception("Invalid symbol for section tag: %s" % repr(tag_type))
diff --git a/pystache/renderengine.py b/pystache/renderengine.py
index 80f795d..39b536c 100644
--- a/pystache/renderengine.py
+++ b/pystache/renderengine.py
@@ -11,9 +11,6 @@ from pystache.common import is_string
from pystache.parser import Parser
-NON_BLANK_RE = re.compile(ur'^(.)', re.M)
-
-
def context_get(stack, name):
"""
Find and return a name from a ContextStack instance.
@@ -90,7 +87,7 @@ class RenderEngine(object):
# The returned value MUST be rendered against the default delimiters,
# then interpolated in place of the lambda.
#
- def _get_string_value(self, context, tag_name):
+ def fetch_string(self, context, tag_name):
"""
Get a value from the given context as a basestring instance.
@@ -106,38 +103,6 @@ class RenderEngine(object):
return val
- def _make_get_partial(self, tag_key, leading_whitespace):
-
- template = self.resolve_partial(tag_key)
- # Indent before rendering.
- template = re.sub(NON_BLANK_RE, leading_whitespace + ur'\1', template)
-
- def get_partial(context):
- """
- Returns: a string of type unicode.
-
- """
- # TODO: can we do the parsing before calling this function?
- return self.render(template, context)
-
- return get_partial
-
- def _make_get_inverse(self, name, parsed_template):
- def get_inverse(context):
- """
- Returns a string with type unicode.
-
- """
- # TODO: is there a bug because we are not using the same
- # logic as in _get_string_value()?
- data = self.resolve_context(context, name)
- # Per the spec, lambdas in inverted sections are considered truthy.
- if data:
- return u''
- return self._render_parsed(parsed_template, context)
-
- return get_inverse
-
# TODO: the template_ and parsed_template_ arguments don't both seem
# to be necessary. Can we remove one of them? For example, if
# callable(data) is True, then the initial parsed_template isn't used.