Commit a3999641 by Chris Jerdonek

More progress on removing RenderEngine from Parser.

parent f94aa621
...@@ -14,6 +14,7 @@ from pystache.parsed import ParsedTemplate ...@@ -14,6 +14,7 @@ from pystache.parsed import ParsedTemplate
DEFAULT_DELIMITERS = (u'{{', u'}}') DEFAULT_DELIMITERS = (u'{{', u'}}')
END_OF_LINE_CHARACTERS = [u'\r', u'\n'] END_OF_LINE_CHARACTERS = [u'\r', u'\n']
NON_BLANK_RE = re.compile(ur'^(.)', re.M)
def _compile_template_re(delimiters=None): def _compile_template_re(delimiters=None):
...@@ -52,13 +53,31 @@ class ParsingError(Exception): ...@@ -52,13 +53,31 @@ class ParsingError(Exception):
pass 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): class VariableNode(object):
def __init__(self, key): def __init__(self, key):
self.key = key self.key = key
def render(self, engine, context): def render(self, engine, context):
s = engine._get_string_value(context, self.key) s = engine.fetch_string(context, self.key)
return engine.escape(s) return engine.escape(s)
...@@ -68,10 +87,41 @@ class LiteralNode(object): ...@@ -68,10 +87,41 @@ class LiteralNode(object):
self.key = key self.key = key
def render(self, engine, context): def render(self, engine, context):
s = engine._get_string_value(context, self.key) s = engine.fetch_string(context, self.key)
return engine.literal(s) 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): class Parser(object):
_delimiters = None _delimiters = None
...@@ -204,12 +254,12 @@ class Parser(object): ...@@ -204,12 +254,12 @@ class Parser(object):
""" """
# TODO: switch to using a dictionary instead of a bunch of ifs and elifs. # TODO: switch to using a dictionary instead of a bunch of ifs and elifs.
if tag_type == '!': if tag_type == '!':
return u'' return CommentNode()
if tag_type == '=': if tag_type == '=':
delimiters = tag_key.split() delimiters = tag_key.split()
self._change_delimiters(delimiters) self._change_delimiters(delimiters)
return u'' return ChangeNode(delimiters)
if tag_type == '': if tag_type == '':
return VariableNode(tag_key) return VariableNode(tag_key)
...@@ -218,7 +268,7 @@ class Parser(object): ...@@ -218,7 +268,7 @@ class Parser(object):
return LiteralNode(tag_key) return LiteralNode(tag_key)
if tag_type == '>': 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)) raise Exception("Invalid symbol for interpolation tag: %s" % repr(tag_type))
...@@ -233,6 +283,6 @@ class Parser(object): ...@@ -233,6 +283,6 @@ class Parser(object):
template, section_start_index, section_end_index) template, section_start_index, section_end_index)
if tag_type == '^': 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)) raise Exception("Invalid symbol for section tag: %s" % repr(tag_type))
...@@ -11,9 +11,6 @@ from pystache.common import is_string ...@@ -11,9 +11,6 @@ from pystache.common import is_string
from pystache.parser import Parser from pystache.parser import Parser
NON_BLANK_RE = re.compile(ur'^(.)', re.M)
def context_get(stack, name): def context_get(stack, name):
""" """
Find and return a name from a ContextStack instance. Find and return a name from a ContextStack instance.
...@@ -90,7 +87,7 @@ class RenderEngine(object): ...@@ -90,7 +87,7 @@ class RenderEngine(object):
# The returned value MUST be rendered against the default delimiters, # The returned value MUST be rendered against the default delimiters,
# then interpolated in place of the lambda. # 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. Get a value from the given context as a basestring instance.
...@@ -106,38 +103,6 @@ class RenderEngine(object): ...@@ -106,38 +103,6 @@ class RenderEngine(object):
return val 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 # TODO: the template_ and parsed_template_ arguments don't both seem
# to be necessary. Can we remove one of them? For example, if # to be necessary. Can we remove one of them? For example, if
# callable(data) is True, then the initial parsed_template isn't used. # 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