codemirror-rails 4.6 → 4.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/lib/codemirror/rails/version.rb +2 -2
  3. data/vendor/assets/javascripts/codemirror.js +24 -25
  4. data/vendor/assets/javascripts/codemirror/addons/comment/comment.js +1 -1
  5. data/vendor/assets/javascripts/codemirror/addons/dialog/dialog.js +4 -1
  6. data/vendor/assets/javascripts/codemirror/addons/edit/closebrackets.js +7 -6
  7. data/vendor/assets/javascripts/codemirror/addons/edit/continuelist.js +21 -8
  8. data/vendor/assets/javascripts/codemirror/addons/hint/sql-hint.js +54 -20
  9. data/vendor/assets/javascripts/codemirror/addons/lint/lint.js +10 -15
  10. data/vendor/assets/javascripts/codemirror/addons/mode/simple.js +210 -0
  11. data/vendor/assets/javascripts/codemirror/addons/runmode/runmode-standalone.js +5 -1
  12. data/vendor/assets/javascripts/codemirror/addons/runmode/runmode.node.js +2 -4
  13. data/vendor/assets/javascripts/codemirror/keymaps/vim.js +425 -554
  14. data/vendor/assets/javascripts/codemirror/modes/clike.js +28 -5
  15. data/vendor/assets/javascripts/codemirror/modes/clojure.js +5 -3
  16. data/vendor/assets/javascripts/codemirror/modes/coffeescript.js +8 -7
  17. data/vendor/assets/javascripts/codemirror/modes/d.js +1 -1
  18. data/vendor/assets/javascripts/codemirror/modes/dtd.js +1 -1
  19. data/vendor/assets/javascripts/codemirror/modes/gherkin.js +1 -1
  20. data/vendor/assets/javascripts/codemirror/modes/go.js +1 -1
  21. data/vendor/assets/javascripts/codemirror/modes/haskell.js +1 -1
  22. data/vendor/assets/javascripts/codemirror/modes/javascript.js +3 -3
  23. data/vendor/assets/javascripts/codemirror/modes/julia.js +1 -1
  24. data/vendor/assets/javascripts/codemirror/modes/markdown.js +4 -3
  25. data/vendor/assets/javascripts/codemirror/modes/octave.js +1 -1
  26. data/vendor/assets/javascripts/codemirror/modes/perl.js +2 -2
  27. data/vendor/assets/javascripts/codemirror/modes/php.js +37 -44
  28. data/vendor/assets/javascripts/codemirror/modes/python.js +17 -4
  29. data/vendor/assets/javascripts/codemirror/modes/ruby.js +12 -11
  30. data/vendor/assets/javascripts/codemirror/modes/rust.js +2 -2
  31. data/vendor/assets/javascripts/codemirror/modes/smartymixed.js +5 -1
  32. data/vendor/assets/javascripts/codemirror/modes/sql.js +2 -1
  33. data/vendor/assets/javascripts/codemirror/modes/stex.js +2 -1
  34. data/vendor/assets/javascripts/codemirror/modes/tcl.js +1 -1
  35. data/vendor/assets/javascripts/codemirror/modes/textile.js +553 -0
  36. data/vendor/assets/javascripts/codemirror/modes/tornado.js +68 -0
  37. data/vendor/assets/javascripts/codemirror/modes/verilog.js +14 -9
  38. data/vendor/assets/stylesheets/codemirror.css +1 -1
  39. data/vendor/assets/stylesheets/codemirror/themes/base16-dark.css +2 -2
  40. data/vendor/assets/stylesheets/codemirror/themes/mdn-like.css +1 -1
  41. metadata +4 -1
@@ -107,16 +107,16 @@ CodeMirror.defineMode("ruby", function(config) {
107
107
  }
108
108
 
109
109
  // Symbols can't start by a digit
110
- if (stream.eat(/[a-zA-Z$@_]/)) {
111
- stream.eatWhile(/[\w]/);
110
+ if (stream.eat(/[a-zA-Z$@_\xa1-\uffff]/)) {
111
+ stream.eatWhile(/[\w$\xa1-\uffff]/);
112
112
  // Only one ? ! = is allowed and only as the last character
113
113
  stream.eat(/[\?\!\=]/);
114
114
  return "atom";
115
115
  }
116
116
  return "operator";
117
- } else if (ch == "@" && stream.match(/^@?[a-zA-Z_]/)) {
117
+ } else if (ch == "@" && stream.match(/^@?[a-zA-Z_\xa1-\uffff]/)) {
118
118
  stream.eat("@");
119
- stream.eatWhile(/[\w]/);
119
+ stream.eatWhile(/[\w\xa1-\uffff]/);
120
120
  return "variable-2";
121
121
  } else if (ch == "$") {
122
122
  if (stream.eat(/[a-zA-Z_]/)) {
@@ -127,8 +127,8 @@ CodeMirror.defineMode("ruby", function(config) {
127
127
  stream.next(); // Must be a special global like $: or $!
128
128
  }
129
129
  return "variable-3";
130
- } else if (/[a-zA-Z_]/.test(ch)) {
131
- stream.eatWhile(/[\w]/);
130
+ } else if (/[a-zA-Z_\xa1-\uffff]/.test(ch)) {
131
+ stream.eatWhile(/[\w\xa1-\uffff]/);
132
132
  stream.eat(/[\?\!]/);
133
133
  if (stream.eat(":")) return "atom";
134
134
  return "ident";
@@ -149,17 +149,18 @@ CodeMirror.defineMode("ruby", function(config) {
149
149
  }
150
150
  }
151
151
 
152
- function tokenBaseUntilBrace() {
153
- var depth = 1;
152
+ function tokenBaseUntilBrace(depth) {
153
+ if (!depth) depth = 1;
154
154
  return function(stream, state) {
155
155
  if (stream.peek() == "}") {
156
- depth--;
157
- if (depth == 0) {
156
+ if (depth == 1) {
158
157
  state.tokenize.pop();
159
158
  return state.tokenize[state.tokenize.length-1](stream, state);
159
+ } else {
160
+ state.tokenize[state.tokenize.length - 1] = tokenBaseUntilBrace(depth - 1);
160
161
  }
161
162
  } else if (stream.peek() == "{") {
162
- depth++;
163
+ state.tokenize[state.tokenize.length - 1] = tokenBaseUntilBrace(depth + 1);
163
164
  }
164
165
  return tokenBase(stream, state);
165
166
  };
@@ -14,7 +14,7 @@
14
14
  CodeMirror.defineMode("rust", function() {
15
15
  var indentUnit = 4, altIndentUnit = 2;
16
16
  var valKeywords = {
17
- "if": "if-style", "while": "if-style", "else": "else-style",
17
+ "if": "if-style", "while": "if-style", "loop": "else-style", "else": "else-style",
18
18
  "do": "else-style", "ret": "else-style", "fail": "else-style",
19
19
  "break": "atom", "cont": "atom", "const": "let", "resource": "fn",
20
20
  "let": "let", "fn": "fn", "for": "for", "alt": "alt", "iface": "iface",
@@ -22,7 +22,7 @@ CodeMirror.defineMode("rust", function() {
22
22
  "as": "op", "true": "atom", "false": "atom", "assert": "op", "check": "op",
23
23
  "claim": "op", "native": "ignore", "unsafe": "ignore", "import": "else-style",
24
24
  "export": "else-style", "copy": "op", "log": "op", "log_err": "op",
25
- "use": "op", "bind": "op", "self": "atom"
25
+ "use": "op", "bind": "op", "self": "atom", "struct": "enum"
26
26
  };
27
27
  var typeKeywords = function() {
28
28
  var keywords = {"fn": "fn", "block": "fn", "obj": "obj"};
@@ -77,7 +77,11 @@ CodeMirror.defineMode("smartymixed", function(config) {
77
77
 
78
78
  var parsers = {
79
79
  html: function(stream, state) {
80
- if (!state.inLiteral && stream.match(regs.htmlHasLeftDelimeter, false) && state.htmlMixedState.htmlState.tagName === null) {
80
+ var htmlTagName = state.htmlMixedState.htmlState.context && state.htmlMixedState.htmlState.context.tagName
81
+ ? state.htmlMixedState.htmlState.context.tagName
82
+ : null;
83
+
84
+ if (!state.inLiteral && stream.match(regs.htmlHasLeftDelimeter, false) && htmlTagName === null) {
81
85
  state.tokenize = parsers.smarty;
82
86
  state.localMode = smartyMode;
83
87
  state.localState = smartyMode.startState(htmlMixedMode.indent(state.htmlMixedState, ""));
@@ -213,7 +213,8 @@ CodeMirror.defineMode("sql", function(config, parserConfig) {
213
213
  while ((ch = stream.next()) != null) {
214
214
  if (ch == "`" && !stream.eat("`")) return "variable-2";
215
215
  }
216
- return null;
216
+ stream.backUp(stream.current().length - 1);
217
+ return stream.eatWhile(/\w/) ? "variable-2" : null;
217
218
  }
218
219
 
219
220
  // variable token
@@ -251,7 +251,8 @@ CodeMirror.defineMode("stex", function() {
251
251
  },
252
252
  token: function(stream, state) {
253
253
  return state.f(stream, state);
254
- }
254
+ },
255
+ lineComment: "%"
255
256
  };
256
257
  });
257
258
 
@@ -78,7 +78,7 @@ CodeMirror.defineMode("tcl", function() {
78
78
  return "comment";
79
79
  }
80
80
  else {
81
- stream.eatWhile(/[\w\$_{}]/);
81
+ stream.eatWhile(/[\w\$_{}\xa1-\uffff]/);
82
82
  var word = stream.current().toLowerCase();
83
83
  if (keywords && keywords.propertyIsEnumerable(word))
84
84
  return "keyword";
@@ -0,0 +1,553 @@
1
+ // CodeMirror, copyright (c) by Marijn Haverbeke and others
2
+ // Distributed under an MIT license: http://codemirror.net/LICENSE
3
+
4
+ (function(mod) {
5
+ if (typeof exports == 'object' && typeof module == 'object') { // CommonJS
6
+ mod(require('../../lib/codemirror'));
7
+ } else if (typeof define == 'function' && define.amd) { // AMD
8
+ define(['../../lib/codemirror'], mod);
9
+ } else { // Plain browser env
10
+ mod(CodeMirror);
11
+ }
12
+ })(function(CodeMirror) {
13
+ 'use strict';
14
+
15
+ var TOKEN_STYLES = {
16
+ addition: 'positive',
17
+ attributes: 'attribute',
18
+ bold: 'strong',
19
+ cite: 'keyword',
20
+ code: 'atom',
21
+ definitionList: 'number',
22
+ deletion: 'negative',
23
+ div: 'punctuation',
24
+ em: 'em',
25
+ footnote: 'variable',
26
+ footCite: 'qualifier',
27
+ header: 'header',
28
+ html: 'comment',
29
+ image: 'string',
30
+ italic: 'em',
31
+ link: 'link',
32
+ linkDefinition: 'link',
33
+ list1: 'variable-2',
34
+ list2: 'variable-3',
35
+ list3: 'keyword',
36
+ notextile: 'string-2',
37
+ pre: 'operator',
38
+ p: 'property',
39
+ quote: 'bracket',
40
+ span: 'quote',
41
+ specialChar: 'tag',
42
+ strong: 'strong',
43
+ sub: 'builtin',
44
+ sup: 'builtin',
45
+ table: 'variable-3',
46
+ tableHeading: 'operator'
47
+ };
48
+
49
+ function Parser(regExpFactory, state, stream) {
50
+ this.regExpFactory = regExpFactory;
51
+ this.state = state;
52
+ this.stream = stream;
53
+ this.styles = TOKEN_STYLES;
54
+
55
+ this.state.specialChar = null;
56
+ }
57
+
58
+ Parser.prototype.eat = function(name) {
59
+ return this.stream.match(this.regExpFactory.pattern(name), true);
60
+ };
61
+
62
+ Parser.prototype.check = function(name) {
63
+ return this.stream.match(this.regExpFactory.pattern(name), false);
64
+ };
65
+
66
+ Parser.prototype.setModeForNextToken = function(mode) {
67
+ return this.state.mode = mode;
68
+ };
69
+
70
+ Parser.prototype.execMode = function(newMode) {
71
+ return this.setModeForNextToken(newMode).call(this);
72
+ };
73
+
74
+ Parser.prototype.startNewLine = function() {
75
+ this.setModeForNextToken(Modes.newLayout);
76
+ this.state.tableHeading = false;
77
+
78
+ if (this.state.layoutType === 'definitionList' && this.state.spanningLayout) {
79
+ if (this.check('definitionListEnd')) {
80
+ this.state.spanningLayout = false;
81
+ }
82
+ }
83
+ };
84
+
85
+ Parser.prototype.nextToken = function() {
86
+ return this.state.mode.call(this);
87
+ };
88
+
89
+ Parser.prototype.styleFor = function(token) {
90
+ if (this.styles.hasOwnProperty(token)) {
91
+ return this.styles[token];
92
+ }
93
+ throw 'unknown token';
94
+ };
95
+
96
+ Parser.prototype.handlePhraseModifier = function(ch) {
97
+ if (ch === '_') {
98
+ if (this.stream.eat('_')) {
99
+ return this.togglePhraseModifier('italic', /^.*__/);
100
+ }
101
+ return this.togglePhraseModifier('em', /^.*_/);
102
+ }
103
+
104
+ if (ch === '*') {
105
+ if (this.stream.eat('*')) {
106
+ return this.togglePhraseModifier('bold', /^.*\*\*/);
107
+ }
108
+ return this.togglePhraseModifier('strong', /^.*\*/);
109
+ }
110
+
111
+ if (ch === '[') {
112
+ if (this.stream.match(/\d+\]/)) {
113
+ this.state.footCite = true;
114
+ }
115
+ return this.tokenStyles();
116
+ }
117
+
118
+ if (ch === '(') {
119
+ if (this.stream.match('r)')) {
120
+ this.state.specialChar = 'r';
121
+ } else if (this.stream.match('tm)')) {
122
+ this.state.specialChar = 'tm';
123
+ } else if (this.stream.match('c)')) {
124
+ this.state.specialChar = 'c';
125
+ }
126
+ return this.tokenStyles();
127
+ }
128
+
129
+ if (ch === '<') {
130
+ if (this.stream.match(/(\w+)[^>]+>[^<]+<\/\1>/)) {
131
+ return this.tokenStylesWith(this.styleFor('html'));
132
+ }
133
+ }
134
+
135
+ if (ch === '?' && this.stream.eat('?')) {
136
+ return this.togglePhraseModifier('cite', /^.*\?\?/);
137
+ }
138
+ if (ch === '=' && this.stream.eat('=')) {
139
+ return this.togglePhraseModifier('notextile', /^.*==/);
140
+ }
141
+ if (ch === '-') {
142
+ return this.togglePhraseModifier('deletion', /^.*-/);
143
+ }
144
+ if (ch === '+') {
145
+ return this.togglePhraseModifier('addition', /^.*\+/);
146
+ }
147
+ if (ch === '~') {
148
+ return this.togglePhraseModifier('sub', /^.*~/);
149
+ }
150
+ if (ch === '^') {
151
+ return this.togglePhraseModifier('sup', /^.*\^/);
152
+ }
153
+ if (ch === '%') {
154
+ return this.togglePhraseModifier('span', /^.*%/);
155
+ }
156
+ if (ch === '@') {
157
+ return this.togglePhraseModifier('code', /^.*@/);
158
+ }
159
+ if (ch === '!') {
160
+ var type = this.togglePhraseModifier('image', /^.*(?:\([^\)]+\))?!/);
161
+ this.stream.match(/^:\S+/); // optional Url portion
162
+ return type;
163
+ }
164
+ return this.tokenStyles();
165
+ };
166
+
167
+ Parser.prototype.togglePhraseModifier = function(phraseModifier, closeRE) {
168
+ if (this.state[phraseModifier]) { // remove phrase modifier
169
+ var type = this.tokenStyles();
170
+ this.state[phraseModifier] = false;
171
+ return type;
172
+ }
173
+ if (this.stream.match(closeRE, false)) { // add phrase modifier
174
+ this.state[phraseModifier] = true;
175
+ this.setModeForNextToken(Modes.attributes);
176
+ }
177
+ return this.tokenStyles();
178
+ };
179
+
180
+ Parser.prototype.tokenStyles = function() {
181
+ var disabled = this.textileDisabled(),
182
+ styles = [];
183
+
184
+ if (disabled) return disabled;
185
+
186
+ if (this.state.layoutType) {
187
+ styles.push(this.styleFor(this.state.layoutType));
188
+ }
189
+
190
+ styles = styles.concat(this.activeStyles('addition', 'bold', 'cite', 'code',
191
+ 'deletion', 'em', 'footCite', 'image', 'italic', 'link', 'span', 'specialChar', 'strong',
192
+ 'sub', 'sup', 'table', 'tableHeading'));
193
+
194
+ if (this.state.layoutType === 'header') {
195
+ styles.push(this.styleFor('header') + '-' + this.state.header);
196
+ }
197
+ return styles.length ? styles.join(' ') : null;
198
+ };
199
+
200
+ Parser.prototype.textileDisabled = function() {
201
+ var type = this.state.layoutType;
202
+
203
+ switch(type) {
204
+ case 'notextile':
205
+ case 'code':
206
+ case 'pre':
207
+ return this.styleFor(type);
208
+ default:
209
+ if (this.state.notextile) {
210
+ return this.styleFor('notextile') + (type ? (' ' + this.styleFor(type)) : '');
211
+ }
212
+
213
+ return null;
214
+ }
215
+ };
216
+
217
+ Parser.prototype.tokenStylesWith = function(extraStyles) {
218
+ var disabled = this.textileDisabled(),
219
+ type;
220
+
221
+ if (disabled) return disabled;
222
+
223
+ type = this.tokenStyles();
224
+ if(extraStyles) {
225
+ return type ? (type + ' ' + extraStyles) : extraStyles;
226
+ }
227
+ return type;
228
+ };
229
+
230
+ Parser.prototype.activeStyles = function() {
231
+ var styles = [],
232
+ i;
233
+ for (i = 0; i < arguments.length; ++i) {
234
+ if (this.state[arguments[i]]) {
235
+ styles.push(this.styleFor(arguments[i]));
236
+ }
237
+ }
238
+ return styles;
239
+ };
240
+
241
+ Parser.prototype.blankLine = function() {
242
+ var spanningLayout = this.state.spanningLayout,
243
+ type = this.state.layoutType,
244
+ key;
245
+
246
+ for (key in this.state) {
247
+ if (this.state.hasOwnProperty(key)) {
248
+ delete this.state[key];
249
+ }
250
+ }
251
+
252
+ this.setModeForNextToken(Modes.newLayout);
253
+ if (spanningLayout) {
254
+ this.state.layoutType = type;
255
+ this.state.spanningLayout = true;
256
+ }
257
+ };
258
+
259
+
260
+ function RegExpFactory() {
261
+ this.cache = {};
262
+ this.single = {
263
+ bc: 'bc',
264
+ bq: 'bq',
265
+ definitionList: /- [^(?::=)]+:=+/,
266
+ definitionListEnd: /.*=:\s*$/,
267
+ div: 'div',
268
+ drawTable: /\|.*\|/,
269
+ foot: /fn\d+/,
270
+ header: /h[1-6]/,
271
+ html: /\s*<(?:\/)?(\w+)(?:[^>]+)?>(?:[^<]+<\/\1>)?/,
272
+ link: /[^"]+":\S/,
273
+ linkDefinition: /\[[^\s\]]+\]\S+/,
274
+ list: /(?:#+|\*+)/,
275
+ notextile: 'notextile',
276
+ para: 'p',
277
+ pre: 'pre',
278
+ table: 'table',
279
+ tableCellAttributes: /[/\\]\d+/,
280
+ tableHeading: /\|_\./,
281
+ tableText: /[^"_\*\[\(\?\+~\^%@|-]+/,
282
+ text: /[^!"_=\*\[\(<\?\+~\^%@-]+/
283
+ };
284
+ this.attributes = {
285
+ align: /(?:<>|<|>|=)/,
286
+ selector: /\([^\(][^\)]+\)/,
287
+ lang: /\[[^\[\]]+\]/,
288
+ pad: /(?:\(+|\)+){1,2}/,
289
+ css: /\{[^\}]+\}/
290
+ };
291
+ }
292
+
293
+ RegExpFactory.prototype.pattern = function(name) {
294
+ return (this.cache[name] || this.createRe(name));
295
+ };
296
+
297
+ RegExpFactory.prototype.createRe = function(name) {
298
+ switch (name) {
299
+ case 'drawTable':
300
+ return this.makeRe('^', this.single.drawTable, '$');
301
+ case 'html':
302
+ return this.makeRe('^', this.single.html, '(?:', this.single.html, ')*', '$');
303
+ case 'linkDefinition':
304
+ return this.makeRe('^', this.single.linkDefinition, '$');
305
+ case 'listLayout':
306
+ return this.makeRe('^', this.single.list, this.pattern('allAttributes'), '*\\s+');
307
+ case 'tableCellAttributes':
308
+ return this.makeRe('^', this.choiceRe(this.single.tableCellAttributes,
309
+ this.pattern('allAttributes')), '+\\.');
310
+ case 'type':
311
+ return this.makeRe('^', this.pattern('allTypes'));
312
+ case 'typeLayout':
313
+ return this.makeRe('^', this.pattern('allTypes'), this.pattern('allAttributes'),
314
+ '*\\.\\.?', '(\\s+|$)');
315
+ case 'attributes':
316
+ return this.makeRe('^', this.pattern('allAttributes'), '+');
317
+
318
+ case 'allTypes':
319
+ return this.choiceRe(this.single.div, this.single.foot,
320
+ this.single.header, this.single.bc, this.single.bq,
321
+ this.single.notextile, this.single.pre, this.single.table,
322
+ this.single.para);
323
+
324
+ case 'allAttributes':
325
+ return this.choiceRe(this.attributes.selector, this.attributes.css,
326
+ this.attributes.lang, this.attributes.align, this.attributes.pad);
327
+
328
+ default:
329
+ return this.makeRe('^', this.single[name]);
330
+ }
331
+ };
332
+
333
+
334
+ RegExpFactory.prototype.makeRe = function() {
335
+ var pattern = '',
336
+ i,
337
+ arg;
338
+
339
+ for (i = 0; i < arguments.length; ++i) {
340
+ arg = arguments[i];
341
+ pattern += (typeof arg === 'string') ? arg : arg.source;
342
+ }
343
+ return new RegExp(pattern);
344
+ };
345
+
346
+ RegExpFactory.prototype.choiceRe = function() {
347
+ var parts = [arguments[0]],
348
+ i;
349
+
350
+ for (i = 1; i < arguments.length; ++i) {
351
+ parts[i * 2 - 1] = '|';
352
+ parts[i * 2] = arguments[i];
353
+ }
354
+
355
+ parts.unshift('(?:');
356
+ parts.push(')');
357
+ return this.makeRe.apply(this, parts);
358
+ };
359
+
360
+
361
+ var Modes = {
362
+ newLayout: function() {
363
+ if (this.check('typeLayout')) {
364
+ this.state.spanningLayout = false;
365
+ return this.execMode(Modes.blockType);
366
+ }
367
+ if (!this.textileDisabled()) {
368
+ if (this.check('listLayout')) {
369
+ return this.execMode(Modes.list);
370
+ } else if (this.check('drawTable')) {
371
+ return this.execMode(Modes.table);
372
+ } else if (this.check('linkDefinition')) {
373
+ return this.execMode(Modes.linkDefinition);
374
+ } else if (this.check('definitionList')) {
375
+ return this.execMode(Modes.definitionList);
376
+ } else if (this.check('html')) {
377
+ return this.execMode(Modes.html);
378
+ }
379
+ }
380
+ return this.execMode(Modes.text);
381
+ },
382
+
383
+ blockType: function() {
384
+ var match,
385
+ type;
386
+ this.state.layoutType = null;
387
+
388
+ if (match = this.eat('type')) {
389
+ type = match[0];
390
+ } else {
391
+ return this.execMode(Modes.text);
392
+ }
393
+
394
+ if(match = type.match(this.regExpFactory.pattern('header'))) {
395
+ this.state.layoutType = 'header';
396
+ this.state.header = parseInt(match[0][1]);
397
+ } else if (type.match(this.regExpFactory.pattern('bq'))) {
398
+ this.state.layoutType = 'quote';
399
+ } else if (type.match(this.regExpFactory.pattern('bc'))) {
400
+ this.state.layoutType = 'code';
401
+ } else if (type.match(this.regExpFactory.pattern('foot'))) {
402
+ this.state.layoutType = 'footnote';
403
+ } else if (type.match(this.regExpFactory.pattern('notextile'))) {
404
+ this.state.layoutType = 'notextile';
405
+ } else if (type.match(this.regExpFactory.pattern('pre'))) {
406
+ this.state.layoutType = 'pre';
407
+ } else if (type.match(this.regExpFactory.pattern('div'))) {
408
+ this.state.layoutType = 'div';
409
+ } else if (type.match(this.regExpFactory.pattern('table'))) {
410
+ this.state.layoutType = 'table';
411
+ }
412
+
413
+ this.setModeForNextToken(Modes.attributes);
414
+ return this.tokenStyles();
415
+ },
416
+
417
+ text: function() {
418
+ if (this.eat('text')) {
419
+ return this.tokenStyles();
420
+ }
421
+
422
+ var ch = this.stream.next();
423
+
424
+ if (ch === '"') {
425
+ return this.execMode(Modes.link);
426
+ }
427
+ return this.handlePhraseModifier(ch);
428
+ },
429
+
430
+ attributes: function() {
431
+ this.setModeForNextToken(Modes.layoutLength);
432
+
433
+ if (this.eat('attributes')) {
434
+ return this.tokenStylesWith(this.styleFor('attributes'));
435
+ }
436
+ return this.tokenStyles();
437
+ },
438
+
439
+ layoutLength: function() {
440
+ if (this.stream.eat('.') && this.stream.eat('.')) {
441
+ this.state.spanningLayout = true;
442
+ }
443
+
444
+ this.setModeForNextToken(Modes.text);
445
+ return this.tokenStyles();
446
+ },
447
+
448
+ list: function() {
449
+ var match = this.eat('list'),
450
+ listMod;
451
+ this.state.listDepth = match[0].length;
452
+ listMod = (this.state.listDepth - 1) % 3;
453
+ if (!listMod) {
454
+ this.state.layoutType = 'list1';
455
+ } else if (listMod === 1) {
456
+ this.state.layoutType = 'list2';
457
+ } else {
458
+ this.state.layoutType = 'list3';
459
+ }
460
+ this.setModeForNextToken(Modes.attributes);
461
+ return this.tokenStyles();
462
+ },
463
+
464
+ link: function() {
465
+ this.setModeForNextToken(Modes.text);
466
+ if (this.eat('link')) {
467
+ this.stream.match(/\S+/);
468
+ return this.tokenStylesWith(this.styleFor('link'));
469
+ }
470
+ return this.tokenStyles();
471
+ },
472
+
473
+ linkDefinition: function() {
474
+ this.stream.skipToEnd();
475
+ return this.tokenStylesWith(this.styleFor('linkDefinition'));
476
+ },
477
+
478
+ definitionList: function() {
479
+ this.eat('definitionList');
480
+
481
+ this.state.layoutType = 'definitionList';
482
+
483
+ if (this.stream.match(/\s*$/)) {
484
+ this.state.spanningLayout = true;
485
+ } else {
486
+ this.setModeForNextToken(Modes.attributes);
487
+ }
488
+ return this.tokenStyles();
489
+ },
490
+
491
+ html: function() {
492
+ this.stream.skipToEnd();
493
+ return this.tokenStylesWith(this.styleFor('html'));
494
+ },
495
+
496
+ table: function() {
497
+ this.state.layoutType = 'table';
498
+ return this.execMode(Modes.tableCell);
499
+ },
500
+
501
+ tableCell: function() {
502
+ if (this.eat('tableHeading')) {
503
+ this.state.tableHeading = true;
504
+ } else {
505
+ this.stream.eat('|');
506
+ }
507
+ this.setModeForNextToken(Modes.tableCellAttributes);
508
+ return this.tokenStyles();
509
+ },
510
+
511
+ tableCellAttributes: function() {
512
+ this.setModeForNextToken(Modes.tableText);
513
+
514
+ if (this.eat('tableCellAttributes')) {
515
+ return this.tokenStylesWith(this.styleFor('attributes'));
516
+ }
517
+ return this.tokenStyles();
518
+ },
519
+
520
+ tableText: function() {
521
+ if (this.eat('tableText')) {
522
+ return this.tokenStyles();
523
+ }
524
+
525
+ if (this.stream.peek() === '|') { // end of cell
526
+ this.setModeForNextToken(Modes.tableCell);
527
+ return this.tokenStyles();
528
+ }
529
+ return this.handlePhraseModifier(this.stream.next());
530
+ }
531
+ };
532
+
533
+
534
+ CodeMirror.defineMode('textile', function() {
535
+ var regExpFactory = new RegExpFactory();
536
+
537
+ return {
538
+ startState: function() {
539
+ return { mode: Modes.newLayout };
540
+ },
541
+ token: function(stream, state) {
542
+ var parser = new Parser(regExpFactory, state, stream);
543
+ if (stream.sol()) { parser.startNewLine(); }
544
+ return parser.nextToken();
545
+ },
546
+ blankLine: function(state) {
547
+ new Parser(regExpFactory, state).blankLine();
548
+ }
549
+ };
550
+ });
551
+
552
+ CodeMirror.defineMIME('text/x-textile', 'textile');
553
+ });