-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrender.py
More file actions
72 lines (59 loc) · 2.21 KB
/
Copy pathrender.py
File metadata and controls
72 lines (59 loc) · 2.21 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Author: yhf
# @Date: 2015-04-20 18:23:27
# @Last Modified by: yhf
# @Last Modified time: 2015-04-21 16:59:04
from tokenizer import TOKEN_REGEX, _Fragment
from parser import _Root, _Text, _Variable, _Each, _If, _Else, _Call
from error import TemplateError, TemplateSyntaxError
from tokenizer import tokenize, VAR_FRAGMENT, BLOCK_FRAGMENT_START, BLOCK_FRAGMENT_END, TEXT_FRAGMENT
class Compiler(object):
def __init__(self, template_string):
self.template_string = template_string
def compile(self):
root = _Root()
scope_stack = [root]
for fragment in tokenize(self.template_string):
if not scope_stack:
raise TemplateError('nesting issues')
parent_scope = scope_stack[-1]
if fragment.type == BLOCK_FRAGMENT_END:
parent_scope.exit_scope()
scope_stack.pop()
continue
new_node = self.create_node(fragment)
if new_node:
parent_scope.children.append(new_node)
if new_node.creates_scope:
scope_stack.append(new_node)
new_node.enter_scope()
return root
def create_node(self, fragment):
node_class = None
if fragment.type == TEXT_FRAGMENT:
node_class = _Text
elif fragment.type == VAR_FRAGMENT:
node_class = _Variable
elif fragment.type == BLOCK_FRAGMENT_START:
cmd = fragment.clean_text.split()[0]
if cmd == 'each':
node_class = _Each
elif cmd == 'if':
node_class = _If
elif cmd == 'else':
node_class = _Else
elif cmd == 'call':
node_class = _Call
if node_class is None:
raise TemplateSyntaxError(fragment)
return node_class(fragment.clean_text)
class Template(object):
def __init__(self, contents):
self.contents = contents
self.root = Compiler(contents).compile()
def render(self, **kwargs):
return self.root.render(kwargs)
if __name__ == '__main__':
template = Template("{{ a }}")
print template.render(a=1)