aboutsummaryrefslogtreecommitdiff
path: root/imports/codemirror/mode/smarty
diff options
context:
space:
mode:
authorJon Reid2012-05-04 14:56:24 -0700
committerJon Reid2012-05-04 14:56:24 -0700
commita6dd2917edcfeca1be7553e03281ddd538422ae1 (patch)
treee6846626bf1e967e80bcd652f6a76bb97abb1789 /imports/codemirror/mode/smarty
parent7fc185cc08b2ba912dbc7bce96f6a465c1dd6dbf (diff)
parent8964e070fa760d23c2de272ca36b8d9beba6007d (diff)
downloadninja-a6dd2917edcfeca1be7553e03281ddd538422ae1.tar.gz
Merge remote-tracking branch 'ninja-jduran/TimelineUber' into timeline-local
Diffstat (limited to 'imports/codemirror/mode/smarty')
-rw-r--r--imports/codemirror/mode/smarty/index.html82
-rw-r--r--imports/codemirror/mode/smarty/smarty.js148
2 files changed, 230 insertions, 0 deletions
diff --git a/imports/codemirror/mode/smarty/index.html b/imports/codemirror/mode/smarty/index.html
new file mode 100644
index 00000000..ad4dccf0
--- /dev/null
+++ b/imports/codemirror/mode/smarty/index.html
@@ -0,0 +1,82 @@
1<!doctype html>
2<html>
3 <head>
4 <title>CodeMirror: Smarty mode</title>
5 <link rel="stylesheet" href="../../lib/codemirror.css">
6 <script src="../../lib/codemirror.js"></script>
7 <script src="smarty.js"></script>
8 <style type="text/css">.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
9 <link rel="stylesheet" href="../../doc/docs.css">
10 </head>
11 <body>
12 <h1>CodeMirror: Smarty mode</h1>
13
14 <form><textarea id="code" name="code">
15{extends file="parent.tpl"}
16{include file="template.tpl"}
17
18{* some example Smarty content *}
19{if isset($name) && $name == 'Blog'}
20 This is a {$var}.
21 {$integer = 451}, {$array[] = "a"}, {$stringvar = "string"}
22 {assign var='bob' value=$var.prop}
23{elseif $name == $foo}
24 {function name=menu level=0}
25 {foreach $data as $entry}
26 {if is_array($entry)}
27 - {$entry@key}
28 {menu data=$entry level=$level+1}
29 {else}
30 {$entry}
31 {/if}
32 {/foreach}
33 {/function}
34{/if}</textarea></form>
35
36 <script>
37 var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
38 lineNumbers: true,
39 mode: "smarty"
40 });
41 </script>
42
43 <br />
44
45 <form><textarea id="code2" name="code2">
46{--extends file="parent.tpl"--}
47{--include file="template.tpl"--}
48
49{--* some example Smarty content *--}
50{--if isset($name) && $name == 'Blog'--}
51 This is a {--$var--}.
52 {--$integer = 451--}, {--$array[] = "a"--}, {--$stringvar = "string"--}
53 {--assign var='bob' value=$var.prop--}
54{--elseif $name == $foo--}
55 {--function name=menu level=0--}
56 {--foreach $data as $entry--}
57 {--if is_array($entry)--}
58 - {--$entry@key--}
59 {--menu data=$entry level=$level+1--}
60 {--else--}
61 {--$entry--}
62 {--/if--}
63 {--/foreach--}
64 {--/function--}
65{--/if--}</textarea></form>
66
67 <script>
68 var editor = CodeMirror.fromTextArea(document.getElementById("code2"), {
69 lineNumbers: true,
70 mode: {
71 name: "smarty",
72 leftDelimiter: "{--",
73 rightDelimiter: "--}"
74 }
75 });
76 </script>
77
78 <p>A plain text/Smarty mode which allows for custom delimiter tags (defaults to <b>{</b> and <b>}</b>).</p>
79
80 <p><strong>MIME types defined:</strong> <code>text/x-smarty</code></p>
81 </body>
82</html>
diff --git a/imports/codemirror/mode/smarty/smarty.js b/imports/codemirror/mode/smarty/smarty.js
new file mode 100644
index 00000000..9da7da62
--- /dev/null
+++ b/imports/codemirror/mode/smarty/smarty.js
@@ -0,0 +1,148 @@
1CodeMirror.defineMode("smarty", function(config, parserConfig) {
2 var keyFuncs = ["debug", "extends", "function", "include", "literal"];
3 var last;
4 var regs = {
5 operatorChars: /[+\-*&%=<>!?]/,
6 validIdentifier: /[a-zA-Z0-9\_]/,
7 stringChar: /[\'\"]/
8 }
9 var leftDelim = (typeof config.mode.leftDelimiter != 'undefined') ? config.mode.leftDelimiter : "{";
10 var rightDelim = (typeof config.mode.rightDelimiter != 'undefined') ? config.mode.rightDelimiter : "}";
11 function ret(style, lst) { last = lst; return style; }
12
13
14 function tokenizer(stream, state) {
15 function chain(parser) {
16 state.tokenize = parser;
17 return parser(stream, state);
18 }
19
20 if (stream.match(leftDelim, true)) {
21 if (stream.eat("*")) {
22 return chain(inBlock("comment", "*" + rightDelim));
23 }
24 else {
25 state.tokenize = inSmarty;
26 return "tag";
27 }
28 }
29 else {
30 // I'd like to do an eatWhile() here, but I can't get it to eat only up to the rightDelim string/char
31 stream.next();
32 return null;
33 }
34 }
35
36 function inSmarty(stream, state) {
37 if (stream.match(rightDelim, true)) {
38 state.tokenize = tokenizer;
39 return ret("tag", null);
40 }
41
42 var ch = stream.next();
43 if (ch == "$") {
44 stream.eatWhile(regs.validIdentifier);
45 return ret("variable-2", "variable");
46 }
47 else if (ch == ".") {
48 return ret("operator", "property");
49 }
50 else if (regs.stringChar.test(ch)) {
51 state.tokenize = inAttribute(ch);
52 return ret("string", "string");
53 }
54 else if (regs.operatorChars.test(ch)) {
55 stream.eatWhile(regs.operatorChars);
56 return ret("operator", "operator");
57 }
58 else if (ch == "[" || ch == "]") {
59 return ret("bracket", "bracket");
60 }
61 else if (/\d/.test(ch)) {
62 stream.eatWhile(/\d/);
63 return ret("number", "number");
64 }
65 else {
66 if (state.last == "variable") {
67 if (ch == "@") {
68 stream.eatWhile(regs.validIdentifier);
69 return ret("property", "property");
70 }
71 else if (ch == "|") {
72 stream.eatWhile(regs.validIdentifier);
73 return ret("qualifier", "modifier");
74 }
75 }
76 else if (state.last == "whitespace") {
77 stream.eatWhile(regs.validIdentifier);
78 return ret("attribute", "modifier");
79 }
80 else if (state.last == "property") {
81 stream.eatWhile(regs.validIdentifier);
82 return ret("property", null);
83 }
84 else if (/\s/.test(ch)) {
85 last = "whitespace";
86 return null;
87 }
88
89 var str = "";
90 if (ch != "/") {
91 str += ch;
92 }
93 var c = "";
94 while ((c = stream.eat(regs.validIdentifier))) {
95 str += c;
96 }
97 var i, j;
98 for (i=0, j=keyFuncs.length; i<j; i++) {
99 if (keyFuncs[i] == str) {
100 return ret("keyword", "keyword");
101 }
102 }
103 if (/\s/.test(ch)) {
104 return null;
105 }
106 return ret("tag", "tag");
107 }
108 }
109
110 function inAttribute(quote) {
111 return function(stream, state) {
112 while (!stream.eol()) {
113 if (stream.next() == quote) {
114 state.tokenize = inSmarty;
115 break;
116 }
117 }
118 return "string";
119 };
120 }
121
122 function inBlock(style, terminator) {
123 return function(stream, state) {
124 while (!stream.eol()) {
125 if (stream.match(terminator)) {
126 state.tokenize = tokenizer;
127 break;
128 }
129 stream.next();
130 }
131 return style;
132 };
133 }
134
135 return {
136 startState: function() {
137 return { tokenize: tokenizer, mode: "smarty", last: null };
138 },
139 token: function(stream, state) {
140 var style = state.tokenize(stream, state);
141 state.last = last;
142 return style;
143 },
144 electricChars: ""
145 }