Commit a3999641 by Chris Jerdonek

More progress on removing RenderEngine from Parser.

parent f94aa621
......@@ -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))
......@@ -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.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment