]> Devi Nivas Git - chevron.git/commitdiff
Added a render function
authornoah morrison <noah@morrison.ph>
Sat, 1 Nov 2014 19:20:45 +0000 (15:20 -0400)
committernoah morrison <noah@morrison.ph>
Sat, 1 Nov 2014 19:20:45 +0000 (15:20 -0400)
Render takes a template and data dictionary and returns
a mustache rendered string.

Also updated the test.mustache and added a partial.mustache file.

chevron.py
data.json
partial.mustache [new file with mode: 0644]
test.mustache

index 2b2373f4a00a1161b542ddb39f76661e3c0cf9bc..71c0b90e6ce54e9daeeadcc25f4f03d8e02d765a 100755 (executable)
@@ -1,7 +1,10 @@
 #!/usr/bin/python
 
+import json
+
 from sys import argv
 from io import StringIO
+from cgi import escape as html_escape
 
 
 def tokenize(template):
@@ -80,6 +83,8 @@ def tokenize(template):
             return
 
         if literal:
+            if len(literal) > 1 and literal.startswith('\n'):
+                literal = literal[1:]
             yield ('literal', literal)
 
         tag_type = tag_types.get(peek(0, 1), 'variable')
@@ -114,11 +119,63 @@ def tokenize(template):
         raise UnclosedSection()
 
 
+def render(template, data, partials_path='.', partials_ext='mustache'):
+    def get_key(key):
+        for scope in scopes:
+            try:
+                for key in key.split('.'):
+                    scope = scope[key]
+                return scope
+            except (TypeError, KeyError):
+                pass
+
+    def get_partial(path):
+        return partials_path + '/' + path + '.' + partials_ext
+
+    tokens = tokenize(template)
+
+    output = ''
+    if type(data) is list:
+        scopes = data
+    else:
+        scopes = [data]
+
+    for tag, key in tokens:
+        if tag == 'end':
+            scopes = scopes[1:]
+
+        elif not scopes[0]:
+            pass
+
+        elif tag == 'literal':
+            output += key
+
+        elif tag == 'variable':
+            output += html_escape(get_key(key))
+
+        elif tag == 'no escape':
+            output += get_key(key)
+
+        elif tag == 'section':
+            scope = get_key(key)
+            scopes.insert(0, scope)
+
+        elif tag == 'inverted section':
+            scope = get_key(key)
+            scopes.insert(0, not scope)
+
+        elif tag == 'partial':
+            partial = get_partial(key)
+            output += render(open(partial, 'r'), scopes)
+
+        else:
+            print('>>', tag)
+
+    return output
+
 if __name__ == '__main__':
     data = argv[1]
     template = argv[2]
 
-    tokens = tokenize(open(template, 'r'))
-
-    for token in tokens:
-        print(token)
+    output = render(open(template, 'r'), json.load(open(data, 'r')))
+    print(output)
index c2a89b01a8266797e134df9acbc9dd39edfd3ef0..b68ba41824294f76b68ca5099b1a3b68832fed18 100644 (file)
--- a/data.json
+++ b/data.json
@@ -3,5 +3,9 @@
   "html_escaped": "<b>no escape!</b>",
   "html_escaped2": "<i>ok</i>",
   "show": true,
-  "delimiter": "custom delimiters work!"
+  "delimiter": {
+    "1": "do delimiters work?",
+    "2": "yes they do!"
+  },
+  "excited": "!!!"
 }
diff --git a/partial.mustache b/partial.mustache
new file mode 100644 (file)
index 0000000..55bd722
--- /dev/null
@@ -0,0 +1 @@
+this is a partial{{excited}}
index fb705ffebcc2ee6f234e445b86424dc84c44ea88..095ca644ddb98560f4c26f597d61782d04383808 100644 (file)
@@ -12,17 +12,17 @@ Show is true!
 {{/show}}
 
 {{^show}}
-Show if false!
+Show is false!
 {{/show}}
 
 {{> partial}}
 
 {{=<< >>=}}
 
-<<delimiter>>
+<<delimiter.1>>
 
 <<={{ }}=>>
 
-{{delimiter}}
+{{delimiter.2}}
 
 That's all folks!