Commit 327c8837 by Pieter van de Bruggen

*Very* rough first pass at section tags.

parent 00c93935
import re
import cgi
def call(view):
def _(x):
return unicode(callable(x) and x(view) or x)
return _
def sectionTag(name, template, delims):
def func(view):
if not view.get(name):
return ''
print template
tmpl = Template(template)
tmpl.view = view
(tmpl.otag, tmpl.ctag) = delims
view.context_list = [view.get(name)] + view.context_list
string = ''.join(map(call(view), tmpl._parse()))
return string
return func
def inverseTag(name, template, delims):
def func(view):
if view.get(name):
return ''
tmpl = Template(template)
tmpl.view = view
(tmpl.otag, tmpl.ctag) = delims
return ''.join(map(call(view), tmpl._parse()))
return func
def escapedTag(name):
def func(view):
return cgi.escape(unicode(view.get(name)), True)
......@@ -11,6 +39,11 @@ def unescapedTag(name):
return unicode(view.get(name))
return func
class EndOfSection(Exception):
def __init__(self, template, position):
self.template = template
self.position = position
class Template(object):
tag_re = None
otag, ctag = '{{', '}}'
......@@ -41,9 +74,10 @@ class Template(object):
"""
self.tag_re = re.compile(tag % tags, re.M | re.X)
def _parse(self, template, section=None, index=0):
def _parse(self, template=None, section=None, index=0):
"""Parse a template into a syntax tree."""
template = template != None and template or self.template
buffer = []
pos = index
......@@ -53,14 +87,14 @@ class Template(object):
if match is None:
break
pos = self._handle_match(template, match, buffer)
pos = self._handle_match(template, match, buffer, index)
# Save the rest of the template.
buffer.append(template[pos:])
return buffer
def _handle_match(self, template, match, buffer):
def _handle_match(self, template, match, buffer, index):
# Normalize the captures dictionary.
captures = match.groupdict()
if captures['change'] is not None:
......@@ -92,6 +126,17 @@ class Template(object):
self._compile_regexps()
elif captures['tag'] == '>':
buffer += self._parse(self.view.partial(name))
elif captures['tag'] in ['#', '^']:
try:
self._parse(template, name, pos)
except EndOfSection as e:
tmpl = e.template
pos = e.position
tag = { '#': sectionTag, '^': inverseTag }[captures['tag']]
buffer.append(tag(name, tmpl, (self.otag, self.ctag)))
elif captures['tag'] == '/':
raise EndOfSection(template[index:match.end('whitespace')], pos)
elif captures['tag'] in ['{', '&']:
buffer.append(unescapedTag(name))
elif captures['tag'] == '':
......@@ -102,13 +147,8 @@ class Template(object):
return pos
def render(self, encoding=None):
parsed = self._parse(self.template)
def call(x):
return unicode(callable(x) and x(self.view) or x)
result = ''.join(map(call, parsed))
parsed = self._parse()
result = ''.join(map(call(self.view), parsed))
if encoding is not None:
result = result.encode(encoding)
......
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