codemirror-rails 2.23 → 2.24

Sign up to get free protection for your applications and to get access to all the features.
Files changed (29) hide show
  1. data/lib/codemirror/rails/version.rb +2 -2
  2. data/vendor/assets/javascripts/codemirror.js +163 -88
  3. data/vendor/assets/javascripts/codemirror/keymaps/emacs.js +1 -1
  4. data/vendor/assets/javascripts/codemirror/keymaps/vim.js +85 -202
  5. data/vendor/assets/javascripts/codemirror/modes/clike.js +1 -1
  6. data/vendor/assets/javascripts/codemirror/modes/gfm.js +1 -1
  7. data/vendor/assets/javascripts/codemirror/modes/htmlembedded.js +1 -1
  8. data/vendor/assets/javascripts/codemirror/modes/htmlmixed.js +3 -1
  9. data/vendor/assets/javascripts/codemirror/modes/javascript.js +4 -3
  10. data/vendor/assets/javascripts/codemirror/modes/less.js +27 -13
  11. data/vendor/assets/javascripts/codemirror/modes/markdown.js +1 -1
  12. data/vendor/assets/javascripts/codemirror/modes/php.js +1 -1
  13. data/vendor/assets/javascripts/codemirror/modes/pig.js +172 -0
  14. data/vendor/assets/javascripts/codemirror/modes/python.js +1 -0
  15. data/vendor/assets/javascripts/codemirror/modes/rpm-spec.css +5 -0
  16. data/vendor/assets/javascripts/codemirror/modes/rst.js +1 -1
  17. data/vendor/assets/javascripts/codemirror/modes/shell.js +103 -0
  18. data/vendor/assets/javascripts/codemirror/modes/tiki.js +316 -0
  19. data/vendor/assets/javascripts/codemirror/modes/xml.js +63 -6
  20. data/vendor/assets/javascripts/codemirror/utils/foldcode.js +13 -8
  21. data/vendor/assets/javascripts/codemirror/utils/loadmode.js +50 -0
  22. data/vendor/assets/javascripts/codemirror/utils/overlay.js +1 -1
  23. data/vendor/assets/javascripts/codemirror/utils/search.js +2 -2
  24. data/vendor/assets/stylesheets/codemirror.css +2 -0
  25. data/vendor/assets/stylesheets/codemirror/modes/tiki.css +26 -0
  26. data/vendor/assets/stylesheets/codemirror/themes/ambiance.css +82 -0
  27. data/vendor/assets/stylesheets/codemirror/themes/blackboard.css +25 -0
  28. data/vendor/assets/stylesheets/codemirror/themes/lesser-dark.css +1 -1
  29. metadata +12 -4
@@ -240,6 +240,6 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
240
240
  getType: getType
241
241
  };
242
242
 
243
- });
243
+ }, "xml");
244
244
 
245
245
  CodeMirror.defineMIME("text/x-markdown", "markdown");
@@ -143,7 +143,7 @@
143
143
 
144
144
  electricChars: "/{}:"
145
145
  }
146
- });
146
+ }, "xml", "clike", "javascript", "css");
147
147
  CodeMirror.defineMIME("application/x-httpd-php", "php");
148
148
  CodeMirror.defineMIME("application/x-httpd-php-open", {name: "php", startOpen: true});
149
149
  CodeMirror.defineMIME("text/x-php", phpConfig);
@@ -0,0 +1,172 @@
1
+ /*
2
+ * Pig Latin Mode for CodeMirror 2
3
+ * @author Prasanth Jayachandran
4
+ * @link https://github.com/prasanthj/pig-codemirror-2
5
+ * This implementation is adapted from PL/SQL mode in CodeMirror 2.
6
+ */
7
+ CodeMirror.defineMode("pig", function(config, parserConfig) {
8
+ var indentUnit = config.indentUnit,
9
+ keywords = parserConfig.keywords,
10
+ builtins = parserConfig.builtins,
11
+ types = parserConfig.types,
12
+ multiLineStrings = parserConfig.multiLineStrings;
13
+
14
+ var isOperatorChar = /[*+\-%<>=&?:\/!|]/;
15
+
16
+ function chain(stream, state, f) {
17
+ state.tokenize = f;
18
+ return f(stream, state);
19
+ }
20
+
21
+ var type;
22
+ function ret(tp, style) {
23
+ type = tp;
24
+ return style;
25
+ }
26
+
27
+ function tokenComment(stream, state) {
28
+ var isEnd = false;
29
+ var ch;
30
+ while(ch = stream.next()) {
31
+ if(ch == "/" && isEnd) {
32
+ state.tokenize = tokenBase;
33
+ break;
34
+ }
35
+ isEnd = (ch == "*");
36
+ }
37
+ return ret("comment", "comment");
38
+ }
39
+
40
+ function tokenString(quote) {
41
+ return function(stream, state) {
42
+ var escaped = false, next, end = false;
43
+ while((next = stream.next()) != null) {
44
+ if (next == quote && !escaped) {
45
+ end = true; break;
46
+ }
47
+ escaped = !escaped && next == "\\";
48
+ }
49
+ if (end || !(escaped || multiLineStrings))
50
+ state.tokenize = tokenBase;
51
+ return ret("string", "error");
52
+ };
53
+ }
54
+
55
+ function tokenBase(stream, state) {
56
+ var ch = stream.next();
57
+
58
+ // is a start of string?
59
+ if (ch == '"' || ch == "'")
60
+ return chain(stream, state, tokenString(ch));
61
+ // is it one of the special chars
62
+ else if(/[\[\]{}\(\),;\.]/.test(ch))
63
+ return ret(ch);
64
+ // is it a number?
65
+ else if(/\d/.test(ch)) {
66
+ stream.eatWhile(/[\w\.]/);
67
+ return ret("number", "number");
68
+ }
69
+ // multi line comment or operator
70
+ else if (ch == "/") {
71
+ if (stream.eat("*")) {
72
+ return chain(stream, state, tokenComment);
73
+ }
74
+ else {
75
+ stream.eatWhile(isOperatorChar);
76
+ return ret("operator", "operator");
77
+ }
78
+ }
79
+ // single line comment or operator
80
+ else if (ch=="-") {
81
+ if(stream.eat("-")){
82
+ stream.skipToEnd();
83
+ return ret("comment", "comment");
84
+ }
85
+ else {
86
+ stream.eatWhile(isOperatorChar);
87
+ return ret("operator", "operator");
88
+ }
89
+ }
90
+ // is it an operator
91
+ else if (isOperatorChar.test(ch)) {
92
+ stream.eatWhile(isOperatorChar);
93
+ return ret("operator", "operator");
94
+ }
95
+ else {
96
+ // get the while word
97
+ stream.eatWhile(/[\w\$_]/);
98
+ // is it one of the listed keywords?
99
+ if (keywords && keywords.propertyIsEnumerable(stream.current().toUpperCase())) {
100
+ if (stream.eat(")") || stream.eat(".")) {
101
+ //keywords can be used as variables like flatten(group), group.$0 etc..
102
+ }
103
+ else {
104
+ return ("keyword", "keyword");
105
+ }
106
+ }
107
+ // is it one of the builtin functions?
108
+ if (builtins && builtins.propertyIsEnumerable(stream.current().toUpperCase()))
109
+ {
110
+ return ("keyword", "variable-2")
111
+ }
112
+ // is it one of the listed types?
113
+ if (types && types.propertyIsEnumerable(stream.current().toUpperCase()))
114
+ return ("keyword", "variable-3")
115
+ // default is a 'word'
116
+ return ret("word", "pig-word");
117
+ }
118
+ }
119
+
120
+ // Interface
121
+ return {
122
+ startState: function(basecolumn) {
123
+ return {
124
+ tokenize: tokenBase,
125
+ startOfLine: true
126
+ };
127
+ },
128
+
129
+ token: function(stream, state) {
130
+ if(stream.eatSpace()) return null;
131
+ var style = state.tokenize(stream, state);
132
+ return style;
133
+ }
134
+ };
135
+ });
136
+
137
+ (function() {
138
+ function keywords(str) {
139
+ var obj = {}, words = str.split(" ");
140
+ for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
141
+ return obj;
142
+ }
143
+
144
+ // builtin funcs taken from trunk revision 1303237
145
+ var pBuiltins = "ABS ACOS ARITY ASIN ATAN AVG BAGSIZE BINSTORAGE BLOOM BUILDBLOOM CBRT CEIL "
146
+ + "CONCAT COR COS COSH COUNT COUNT_STAR COV CONSTANTSIZE CUBEDIMENSIONS DIFF DISTINCT DOUBLEABS "
147
+ + "DOUBLEAVG DOUBLEBASE DOUBLEMAX DOUBLEMIN DOUBLEROUND DOUBLESUM EXP FLOOR FLOATABS FLOATAVG "
148
+ + "FLOATMAX FLOATMIN FLOATROUND FLOATSUM GENERICINVOKER INDEXOF INTABS INTAVG INTMAX INTMIN "
149
+ + "INTSUM INVOKEFORDOUBLE INVOKEFORFLOAT INVOKEFORINT INVOKEFORLONG INVOKEFORSTRING INVOKER "
150
+ + "ISEMPTY JSONLOADER JSONMETADATA JSONSTORAGE LAST_INDEX_OF LCFIRST LOG LOG10 LOWER LONGABS "
151
+ + "LONGAVG LONGMAX LONGMIN LONGSUM MAX MIN MAPSIZE MONITOREDUDF NONDETERMINISTIC OUTPUTSCHEMA "
152
+ + "PIGSTORAGE PIGSTREAMING RANDOM REGEX_EXTRACT REGEX_EXTRACT_ALL REPLACE ROUND SIN SINH SIZE "
153
+ + "SQRT STRSPLIT SUBSTRING SUM STRINGCONCAT STRINGMAX STRINGMIN STRINGSIZE TAN TANH TOBAG "
154
+ + "TOKENIZE TOMAP TOP TOTUPLE TRIM TEXTLOADER TUPLESIZE UCFIRST UPPER UTF8STORAGECONVERTER ";
155
+
156
+ // taken from QueryLexer.g
157
+ var pKeywords = "VOID IMPORT RETURNS DEFINE LOAD FILTER FOREACH ORDER CUBE DISTINCT COGROUP "
158
+ + "JOIN CROSS UNION SPLIT INTO IF OTHERWISE ALL AS BY USING INNER OUTER ONSCHEMA PARALLEL "
159
+ + "PARTITION GROUP AND OR NOT GENERATE FLATTEN ASC DESC IS STREAM THROUGH STORE MAPREDUCE "
160
+ + "SHIP CACHE INPUT OUTPUT STDERROR STDIN STDOUT LIMIT SAMPLE LEFT RIGHT FULL EQ GT LT GTE LTE "
161
+ + "NEQ MATCHES TRUE FALSE ";
162
+
163
+ // data types
164
+ var pTypes = "BOOLEAN INT LONG FLOAT DOUBLE CHARARRAY BYTEARRAY BAG TUPLE MAP "
165
+
166
+ CodeMirror.defineMIME("text/x-pig", {
167
+ name: "pig",
168
+ builtins: keywords(pBuiltins),
169
+ keywords: keywords(pKeywords),
170
+ types: keywords(pTypes)
171
+ });
172
+ }());
@@ -275,6 +275,7 @@ CodeMirror.defineMode("python", function(conf, parserConf) {
275
275
  if (current === 'pass' || current === 'return') {
276
276
  state.dedent += 1;
277
277
  }
278
+ if (current === 'lambda') state.lambda = true;
278
279
  if ((current === ':' && !state.lambda && state.scopes[0].type == 'py')
279
280
  || indentInfo === 'indent') {
280
281
  indent(stream, state);
@@ -0,0 +1,5 @@
1
+ .cm-s-default span.cm-preamble {color: #b26818; font-weight: bold;}
2
+ .cm-s-default span.cm-macro {color: #b218b2;}
3
+ .cm-s-default span.cm-section {color: green; font-weight: bold;}
4
+ .cm-s-default span.cm-script {color: red;}
5
+ .cm-s-default span.cm-issue {color: yellow;}
@@ -321,6 +321,6 @@ CodeMirror.defineMode('rst', function(config, options) {
321
321
  return token;
322
322
  }
323
323
  };
324
- });
324
+ }, "python");
325
325
 
326
326
  CodeMirror.defineMIME("text/x-rst", "rst");
@@ -0,0 +1,103 @@
1
+ CodeMirror.defineMode('shell', function(config) {
2
+
3
+ var atoms = ['true','false'],
4
+ keywords = ['if','then','do','else','elif','while','until','for','in','esac','fi','fin','fil','done','exit','set','unset','export','function'],
5
+ commands = ['ab','awk','bash','beep','cat','cc','cd','chown','chmod','chroot','clear','cp','curl','cut','diff','echo','find','gawk','gcc','get','git','grep','kill','killall','ls','make','mkdir','openssl','mv','nc','node','npm','ping','ps','restart','rm','rmdir','sed','service','sh','shopt','shred','source','sort','sleep','ssh','start','stop','su','sudo','tee','telnet','top','touch','vi','vim','wall','wc','wget','who','write','yes','zsh'];
6
+
7
+ function tokenBase(stream, state) {
8
+
9
+ var sol = stream.sol();
10
+ var ch = stream.next();
11
+
12
+ if (ch === '\'' || ch === '"' || ch === '`') {
13
+ state.tokens.unshift(tokenString(ch));
14
+ return tokenize(stream, state);
15
+ }
16
+ if (ch === '#') {
17
+ if (sol && stream.eat('!')) {
18
+ stream.skipToEnd();
19
+ return 'meta'; // 'comment'?
20
+ }
21
+ stream.skipToEnd();
22
+ return 'comment';
23
+ }
24
+ if (ch === '$') {
25
+ state.tokens.unshift(tokenDollar);
26
+ return tokenize(stream, state);
27
+ }
28
+ if (ch === '+' || ch === '=') {
29
+ return 'operator';
30
+ }
31
+ if (ch === '-') {
32
+ stream.eat('-');
33
+ stream.eatWhile(/\w/);
34
+ return 'attribute';
35
+ }
36
+ if (/\d/.test(ch)) {
37
+ stream.eatWhile(/\d/);
38
+ if(!/\w/.test(stream.peek())) {
39
+ return 'number';
40
+ }
41
+ }
42
+ stream.eatWhile(/\w/);
43
+ var cur = stream.current();
44
+ if (stream.peek() === '=' && /\w+/.test(cur)) return 'def';
45
+ if (atoms.indexOf(cur) !== -1) return 'atom';
46
+ if (commands.indexOf(cur) !== -1) return 'builtin';
47
+ if (keywords.indexOf(cur) !== -1) return 'keyword';
48
+ return 'word';
49
+ }
50
+
51
+ function tokenString(quote) {
52
+ return function(stream, state) {
53
+ var next, end = false, escaped = false;
54
+ while ((next = stream.next()) != null) {
55
+ if (next === quote && !escaped) {
56
+ end = true;
57
+ break;
58
+ }
59
+ if (next === '$' && !escaped && quote !== '\'') {
60
+ escaped = true;
61
+ stream.backUp(1);
62
+ state.tokens.unshift(tokenDollar);
63
+ break;
64
+ }
65
+ escaped = !escaped && next === '\\';
66
+ }
67
+ if (end || !escaped) {
68
+ state.tokens.shift();
69
+ }
70
+ return (quote === '`' || quote === ')' ? 'quote' : 'string');
71
+ };
72
+ };
73
+
74
+ var tokenDollar = function(stream, state) {
75
+ if (state.tokens.length > 1) stream.eat('$');
76
+ var ch = stream.next(), hungry = /\w/;
77
+ if (ch === '{') hungry = /[^}]/;
78
+ if (ch === '(') {
79
+ state.tokens[0] = tokenString(')');
80
+ return tokenize(stream, state);
81
+ }
82
+ if (!/\d/.test(ch)) {
83
+ stream.eatWhile(hungry);
84
+ stream.eat('}');
85
+ }
86
+ state.tokens.shift();
87
+ return 'def';
88
+ };
89
+
90
+ function tokenize(stream, state) {
91
+ return (state.tokens[0] || tokenBase) (stream, state);
92
+ };
93
+
94
+ return {
95
+ startState: function() {return {tokens:[]}},
96
+ token: function(stream, state) {
97
+ if (stream.eatSpace()) return null;
98
+ return tokenize(stream, state);
99
+ }
100
+ };
101
+ });
102
+
103
+ CodeMirror.defineMIME('text/x-sh', 'shell');
@@ -0,0 +1,316 @@
1
+ CodeMirror.defineMode('tiki', function(config, parserConfig) {
2
+ function inBlock(style, terminator, returnTokenizer) {
3
+ return function(stream, state) {
4
+ while (!stream.eol()) {
5
+ if (stream.match(terminator)) {
6
+ state.tokenize = inText;
7
+ break;
8
+ }
9
+ stream.next();
10
+ }
11
+
12
+ if (returnTokenizer) state.tokenize = returnTokenizer;
13
+
14
+ return style;
15
+ };
16
+ }
17
+
18
+ function inLine(style, terminator) {
19
+ return function(stream, state) {
20
+ while(!stream.eol()) {
21
+ stream.next()
22
+ }
23
+ state.tokenize = inText;
24
+ return style;
25
+ };
26
+ }
27
+
28
+ function inText(stream, state) {
29
+ function chain(parser) {
30
+ state.tokenize = parser;
31
+ return parser(stream, state);
32
+ }
33
+
34
+ var sol = stream.sol();
35
+ var ch = stream.next();
36
+
37
+ //non start of line
38
+ switch (ch) { //switch is generally much faster than if, so it is used here
39
+ case "{": //plugin
40
+ type = stream.eat("/") ? "closeTag" : "openTag";
41
+ stream.eatSpace();
42
+ tagName = "";
43
+ var c;
44
+ while ((c = stream.eat(/[^\s\u00a0=\"\'\/?(}]/))) tagName += c;
45
+ state.tokenize = inPlugin;
46
+ return "tag";
47
+ break;
48
+ case "_": //bold
49
+ if (stream.eat("_")) {
50
+ return chain(inBlock("strong", "__", inText));
51
+ }
52
+ break;
53
+ case "'": //italics
54
+ if (stream.eat("'")) {
55
+ // Italic text
56
+ return chain(inBlock("em", "''", inText));
57
+ }
58
+ break;
59
+ case "(":// Wiki Link
60
+ if (stream.eat("(")) {
61
+ return chain(inBlock("variable-2", "))", inText));
62
+ }
63
+ break;
64
+ case "[":// Weblink
65
+ return chain(inBlock("variable-3", "]", inText));
66
+ break;
67
+ case "|": //table
68
+ if (stream.eat("|")) {
69
+ return chain(inBlock("comment", "||"));
70
+ }
71
+ break;
72
+ case "-":
73
+ if (stream.eat("=")) {//titleBar
74
+ return chain(inBlock("header string", "=-", inText));
75
+ } else if (stream.eat("-")) {//deleted
76
+ return chain(inBlock("error tw-deleted", "--", inText));
77
+ }
78
+ break;
79
+ case "=": //underline
80
+ if (stream.match("==")) {
81
+ return chain(inBlock("tw-underline", "===", inText));
82
+ }
83
+ break;
84
+ case ":":
85
+ if (stream.eat(":")) {
86
+ return chain(inBlock("comment", "::"));
87
+ }
88
+ break;
89
+ case "^": //box
90
+ return chain(inBlock("tw-box", "^"));
91
+ break;
92
+ case "~": //np
93
+ if (stream.match("np~")) {
94
+ return chain(inBlock("meta", "~/np~"));
95
+ }
96
+ break;
97
+ }
98
+
99
+ //start of line types
100
+ if (sol) {
101
+ switch (ch) {
102
+ case "!": //header at start of line
103
+ if (stream.match('!!!!!')) {
104
+ return chain(inLine("header string"));
105
+ } else if (stream.match('!!!!')) {
106
+ return chain(inLine("header string"));
107
+ } else if (stream.match('!!!')) {
108
+ return chain(inLine("header string"));
109
+ } else if (stream.match('!!')) {
110
+ return chain(inLine("header string"));
111
+ } else {
112
+ return chain(inLine("header string"));
113
+ }
114
+ break;
115
+ case "*": //unordered list line item, or <li /> at start of line
116
+ case "#": //ordered list line item, or <li /> at start of line
117
+ case "+": //ordered list line item, or <li /> at start of line
118
+ return chain(inLine("tw-listitem bracket"));
119
+ break;
120
+ }
121
+ }
122
+
123
+ //stream.eatWhile(/[&{]/); was eating up plugins, turned off to act less like html and more like tiki
124
+ return null;
125
+ }
126
+
127
+ var indentUnit = config.indentUnit;
128
+
129
+ // Return variables for tokenizers
130
+ var pluginName, type;
131
+ function inPlugin(stream, state) {
132
+ var ch = stream.next();
133
+ var peek = stream.peek();
134
+
135
+ if (ch == "}") {
136
+ state.tokenize = inText;
137
+ //type = ch == ")" ? "endPlugin" : "selfclosePlugin"; inPlugin
138
+ return "tag";
139
+ } else if (ch == "(" || ch == ")") {
140
+ return "bracket";
141
+ } else if (ch == "=") {
142
+ type = "equals";
143
+
144
+ if (peek == ">") {
145
+ ch = stream.next();
146
+ peek = stream.peek();
147
+ }
148
+
149
+ //here we detect values directly after equal character with no quotes
150
+ if (!/[\'\"]/.test(peek)) {
151
+ state.tokenize = inAttributeNoQuote();
152
+ }
153
+ //end detect values
154
+
155
+ return "operator";
156
+ } else if (/[\'\"]/.test(ch)) {
157
+ state.tokenize = inAttribute(ch);
158
+ return state.tokenize(stream, state);
159
+ } else {
160
+ stream.eatWhile(/[^\s\u00a0=\"\'\/?]/);
161
+ return "keyword";
162
+ }
163
+ }
164
+
165
+ function inAttribute(quote) {
166
+ return function(stream, state) {
167
+ while (!stream.eol()) {
168
+ if (stream.next() == quote) {
169
+ state.tokenize = inPlugin;
170
+ break;
171
+ }
172
+ }
173
+ return "string";
174
+ };
175
+ }
176
+
177
+ function inAttributeNoQuote() {
178
+ return function(stream, state) {
179
+ while (!stream.eol()) {
180
+ var ch = stream.next();
181
+ var peek = stream.peek();
182
+ if (ch == " " || ch == "," || /[ )}]/.test(peek)) {
183
+ state.tokenize = inPlugin;
184
+ break;
185
+ }
186
+ }
187
+ return "string";
188
+ };
189
+ }
190
+
191
+ var curState, setStyle;
192
+ function pass() {
193
+ for (var i = arguments.length - 1; i >= 0; i--) curState.cc.push(arguments[i]);
194
+ }
195
+
196
+ function cont() {
197
+ pass.apply(null, arguments);
198
+ return true;
199
+ }
200
+
201
+ function pushContext(pluginName, startOfLine) {
202
+ var noIndent = curState.context && curState.context.noIndent;
203
+ curState.context = {
204
+ prev: curState.context,
205
+ pluginName: pluginName,
206
+ indent: curState.indented,
207
+ startOfLine: startOfLine,
208
+ noIndent: noIndent
209
+ };
210
+ }
211
+
212
+ function popContext() {
213
+ if (curState.context) curState.context = curState.context.prev;
214
+ }
215
+
216
+ function element(type) {
217
+ if (type == "openPlugin") {curState.pluginName = pluginName; return cont(attributes, endplugin(curState.startOfLine));}
218
+ else if (type == "closePlugin") {
219
+ var err = false;
220
+ if (curState.context) {
221
+ err = curState.context.pluginName != pluginName;
222
+ popContext();
223
+ } else {
224
+ err = true;
225
+ }
226
+ if (err) setStyle = "error";
227
+ return cont(endcloseplugin(err));
228
+ }
229
+ else if (type == "string") {
230
+ if (!curState.context || curState.context.name != "!cdata") pushContext("!cdata");
231
+ if (curState.tokenize == inText) popContext();
232
+ return cont();
233
+ }
234
+ else return cont();
235
+ }
236
+
237
+ function endplugin(startOfLine) {
238
+ return function(type) {
239
+ if (
240
+ type == "selfclosePlugin" ||
241
+ type == "endPlugin"
242
+ )
243
+ return cont();
244
+ if (type == "endPlugin") {pushContext(curState.pluginName, startOfLine); return cont();}
245
+ return cont();
246
+ };
247
+ }
248
+
249
+ function endcloseplugin(err) {
250
+ return function(type) {
251
+ if (err) setStyle = "error";
252
+ if (type == "endPlugin") return cont();
253
+ return pass();
254
+ }
255
+ }
256
+
257
+ function attributes(type) {
258
+ if (type == "keyword") {setStyle = "attribute"; return cont(attributes);}
259
+ if (type == "equals") return cont(attvalue, attributes);
260
+ return pass();
261
+ }
262
+ function attvalue(type) {
263
+ if (type == "keyword") {setStyle = "string"; return cont();}
264
+ if (type == "string") return cont(attvaluemaybe);
265
+ return pass();
266
+ }
267
+ function attvaluemaybe(type) {
268
+ if (type == "string") return cont(attvaluemaybe);
269
+ else return pass();
270
+ }
271
+ return {
272
+ startState: function() {
273
+ return {tokenize: inText, cc: [], indented: 0, startOfLine: true, pluginName: null, context: null};
274
+ },
275
+ token: function(stream, state) {
276
+ if (stream.sol()) {
277
+ state.startOfLine = true;
278
+ state.indented = stream.indentation();
279
+ }
280
+ if (stream.eatSpace()) return null;
281
+
282
+ setStyle = type = pluginName = null;
283
+ var style = state.tokenize(stream, state);
284
+ if ((style || type) && style != "comment") {
285
+ curState = state;
286
+ while (true) {
287
+ var comb = state.cc.pop() || element;
288
+ if (comb(type || style)) break;
289
+ }
290
+ }
291
+ state.startOfLine = false;
292
+ return setStyle || style;
293
+ },
294
+ indent: function(state, textAfter) {
295
+ var context = state.context;
296
+ if (context && context.noIndent) return 0;
297
+ if (context && /^{\//.test(textAfter))
298
+ context = context.prev;
299
+ while (context && !context.startOfLine)
300
+ context = context.prev;
301
+ if (context) return context.indent + indentUnit;
302
+ else return 0;
303
+ },
304
+ compareStates: function(a, b) {
305
+ if (a.indented != b.indented || a.pluginName != b.pluginName) return false;
306
+ for (var ca = a.context, cb = b.context; ; ca = ca.prev, cb = cb.prev) {
307
+ if (!ca || !cb) return ca == cb;
308
+ if (ca.pluginName != cb.pluginName) return false;
309
+ }
310
+ },
311
+ electricChars: "/"
312
+ };
313
+ });
314
+
315
+ //I figure, why not
316
+ CodeMirror.defineMIME("text/tiki", "tiki");