codemirror-rails 4.8 → 4.9

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 (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
  });