codemirror-rails 2.23 → 2.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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");