Commit ab31eadc by Chris Wanstrath

delimiter support

parent 76b3c5d1
{{=<% %>=}}
* <% first %>
<%=| |=%>
* | second |
|={{ }}=|
* {{ third }}
import pystache
class Delimiters(pystache.View):
template_path = 'examples'
def first(self):
return "It worked the first time."
def second(self):
return "And it worked the second time."
def third(self):
return "Then, surprisingly, it worked the third time."
import re import re
import cgi import cgi
SECTION_RE = re.compile(r"{{\#([^\}]*)}}\s*(.+?)\s*{{/\1}}", re.M | re.S)
TAG_RE = re.compile(r"{{(#|=|!|<|>|\{)?(.+?)\1?}}+")
class Template(object): class Template(object):
# The regular expression used to find a #section
section_re = None
# The regular expression used to find a tag.
tag_re = None
# Opening tag delimiter
otag = '{{'
# Closing tag delimiter
ctag = '}}'
# Names of different tag modifiers, used to render them.
tag_types = { tag_types = {
None: 'tag', None: 'tag',
'!': 'comment', '!': 'comment',
'{': 'unescaped', '{': 'unescaped',
'>': 'partial' '>': 'partial',
'=': 'delimiter'
} }
def __init__(self, template, context=None): def __init__(self, template, context=None):
self.template = template self.template = template
self.context = context or {} self.context = context or {}
self.compile_regexps()
def render(self, template=None, context=None): def render(self, template=None, context=None):
"""Turns a Mustache template into something wonderful.""" """Turns a Mustache template into something wonderful."""
...@@ -24,10 +36,20 @@ class Template(object): ...@@ -24,10 +36,20 @@ class Template(object):
template = self.render_sections(template, context) template = self.render_sections(template, context)
return self.render_tags(template, context) return self.render_tags(template, context)
def compile_regexps(self):
"""Compiles our section and tag regular expressions."""
tags = { 'otag': re.escape(self.otag), 'ctag': re.escape(self.ctag) }
section = r"%(otag)s\#([^\}]*)%(ctag)s\s*(.+?)\s*%(otag)s/\1%(ctag)s"
self.section_re = re.compile(section % tags, re.M|re.S)
tag = r"%(otag)s(#|=|!|>|\{)?\s*(.+?)\s*\1?%(ctag)s+"
self.tag_re = re.compile(tag % tags)
def render_sections(self, template, context): def render_sections(self, template, context):
"""Expands sections.""" """Expands sections."""
while 1: while 1:
match = SECTION_RE.search(template) match = self.section_re.search(template)
if match is None: if match is None:
break break
...@@ -50,7 +72,7 @@ class Template(object): ...@@ -50,7 +72,7 @@ class Template(object):
def render_tags(self, template, context): def render_tags(self, template, context):
"""Renders all the tags in a template for a context.""" """Renders all the tags in a template for a context."""
while 1: while 1:
match = TAG_RE.search(template) match = self.tag_re.search(template)
if match is None: if match is None:
break break
...@@ -84,3 +106,9 @@ class Template(object): ...@@ -84,3 +106,9 @@ class Template(object):
view.template_name = tag_name view.template_name = tag_name
return view.render() return view.render()
def render_delimiter(self, tag_name=None, context=None):
"""Changes the Mustache delimiter."""
self.otag, self.ctag = tag_name.split(' ')
self.compile_regexps()
return ''
...@@ -6,6 +6,7 @@ from examples.double_section import DoubleSection ...@@ -6,6 +6,7 @@ from examples.double_section import DoubleSection
from examples.escaped import Escaped from examples.escaped import Escaped
from examples.unescaped import Unescaped from examples.unescaped import Unescaped
from examples.template_partial import TemplatePartial from examples.template_partial import TemplatePartial
from examples.delimiters import Delimiters
class TestView(unittest.TestCase): class TestView(unittest.TestCase):
def test_comments(self): def test_comments(self):
...@@ -35,3 +36,13 @@ Again, Welcome!""") ...@@ -35,3 +36,13 @@ Again, Welcome!""")
Again, Welcome! Again, Welcome!
""") """)
def test_delimiters(self):
self.assertEquals(Delimiters().render(), """
* It worked the first time.
* And it worked the second time.
* Then, surprisingly, it worked the third time.
""")
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