Commit 3da797f9 by Chris Jerdonek

More minor refactorings.

parent 46ffcc2e
...@@ -7,6 +7,7 @@ import types ...@@ -7,6 +7,7 @@ import types
END_OF_LINE_CHARACTERS = ['\r', '\n'] END_OF_LINE_CHARACTERS = ['\r', '\n']
# TODO: what are the possibilities for val?
def call(val, view, template=None): def call(val, view, template=None):
if callable(val): if callable(val):
(args, _, _, _) = inspect.getargspec(val) (args, _, _, _) = inspect.getargspec(val)
...@@ -44,15 +45,28 @@ def parse_to_tree(template, view, delims=('{{', '}}')): ...@@ -44,15 +45,28 @@ def parse_to_tree(template, view, delims=('{{', '}}')):
return template.parse_to_tree() return template.parse_to_tree()
def render_parse_tree(parse_tree, view, template): def render_parse_tree(parse_tree, view, template):
"""
Convert a parse-tree into a string.
"""
get_string = lambda val: call(val, view, template) get_string = lambda val: call(val, view, template)
parts = map(get_string, parse_tree) parts = map(get_string, parse_tree)
return ''.join(parts) return ''.join(parts)
def render(template, view, delims=('{{', '}}')): def render(template, view, delims=('{{', '}}')):
"""
Arguments:
template: template string
view: context
"""
parse_tree = parse_to_tree(template, view, delims) parse_tree = parse_to_tree(template, view, delims)
return render_parse_tree(parse_tree, view, template) return render_parse_tree(parse_tree, view, template)
## The possible function parse-tree elements:
def partialTag(name, indentation=''): def partialTag(name, indentation=''):
def func(self): def func(self):
nonblank = re.compile(r'^(.)', re.M) nonblank = re.compile(r'^(.)', re.M)
...@@ -60,14 +74,16 @@ def partialTag(name, indentation=''): ...@@ -60,14 +74,16 @@ def partialTag(name, indentation=''):
return render(template, self) return render(template, self)
return func return func
def sectionTag(name, parse_tree_, template, delims): def sectionTag(name, parse_tree_, template_, delims):
def func(self): def func(self):
template = template_
parse_tree = parse_tree_ parse_tree = parse_tree_
data = self.get(name) data = self.get(name)
if not data: if not data:
return '' return ''
elif callable(data): elif callable(data):
parse_tree = parse_to_tree(call(view=self, val=data, template=template), self, delims) template = call(val=data, view=self, template=template)
parse_tree = parse_to_tree(template, self, delims)
data = [ data ] data = [ data ]
elif type(data) not in [list, tuple]: elif type(data) not in [list, tuple]:
data = [ data ] data = [ data ]
...@@ -153,16 +169,21 @@ class Template(object): ...@@ -153,16 +169,21 @@ class Template(object):
if match is None: if match is None:
break break
index = self._handle_match(template, match, parse_tree, start_index) captures = match.groupdict()
match_index = match.end('content')
end_index = match.end()
index = self._handle_match(parse_tree, captures, start_index, match_index, end_index)
# Save the rest of the template. # Save the rest of the template.
parse_tree.append(template[index:]) parse_tree.append(template[index:])
return parse_tree return parse_tree
def _handle_match(self, template, match, parse_tree, start_index): def _handle_match(self, parse_tree, captures, start_index, match_index, end_index):
template = self.template
# Normalize the captures dictionary. # Normalize the captures dictionary.
captures = match.groupdict()
if captures['change'] is not None: if captures['change'] is not None:
captures.update(tag='=', name=captures['delims']) captures.update(tag='=', name=captures['delims'])
elif captures['raw'] is not None: elif captures['raw'] is not None:
...@@ -170,9 +191,6 @@ class Template(object): ...@@ -170,9 +191,6 @@ class Template(object):
parse_tree.append(captures['content']) parse_tree.append(captures['content'])
match_index = match.end('content')
end_index = match.end()
# Standalone (non-interpolation) tags consume the entire line, # Standalone (non-interpolation) tags consume the entire line,
# both leading whitespace and trailing newline. # both leading whitespace and trailing newline.
did_tag_begin_line = match_index == 0 or template[match_index - 1] in END_OF_LINE_CHARACTERS did_tag_begin_line = match_index == 0 or template[match_index - 1] in END_OF_LINE_CHARACTERS
...@@ -190,15 +208,19 @@ class Template(object): ...@@ -190,15 +208,19 @@ class Template(object):
captures['whitespace'] = '' captures['whitespace'] = ''
name = captures['name'] name = captures['name']
if captures['tag'] == '!': if captures['tag'] == '!':
pass return end_index
elif captures['tag'] == '=':
if captures['tag'] == '=':
self.otag, self.ctag = name.split() self.otag, self.ctag = name.split()
self._compile_regexps() self._compile_regexps()
elif captures['tag'] == '>': return end_index
if captures['tag'] == '>':
func = partialTag(name, captures['whitespace']) func = partialTag(name, captures['whitespace'])
parse_tree.append(func)
elif captures['tag'] in ['#', '^']: elif captures['tag'] in ['#', '^']:
try: try:
self.parse_to_tree(index=end_index) self.parse_to_tree(index=end_index)
except EndOfSection as e: except EndOfSection as e:
...@@ -206,23 +228,27 @@ class Template(object): ...@@ -206,23 +228,27 @@ class Template(object):
tmpl = e.template tmpl = e.template
end_index = e.position end_index = e.position
tag = { '#': sectionTag, '^': inverseTag }[captures['tag']] tag = sectionTag if captures['tag'] == '#' else inverseTag
parse_tree.append(tag(name, bufr, tmpl, (self.otag, self.ctag))) func = tag(name, bufr, tmpl, (self.otag, self.ctag))
elif captures['tag'] == '/':
raise EndOfSection(parse_tree, template[start_index:match_index], end_index)
elif captures['tag'] in ['{', '&']: elif captures['tag'] in ['{', '&']:
func = literal_tag_function(name) func = literal_tag_function(name)
parse_tree.append(func)
elif captures['tag'] == '': elif captures['tag'] == '':
func = escape_tag_function(name) func = escape_tag_function(name)
parse_tree.append(func)
elif captures['tag'] == '/':
# TODO: don't use exceptions for flow control.
raise EndOfSection(parse_tree, template[start_index:match_index], end_index)
else: else:
raise Exception("'%s' is an unrecognized type!" % captures['tag']) raise Exception("'%s' is an unrecognized type!" % captures['tag'])
parse_tree.append(func)
return end_index return end_index
def render(self, encoding=None): def render(self, encoding=None):
......
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