codemirror-rails 4.8 → 4.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +24 -6
  3. data/lib/codemirror/rails/version.rb +2 -2
  4. data/vendor/assets/javascripts/codemirror.js +289 -184
  5. data/vendor/assets/javascripts/codemirror/addons/dialog/dialog.js +1 -1
  6. data/vendor/assets/javascripts/codemirror/addons/display/panel.js +94 -0
  7. data/vendor/assets/javascripts/codemirror/addons/edit/continuelist.js +4 -4
  8. data/vendor/assets/javascripts/codemirror/addons/hint/anyword-hint.js +1 -2
  9. data/vendor/assets/javascripts/codemirror/addons/hint/css-hint.js +1 -1
  10. data/vendor/assets/javascripts/codemirror/addons/hint/html-hint.js +1 -1
  11. data/vendor/assets/javascripts/codemirror/addons/hint/javascript-hint.js +8 -3
  12. data/vendor/assets/javascripts/codemirror/addons/hint/show-hint.js +1 -1
  13. data/vendor/assets/javascripts/codemirror/addons/hint/sql-hint.js +7 -4
  14. data/vendor/assets/javascripts/codemirror/addons/hint/xml-hint.js +3 -4
  15. data/vendor/assets/javascripts/codemirror/addons/merge/merge.js +170 -63
  16. data/vendor/assets/javascripts/codemirror/addons/mode/simple.js +11 -8
  17. data/vendor/assets/javascripts/codemirror/addons/scroll/annotatescrollbar.js +76 -0
  18. data/vendor/assets/javascripts/codemirror/addons/scroll/simplescrollbars.js +139 -0
  19. data/vendor/assets/javascripts/codemirror/addons/search/matchesonscrollbar.js +90 -0
  20. data/vendor/assets/javascripts/codemirror/addons/search/search.js +9 -4
  21. data/vendor/assets/javascripts/codemirror/addons/tern/tern.js +5 -3
  22. data/vendor/assets/javascripts/codemirror/keymaps/emacs.js +25 -7
  23. data/vendor/assets/javascripts/codemirror/keymaps/vim.js +181 -109
  24. data/vendor/assets/javascripts/codemirror/modes/coffeescript.js +2 -2
  25. data/vendor/assets/javascripts/codemirror/modes/commonlisp.js +5 -3
  26. data/vendor/assets/javascripts/codemirror/modes/cypher.js +1 -1
  27. data/vendor/assets/javascripts/codemirror/modes/dart.js +50 -0
  28. data/vendor/assets/javascripts/codemirror/modes/dockerfile.js +5 -9
  29. data/vendor/assets/javascripts/codemirror/modes/ebnf.js +195 -0
  30. data/vendor/assets/javascripts/codemirror/modes/javascript.js +2 -0
  31. data/vendor/assets/javascripts/codemirror/modes/markdown.js +3 -3
  32. data/vendor/assets/javascripts/codemirror/modes/puppet.js +2 -2
  33. data/vendor/assets/javascripts/codemirror/modes/shell.js +2 -1
  34. data/vendor/assets/javascripts/codemirror/modes/soy.js +198 -0
  35. data/vendor/assets/javascripts/codemirror/modes/spreadsheet.js +109 -0
  36. data/vendor/assets/javascripts/codemirror/modes/stex.js +4 -6
  37. data/vendor/assets/javascripts/codemirror/modes/textile.js +392 -476
  38. data/vendor/assets/javascripts/codemirror/modes/turtle.js +3 -1
  39. data/vendor/assets/stylesheets/codemirror.css +2 -11
  40. data/vendor/assets/stylesheets/codemirror/addons/merge/merge.css +14 -0
  41. data/vendor/assets/stylesheets/codemirror/addons/scroll/simplescrollbars.css +66 -0
  42. data/vendor/assets/stylesheets/codemirror/addons/search/matchesonscrollbar.css +8 -0
  43. data/vendor/assets/stylesheets/codemirror/themes/tomorrow-night-bright.css +35 -0
  44. data/vendor/assets/stylesheets/codemirror/themes/zenburn.css +37 -0
  45. metadata +14 -3
  46. data/vendor/assets/javascripts/codemirror/addons/hint/python-hint.js +0 -102
@@ -0,0 +1,109 @@
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
+ })(function(CodeMirror) {
12
+ "use strict";
13
+
14
+ CodeMirror.defineMode("spreadsheet", function () {
15
+ return {
16
+ startState: function () {
17
+ return {
18
+ stringType: null,
19
+ stack: []
20
+ };
21
+ },
22
+ token: function (stream, state) {
23
+ if (!stream) return;
24
+
25
+ //check for state changes
26
+ if (state.stack.length === 0) {
27
+ //strings
28
+ if ((stream.peek() == '"') || (stream.peek() == "'")) {
29
+ state.stringType = stream.peek();
30
+ stream.next(); // Skip quote
31
+ state.stack.unshift("string");
32
+ }
33
+ }
34
+
35
+ //return state
36
+ //stack has
37
+ switch (state.stack[0]) {
38
+ case "string":
39
+ while (state.stack[0] === "string" && !stream.eol()) {
40
+ if (stream.peek() === state.stringType) {
41
+ stream.next(); // Skip quote
42
+ state.stack.shift(); // Clear flag
43
+ } else if (stream.peek() === "\\") {
44
+ stream.next();
45
+ stream.next();
46
+ } else {
47
+ stream.match(/^.[^\\\"\']*/);
48
+ }
49
+ }
50
+ return "string";
51
+
52
+ case "characterClass":
53
+ while (state.stack[0] === "characterClass" && !stream.eol()) {
54
+ if (!(stream.match(/^[^\]\\]+/) || stream.match(/^\\./)))
55
+ state.stack.shift();
56
+ }
57
+ return "operator";
58
+ }
59
+
60
+ var peek = stream.peek();
61
+
62
+ //no stack
63
+ switch (peek) {
64
+ case "[":
65
+ stream.next();
66
+ state.stack.unshift("characterClass");
67
+ return "bracket";
68
+ case ":":
69
+ stream.next();
70
+ return "operator";
71
+ case "\\":
72
+ if (stream.match(/\\[a-z]+/)) return "string-2";
73
+ else return null;
74
+ case ".":
75
+ case ",":
76
+ case ";":
77
+ case "*":
78
+ case "-":
79
+ case "+":
80
+ case "^":
81
+ case "<":
82
+ case "/":
83
+ case "=":
84
+ stream.next();
85
+ return "atom";
86
+ case "$":
87
+ stream.next();
88
+ return "builtin";
89
+ }
90
+
91
+ if (stream.match(/\d+/)) {
92
+ if (stream.match(/^\w+/)) return "error";
93
+ return "number";
94
+ } else if (stream.match(/^[a-zA-Z_]\w*/)) {
95
+ if (stream.match(/(?=[\(.])/, false)) return "keyword";
96
+ return "variable-2";
97
+ } else if (["[", "]", "(", ")", "{", "}"].indexOf(peek) != -1) {
98
+ stream.next();
99
+ return "bracket";
100
+ } else if (!stream.eatSpace()) {
101
+ stream.next();
102
+ }
103
+ return null;
104
+ }
105
+ };
106
+ });
107
+
108
+ CodeMirror.defineMIME("text/x-spreadsheet", "spreadsheet");
109
+ });
@@ -130,8 +130,7 @@
130
130
  if (ch == "%") {
131
131
  source.skipToEnd();
132
132
  return "comment";
133
- }
134
- else if (ch == '}' || ch == ']') {
133
+ } else if (ch == '}' || ch == ']') {
135
134
  plug = peekCommand(state);
136
135
  if (plug) {
137
136
  plug.closeBracket(ch);
@@ -145,12 +144,10 @@
145
144
  plug = new plug();
146
145
  pushCommand(state, plug);
147
146
  return "bracket";
148
- }
149
- else if (/\d/.test(ch)) {
147
+ } else if (/\d/.test(ch)) {
150
148
  source.eatWhile(/[\w.%]/);
151
149
  return "atom";
152
- }
153
- else {
150
+ } else {
154
151
  source.eatWhile(/[\w\-_]/);
155
152
  plug = getMostPowerful(state);
156
153
  if (plug.name == 'begin') {
@@ -242,6 +239,7 @@
242
239
  },
243
240
  blankLine: function(state) {
244
241
  state.f = normal;
242
+ state.cmdState.length = 0;
245
243
  },
246
244
  lineComment: "%"
247
245
  };
@@ -2,552 +2,468 @@
2
2
  // Distributed under an MIT license: http://codemirror.net/LICENSE
3
3
 
4
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);
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
9
  } else { // Plain browser env
10
10
  mod(CodeMirror);
11
11
  }
12
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
- };
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
+ };
84
48
 
85
- Parser.prototype.nextToken = function() {
86
- return this.state.mode.call(this);
87
- };
49
+ function startNewLine(stream, state) {
50
+ state.mode = Modes.newLayout;
51
+ state.tableHeading = false;
88
52
 
89
- Parser.prototype.styleFor = function(token) {
90
- if (this.styles.hasOwnProperty(token)) {
91
- return this.styles[token];
53
+ if (state.layoutType === "definitionList" && state.spanningLayout &&
54
+ stream.match(RE("definitionListEnd"), false))
55
+ state.spanningLayout = false;
92
56
  }
93
- throw 'unknown token';
94
- };
95
57
 
96
- Parser.prototype.handlePhraseModifier = function(ch) {
97
- if (ch === '_') {
98
- if (this.stream.eat('_')) {
99
- return this.togglePhraseModifier('italic', /^.*__/);
58
+ function handlePhraseModifier(stream, state, ch) {
59
+ if (ch === "_") {
60
+ if (stream.eat("_"))
61
+ return togglePhraseModifier(stream, state, "italic", /__/, 2);
62
+ else
63
+ return togglePhraseModifier(stream, state, "em", /_/, 1);
100
64
  }
101
- return this.togglePhraseModifier('em', /^.*_/);
102
- }
103
65
 
104
- if (ch === '*') {
105
- if (this.stream.eat('*')) {
106
- return this.togglePhraseModifier('bold', /^.*\*\*/);
66
+ if (ch === "*") {
67
+ if (stream.eat("*")) {
68
+ return togglePhraseModifier(stream, state, "bold", /\*\*/, 2);
69
+ }
70
+ return togglePhraseModifier(stream, state, "strong", /\*/, 1);
107
71
  }
108
- return this.togglePhraseModifier('strong', /^.*\*/);
109
- }
110
72
 
111
- if (ch === '[') {
112
- if (this.stream.match(/\d+\]/)) {
113
- this.state.footCite = true;
73
+ if (ch === "[") {
74
+ if (stream.match(/\d+\]/)) state.footCite = true;
75
+ return tokenStyles(state);
114
76
  }
115
- return this.tokenStyles();
116
- }
117
77
 
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';
78
+ if (ch === "(") {
79
+ var spec = stream.match(/^(r|tm|c)\)/);
80
+ if (spec)
81
+ return tokenStylesWith(state, TOKEN_STYLES.specialChar);
125
82
  }
126
- return this.tokenStyles();
127
- }
128
83
 
129
- if (ch === '<') {
130
- if (this.stream.match(/(\w+)[^>]+>[^<]+<\/\1>/)) {
131
- return this.tokenStylesWith(this.styleFor('html'));
132
- }
133
- }
84
+ if (ch === "<" && stream.match(/(\w+)[^>]+>[^<]+<\/\1>/))
85
+ return tokenStylesWith(state, TOKEN_STYLES.html);
134
86
 
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
- };
87
+ if (ch === "?" && stream.eat("?"))
88
+ return togglePhraseModifier(stream, state, "cite", /\?\?/, 2);
179
89
 
180
- Parser.prototype.tokenStyles = function() {
181
- var disabled = this.textileDisabled(),
182
- styles = [];
90
+ if (ch === "=" && stream.eat("="))
91
+ return togglePhraseModifier(stream, state, "notextile", /==/, 2);
183
92
 
184
- if (disabled) return disabled;
93
+ if (ch === "-" && !stream.eat("-"))
94
+ return togglePhraseModifier(stream, state, "deletion", /-/, 1);
185
95
 
186
- if (this.state.layoutType) {
187
- styles.push(this.styleFor(this.state.layoutType));
188
- }
96
+ if (ch === "+")
97
+ return togglePhraseModifier(stream, state, "addition", /\+/, 1);
189
98
 
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'));
99
+ if (ch === "~")
100
+ return togglePhraseModifier(stream, state, "sub", /~/, 1);
193
101
 
194
- if (this.state.layoutType === 'header') {
195
- styles.push(this.styleFor('header') + '-' + this.state.header);
196
- }
197
- return styles.length ? styles.join(' ') : null;
198
- };
102
+ if (ch === "^")
103
+ return togglePhraseModifier(stream, state, "sup", /\^/, 1);
199
104
 
200
- Parser.prototype.textileDisabled = function() {
201
- var type = this.state.layoutType;
105
+ if (ch === "%")
106
+ return togglePhraseModifier(stream, state, "span", /%/, 1);
202
107
 
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
- }
108
+ if (ch === "@")
109
+ return togglePhraseModifier(stream, state, "code", /@/, 1);
212
110
 
213
- return null;
111
+ if (ch === "!") {
112
+ var type = togglePhraseModifier(stream, state, "image", /(?:\([^\)]+\))?!/, 1);
113
+ stream.match(/^:\S+/); // optional Url portion
114
+ return type;
115
+ }
116
+ return tokenStyles(state);
214
117
  }
215
- };
216
118
 
217
- Parser.prototype.tokenStylesWith = function(extraStyles) {
218
- var disabled = this.textileDisabled(),
219
- type;
119
+ function togglePhraseModifier(stream, state, phraseModifier, closeRE, openSize) {
120
+ var charBefore = stream.pos > openSize ? stream.string.charAt(stream.pos - openSize - 1) : null;
121
+ var charAfter = stream.peek();
122
+ if (state[phraseModifier]) {
123
+ if ((!charAfter || /\W/.test(charAfter)) && charBefore && /\S/.test(charBefore)) {
124
+ var type = tokenStyles(state);
125
+ state[phraseModifier] = false;
126
+ return type;
127
+ }
128
+ } else if ((!charBefore || /\W/.test(charBefore)) && charAfter && /\S/.test(charAfter) &&
129
+ stream.match(new RegExp("^.*\\S" + closeRE.source + "(?:\\W|$)"), false)) {
130
+ state[phraseModifier] = true;
131
+ state.mode = Modes.attributes;
132
+ }
133
+ return tokenStyles(state);
134
+ };
220
135
 
221
- if (disabled) return disabled;
136
+ function tokenStyles(state) {
137
+ var disabled = textileDisabled(state);
138
+ if (disabled) return disabled;
222
139
 
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
- };
140
+ var styles = [];
141
+ if (state.layoutType) styles.push(TOKEN_STYLES[state.layoutType]);
240
142
 
241
- Parser.prototype.blankLine = function() {
242
- var spanningLayout = this.state.spanningLayout,
243
- type = this.state.layoutType,
244
- key;
143
+ styles = styles.concat(activeStyles(
144
+ state, "addition", "bold", "cite", "code", "deletion", "em", "footCite",
145
+ "image", "italic", "link", "span", "strong", "sub", "sup", "table", "tableHeading"));
245
146
 
246
- for (key in this.state) {
247
- if (this.state.hasOwnProperty(key)) {
248
- delete this.state[key];
249
- }
250
- }
147
+ if (state.layoutType === "header")
148
+ styles.push(TOKEN_STYLES.header + "-" + state.header);
251
149
 
252
- this.setModeForNextToken(Modes.newLayout);
253
- if (spanningLayout) {
254
- this.state.layoutType = type;
255
- this.state.spanningLayout = true;
150
+ return styles.length ? styles.join(" ") : null;
256
151
  }
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
152
 
153
+ function textileDisabled(state) {
154
+ var type = state.layoutType;
155
+
156
+ switch(type) {
157
+ case "notextile":
158
+ case "code":
159
+ case "pre":
160
+ return TOKEN_STYLES[type];
328
161
  default:
329
- return this.makeRe('^', this.single[name]);
162
+ if (state.notextile)
163
+ return TOKEN_STYLES.notextile + (type ? (" " + TOKEN_STYLES[type]) : "");
164
+ return null;
165
+ }
330
166
  }
331
- };
332
167
 
168
+ function tokenStylesWith(state, extraStyles) {
169
+ var disabled = textileDisabled(state);
170
+ if (disabled) return disabled;
333
171
 
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;
172
+ var type = tokenStyles(state);
173
+ if (extraStyles)
174
+ return type ? (type + " " + extraStyles) : extraStyles;
175
+ else
176
+ return type;
342
177
  }
343
- return new RegExp(pattern);
344
- };
345
-
346
- RegExpFactory.prototype.choiceRe = function() {
347
- var parts = [arguments[0]],
348
- i;
349
178
 
350
- for (i = 1; i < arguments.length; ++i) {
351
- parts[i * 2 - 1] = '|';
352
- parts[i * 2] = arguments[i];
179
+ function activeStyles(state) {
180
+ var styles = [];
181
+ for (var i = 1; i < arguments.length; ++i) {
182
+ if (state[arguments[i]])
183
+ styles.push(TOKEN_STYLES[arguments[i]]);
184
+ }
185
+ return styles;
353
186
  }
354
187
 
355
- parts.unshift('(?:');
356
- parts.push(')');
357
- return this.makeRe.apply(this, parts);
358
- };
188
+ function blankLine(state) {
189
+ var spanningLayout = state.spanningLayout, type = state.layoutType;
359
190
 
191
+ for (var key in state) if (state.hasOwnProperty(key))
192
+ delete state[key];
360
193
 
361
- var Modes = {
362
- newLayout: function() {
363
- if (this.check('typeLayout')) {
364
- this.state.spanningLayout = false;
365
- return this.execMode(Modes.blockType);
194
+ state.mode = Modes.newLayout;
195
+ if (spanningLayout) {
196
+ state.layoutType = type;
197
+ state.spanningLayout = true;
366
198
  }
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);
199
+ }
200
+
201
+ var REs = {
202
+ cache: {},
203
+ single: {
204
+ bc: "bc",
205
+ bq: "bq",
206
+ definitionList: /- [^(?::=)]+:=+/,
207
+ definitionListEnd: /.*=:\s*$/,
208
+ div: "div",
209
+ drawTable: /\|.*\|/,
210
+ foot: /fn\d+/,
211
+ header: /h[1-6]/,
212
+ html: /\s*<(?:\/)?(\w+)(?:[^>]+)?>(?:[^<]+<\/\1>)?/,
213
+ link: /[^"]+":\S/,
214
+ linkDefinition: /\[[^\s\]]+\]\S+/,
215
+ list: /(?:#+|\*+)/,
216
+ notextile: "notextile",
217
+ para: "p",
218
+ pre: "pre",
219
+ table: "table",
220
+ tableCellAttributes: /[\/\\]\d+/,
221
+ tableHeading: /\|_\./,
222
+ tableText: /[^"_\*\[\(\?\+~\^%@|-]+/,
223
+ text: /[^!"_=\*\[\(<\?\+~\^%@-]+/
224
+ },
225
+ attributes: {
226
+ align: /(?:<>|<|>|=)/,
227
+ selector: /\([^\(][^\)]+\)/,
228
+ lang: /\[[^\[\]]+\]/,
229
+ pad: /(?:\(+|\)+){1,2}/,
230
+ css: /\{[^\}]+\}/
231
+ },
232
+ createRe: function(name) {
233
+ switch (name) {
234
+ case "drawTable":
235
+ return REs.makeRe("^", REs.single.drawTable, "$");
236
+ case "html":
237
+ return REs.makeRe("^", REs.single.html, "(?:", REs.single.html, ")*", "$");
238
+ case "linkDefinition":
239
+ return REs.makeRe("^", REs.single.linkDefinition, "$");
240
+ case "listLayout":
241
+ return REs.makeRe("^", REs.single.list, RE("allAttributes"), "*\\s+");
242
+ case "tableCellAttributes":
243
+ return REs.makeRe("^", REs.choiceRe(REs.single.tableCellAttributes,
244
+ RE("allAttributes")), "+\\.");
245
+ case "type":
246
+ return REs.makeRe("^", RE("allTypes"));
247
+ case "typeLayout":
248
+ return REs.makeRe("^", RE("allTypes"), RE("allAttributes"),
249
+ "*\\.\\.?", "(\\s+|$)");
250
+ case "attributes":
251
+ return REs.makeRe("^", RE("allAttributes"), "+");
252
+
253
+ case "allTypes":
254
+ return REs.choiceRe(REs.single.div, REs.single.foot,
255
+ REs.single.header, REs.single.bc, REs.single.bq,
256
+ REs.single.notextile, REs.single.pre, REs.single.table,
257
+ REs.single.para);
258
+
259
+ case "allAttributes":
260
+ return REs.choiceRe(REs.attributes.selector, REs.attributes.css,
261
+ REs.attributes.lang, REs.attributes.align, REs.attributes.pad);
262
+
263
+ default:
264
+ return REs.makeRe("^", REs.single[name]);
265
+ }
266
+ },
267
+ makeRe: function() {
268
+ var pattern = "";
269
+ for (var i = 0; i < arguments.length; ++i) {
270
+ var arg = arguments[i];
271
+ pattern += (typeof arg === "string") ? arg : arg.source;
272
+ }
273
+ return new RegExp(pattern);
274
+ },
275
+ choiceRe: function() {
276
+ var parts = [arguments[0]];
277
+ for (var i = 1; i < arguments.length; ++i) {
278
+ parts[i * 2 - 1] = "|";
279
+ parts[i * 2] = arguments[i];
378
280
  }
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
281
 
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';
282
+ parts.unshift("(?:");
283
+ parts.push(")");
284
+ return REs.makeRe.apply(null, parts);
411
285
  }
286
+ };
412
287
 
413
- this.setModeForNextToken(Modes.attributes);
414
- return this.tokenStyles();
415
- },
288
+ function RE(name) {
289
+ return (REs.cache[name] || (REs.cache[name] = REs.createRe(name)));
290
+ }
416
291
 
417
- text: function() {
418
- if (this.eat('text')) {
419
- return this.tokenStyles();
420
- }
292
+ var Modes = {
293
+ newLayout: function(stream, state) {
294
+ if (stream.match(RE("typeLayout"), false)) {
295
+ state.spanningLayout = false;
296
+ return (state.mode = Modes.blockType)(stream, state);
297
+ }
298
+ var newMode;
299
+ if (!textileDisabled(state)) {
300
+ if (stream.match(RE("listLayout"), false))
301
+ newMode = Modes.list;
302
+ else if (stream.match(RE("drawTable"), false))
303
+ newMode = Modes.table;
304
+ else if (stream.match(RE("linkDefinition"), false))
305
+ newMode = Modes.linkDefinition;
306
+ else if (stream.match(RE("definitionList")))
307
+ newMode = Modes.definitionList;
308
+ else if (stream.match(RE("html"), false))
309
+ newMode = Modes.html;
310
+ }
311
+ return (state.mode = (newMode || Modes.text))(stream, state);
312
+ },
421
313
 
422
- var ch = this.stream.next();
314
+ blockType: function(stream, state) {
315
+ var match, type;
316
+ state.layoutType = null;
317
+
318
+ if (match = stream.match(RE("type")))
319
+ type = match[0];
320
+ else
321
+ return (state.mode = Modes.text)(stream, state);
322
+
323
+ if (match = type.match(RE("header"))) {
324
+ state.layoutType = "header";
325
+ state.header = parseInt(match[0][1]);
326
+ } else if (type.match(RE("bq"))) {
327
+ state.layoutType = "quote";
328
+ } else if (type.match(RE("bc"))) {
329
+ state.layoutType = "code";
330
+ } else if (type.match(RE("foot"))) {
331
+ state.layoutType = "footnote";
332
+ } else if (type.match(RE("notextile"))) {
333
+ state.layoutType = "notextile";
334
+ } else if (type.match(RE("pre"))) {
335
+ state.layoutType = "pre";
336
+ } else if (type.match(RE("div"))) {
337
+ state.layoutType = "div";
338
+ } else if (type.match(RE("table"))) {
339
+ state.layoutType = "table";
340
+ }
423
341
 
424
- if (ch === '"') {
425
- return this.execMode(Modes.link);
426
- }
427
- return this.handlePhraseModifier(ch);
428
- },
342
+ state.mode = Modes.attributes;
343
+ return tokenStyles(state);
344
+ },
429
345
 
430
- attributes: function() {
431
- this.setModeForNextToken(Modes.layoutLength);
346
+ text: function(stream, state) {
347
+ if (stream.match(RE("text"))) return tokenStyles(state);
432
348
 
433
- if (this.eat('attributes')) {
434
- return this.tokenStylesWith(this.styleFor('attributes'));
435
- }
436
- return this.tokenStyles();
437
- },
349
+ var ch = stream.next();
350
+ if (ch === '"')
351
+ return (state.mode = Modes.link)(stream, state);
352
+ return handlePhraseModifier(stream, state, ch);
353
+ },
438
354
 
439
- layoutLength: function() {
440
- if (this.stream.eat('.') && this.stream.eat('.')) {
441
- this.state.spanningLayout = true;
442
- }
355
+ attributes: function(stream, state) {
356
+ state.mode = Modes.layoutLength;
443
357
 
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
- },
358
+ if (stream.match(RE("attributes")))
359
+ return tokenStylesWith(state, TOKEN_STYLES.attributes);
360
+ else
361
+ return tokenStyles(state);
362
+ },
472
363
 
473
- linkDefinition: function() {
474
- this.stream.skipToEnd();
475
- return this.tokenStylesWith(this.styleFor('linkDefinition'));
476
- },
364
+ layoutLength: function(stream, state) {
365
+ if (stream.eat(".") && stream.eat("."))
366
+ state.spanningLayout = true;
477
367
 
478
- definitionList: function() {
479
- this.eat('definitionList');
368
+ state.mode = Modes.text;
369
+ return tokenStyles(state);
370
+ },
480
371
 
481
- this.state.layoutType = 'definitionList';
372
+ list: function(stream, state) {
373
+ var match = stream.match(RE("list"));
374
+ state.listDepth = match[0].length;
375
+ var listMod = (state.listDepth - 1) % 3;
376
+ if (!listMod)
377
+ state.layoutType = "list1";
378
+ else if (listMod === 1)
379
+ state.layoutType = "list2";
380
+ else
381
+ state.layoutType = "list3";
382
+
383
+ state.mode = Modes.attributes;
384
+ return tokenStyles(state);
385
+ },
482
386
 
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
- },
387
+ link: function(stream, state) {
388
+ state.mode = Modes.text;
389
+ if (stream.match(RE("link"))) {
390
+ stream.match(/\S+/);
391
+ return tokenStylesWith(state, TOKEN_STYLES.link);
392
+ }
393
+ return tokenStyles(state);
394
+ },
510
395
 
511
- tableCellAttributes: function() {
512
- this.setModeForNextToken(Modes.tableText);
396
+ linkDefinition: function(stream, state) {
397
+ stream.skipToEnd();
398
+ return tokenStylesWith(state, TOKEN_STYLES.linkDefinition);
399
+ },
513
400
 
514
- if (this.eat('tableCellAttributes')) {
515
- return this.tokenStylesWith(this.styleFor('attributes'));
516
- }
517
- return this.tokenStyles();
518
- },
401
+ definitionList: function(stream, state) {
402
+ stream.match(RE("definitionList"));
519
403
 
520
- tableText: function() {
521
- if (this.eat('tableText')) {
522
- return this.tokenStyles();
523
- }
404
+ state.layoutType = "definitionList";
524
405
 
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
- };
406
+ if (stream.match(/\s*$/))
407
+ state.spanningLayout = true;
408
+ else
409
+ state.mode = Modes.attributes;
532
410
 
411
+ return tokenStyles(state);
412
+ },
533
413
 
534
- CodeMirror.defineMode('textile', function() {
535
- var regExpFactory = new RegExpFactory();
414
+ html: function(stream, state) {
415
+ stream.skipToEnd();
416
+ return tokenStylesWith(state, TOKEN_STYLES.html);
417
+ },
536
418
 
537
- return {
538
- startState: function() {
539
- return { mode: Modes.newLayout };
419
+ table: function(stream, state) {
420
+ state.layoutType = "table";
421
+ return (state.mode = Modes.tableCell)(stream, state);
540
422
  },
541
- token: function(stream, state) {
542
- var parser = new Parser(regExpFactory, state, stream);
543
- if (stream.sol()) { parser.startNewLine(); }
544
- return parser.nextToken();
423
+
424
+ tableCell: function(stream, state) {
425
+ if (stream.match(RE("tableHeading")))
426
+ state.tableHeading = true;
427
+ else
428
+ stream.eat("|");
429
+
430
+ state.mode = Modes.tableCellAttributes;
431
+ return tokenStyles(state);
545
432
  },
546
- blankLine: function(state) {
547
- new Parser(regExpFactory, state).blankLine();
433
+
434
+ tableCellAttributes: function(stream, state) {
435
+ state.mode = Modes.tableText;
436
+
437
+ if (stream.match(RE("tableCellAttributes")))
438
+ return tokenStylesWith(state, TOKEN_STYLES.attributes);
439
+ else
440
+ return tokenStyles(state);
441
+ },
442
+
443
+ tableText: function(stream, state) {
444
+ if (stream.match(RE("tableText")))
445
+ return tokenStyles(state);
446
+
447
+ if (stream.peek() === "|") { // end of cell
448
+ state.mode = Modes.tableCell;
449
+ return tokenStyles(state);
450
+ }
451
+ return handlePhraseModifier(stream, state, stream.next());
548
452
  }
549
453
  };
550
- });
551
454
 
552
- CodeMirror.defineMIME('text/x-textile', 'textile');
455
+ CodeMirror.defineMode("textile", function() {
456
+ return {
457
+ startState: function() {
458
+ return { mode: Modes.newLayout };
459
+ },
460
+ token: function(stream, state) {
461
+ if (stream.sol()) startNewLine(stream, state);
462
+ return state.mode(stream, state);
463
+ },
464
+ blankLine: blankLine
465
+ };
466
+ });
467
+
468
+ CodeMirror.defineMIME("text/x-textile", "textile");
553
469
  });