diff options
author | Pushkar Joshi | 2012-05-22 13:22:26 -0700 |
---|---|---|
committer | Pushkar Joshi | 2012-05-22 13:22:26 -0700 |
commit | 01dbc1f329a95bc7e3b93224543d88ad5bdbd315 (patch) | |
tree | ceb527713554f506c537168e36a10452cd09ad10 /imports/codemirror/mode/smarty | |
parent | b9262c831952e77135b79c2de7c455d5e7ff0589 (diff) | |
parent | c37a876b373ddc7cb19277aaeaa6bb2d2d5a50ac (diff) | |
download | ninja-01dbc1f329a95bc7e3b93224543d88ad5bdbd315.tar.gz |
Merge branch 'master' into brushtool
Diffstat (limited to 'imports/codemirror/mode/smarty')
-rw-r--r-- | imports/codemirror/mode/smarty/index.html | 82 | ||||
-rw-r--r-- | imports/codemirror/mode/smarty/smarty.js | 148 |
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 @@ | |||
1 | CodeMirror.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 | } | ||