codemirror-rails 2.3 → 2.21

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) hide show
  1. data/README.md +0 -16
  2. data/codemirror-rails.gemspec +1 -1
  3. data/lib/codemirror/rails/version.rb +2 -2
  4. data/vendor/assets/javascripts/codemirror.js +323 -687
  5. data/vendor/assets/javascripts/codemirror/modes/clike.js +3 -40
  6. data/vendor/assets/javascripts/codemirror/modes/clojure.js +14 -14
  7. data/vendor/assets/javascripts/codemirror/modes/coffeescript.js +0 -6
  8. data/vendor/assets/javascripts/codemirror/modes/css.js +1 -1
  9. data/vendor/assets/javascripts/codemirror/modes/diff.js +5 -24
  10. data/vendor/assets/javascripts/codemirror/modes/gfm.js +4 -40
  11. data/vendor/assets/javascripts/codemirror/modes/go.js +22 -20
  12. data/vendor/assets/javascripts/codemirror/modes/htmlembedded.js +1 -1
  13. data/vendor/assets/javascripts/codemirror/modes/htmlmixed.js +2 -4
  14. data/vendor/assets/javascripts/codemirror/modes/javascript.js +7 -8
  15. data/vendor/assets/javascripts/codemirror/modes/less.js +54 -100
  16. data/vendor/assets/javascripts/codemirror/modes/markdown.js +49 -52
  17. data/vendor/assets/javascripts/codemirror/modes/pascal.js +46 -2
  18. data/vendor/assets/javascripts/codemirror/modes/perl.js +1 -1
  19. data/vendor/assets/javascripts/codemirror/modes/php.js +25 -54
  20. data/vendor/assets/javascripts/codemirror/modes/python.js +16 -14
  21. data/vendor/assets/javascripts/codemirror/modes/rpm-spec.js +1 -1
  22. data/vendor/assets/javascripts/codemirror/modes/rst.js +1 -1
  23. data/vendor/assets/javascripts/codemirror/modes/ruby.js +9 -4
  24. data/vendor/assets/javascripts/codemirror/modes/scheme.js +46 -74
  25. data/vendor/assets/javascripts/codemirror/modes/smalltalk.js +16 -16
  26. data/vendor/assets/javascripts/codemirror/modes/stex.js +6 -21
  27. data/vendor/assets/javascripts/codemirror/modes/tiddlywiki.js +45 -55
  28. data/vendor/assets/javascripts/codemirror/modes/xml.js +14 -79
  29. data/vendor/assets/javascripts/codemirror/{utils/overlay.js → overlay.js} +2 -3
  30. data/vendor/assets/javascripts/codemirror/runmode.js +27 -0
  31. data/vendor/assets/stylesheets/codemirror.css +2 -63
  32. data/vendor/assets/stylesheets/codemirror/modes/tiddlywiki.css +21 -14
  33. data/vendor/assets/stylesheets/codemirror/themes/eclipse.css +1 -1
  34. data/vendor/assets/stylesheets/codemirror/themes/elegant.css +2 -2
  35. data/vendor/assets/stylesheets/codemirror/themes/neat.css +3 -3
  36. data/vendor/assets/stylesheets/codemirror/themes/night.css +1 -1
  37. data/vendor/assets/stylesheets/codemirror/themes/rubyblue.css +2 -2
  38. metadata +6 -39
  39. data/vendor/assets/javascripts/codemirror/keymaps/emacs.js +0 -29
  40. data/vendor/assets/javascripts/codemirror/keymaps/vim.js +0 -766
  41. data/vendor/assets/javascripts/codemirror/modes/ecl.js +0 -203
  42. data/vendor/assets/javascripts/codemirror/modes/erlang.js +0 -251
  43. data/vendor/assets/javascripts/codemirror/modes/pig.js +0 -172
  44. data/vendor/assets/javascripts/codemirror/modes/properties.js +0 -63
  45. data/vendor/assets/javascripts/codemirror/modes/shell.js +0 -103
  46. data/vendor/assets/javascripts/codemirror/modes/smarty.js +0 -148
  47. data/vendor/assets/javascripts/codemirror/modes/tiki.js +0 -316
  48. data/vendor/assets/javascripts/codemirror/modes/vbscript.js +0 -26
  49. data/vendor/assets/javascripts/codemirror/modes/xquery.js +0 -448
  50. data/vendor/assets/javascripts/codemirror/utils/closetag.js +0 -146
  51. data/vendor/assets/javascripts/codemirror/utils/dialog.js +0 -63
  52. data/vendor/assets/javascripts/codemirror/utils/foldcode.js +0 -196
  53. data/vendor/assets/javascripts/codemirror/utils/formatting.js +0 -297
  54. data/vendor/assets/javascripts/codemirror/utils/javascript-hint.js +0 -134
  55. data/vendor/assets/javascripts/codemirror/utils/loadmode.js +0 -51
  56. data/vendor/assets/javascripts/codemirror/utils/match-highlighter.js +0 -44
  57. data/vendor/assets/javascripts/codemirror/utils/multiplex.js +0 -72
  58. data/vendor/assets/javascripts/codemirror/utils/pig-hint.js +0 -123
  59. data/vendor/assets/javascripts/codemirror/utils/runmode.js +0 -49
  60. data/vendor/assets/javascripts/codemirror/utils/search.js +0 -118
  61. data/vendor/assets/javascripts/codemirror/utils/searchcursor.js +0 -117
  62. data/vendor/assets/javascripts/codemirror/utils/simple-hint.js +0 -72
  63. data/vendor/assets/stylesheets/codemirror/modes/tiki.css +0 -26
  64. data/vendor/assets/stylesheets/codemirror/themes/ambiance.css +0 -81
  65. data/vendor/assets/stylesheets/codemirror/themes/blackboard.css +0 -25
  66. data/vendor/assets/stylesheets/codemirror/themes/erlang-dark.css +0 -21
  67. data/vendor/assets/stylesheets/codemirror/themes/lesser-dark.css +0 -44
  68. data/vendor/assets/stylesheets/codemirror/themes/vibrant-ink.css +0 -27
  69. data/vendor/assets/stylesheets/codemirror/themes/xq-dark.css +0 -46
  70. data/vendor/assets/stylesheets/codemirror/utils/dialog.css +0 -23
  71. data/vendor/assets/stylesheets/codemirror/utils/simple-hint.css +0 -16
@@ -13,10 +13,11 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
13
13
  , strong = 'strong'
14
14
  , emstrong = 'emstrong';
15
15
 
16
- var hrRE = /^([*\-=_])(?:\s*\1){2,}\s*$/
17
- , ulRE = /^[*\-+]\s+/
18
- , olRE = /^[0-9]+\.\s+/
16
+ var hrRE = /^[*-=_]/
17
+ , ulRE = /^[*-+]\s+/
18
+ , olRE = /^[0-9]\.\s+/
19
19
  , headerRE = /^(?:\={3,}|-{3,})$/
20
+ , codeRE = /^(k:\t|\s{4,})/
20
21
  , textRE = /^[^\[*_\\<>`]+/;
21
22
 
22
23
  function switchInline(stream, state, f) {
@@ -32,32 +33,36 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
32
33
 
33
34
  // Blocks
34
35
 
35
- function blankLine(state) {
36
- // Reset EM state
37
- state.em = false;
38
- // Reset STRONG state
39
- state.strong = false;
40
- return null;
41
- }
42
-
43
36
  function blockNormal(stream, state) {
44
- var match;
45
- if (state.indentationDiff >= 4) {
46
- state.indentation -= state.indentationDiff;
37
+ if (stream.match(codeRE)) {
47
38
  stream.skipToEnd();
48
39
  return code;
49
- } else if (stream.eatSpace()) {
40
+ }
41
+
42
+ if (stream.eatSpace()) {
50
43
  return null;
51
- } else if (stream.peek() === '#' || stream.match(headerRE)) {
52
- state.header = true;
53
- } else if (stream.eat('>')) {
44
+ }
45
+
46
+ if (stream.peek() === '#' || stream.match(headerRE)) {
47
+ stream.skipToEnd();
48
+ return header;
49
+ }
50
+ if (stream.eat('>')) {
54
51
  state.indentation++;
55
- state.quote = true;
56
- } else if (stream.peek() === '[') {
52
+ return quote;
53
+ }
54
+ if (stream.peek() === '[') {
57
55
  return switchInline(stream, state, footnoteLink);
58
- } else if (stream.match(hrRE, true)) {
59
- return hr;
60
- } else if (match = stream.match(ulRE, true) || stream.match(olRE, true)) {
56
+ }
57
+ if (hrRE.test(stream.peek())) {
58
+ var re = new RegExp('(?:\s*['+stream.peek()+']){3,}$');
59
+ if (stream.match(re, true)) {
60
+ return hr;
61
+ }
62
+ }
63
+
64
+ var match;
65
+ if (match = stream.match(ulRE, true) || stream.match(olRE, true)) {
61
66
  state.indentation += match[0].length;
62
67
  return list;
63
68
  }
@@ -77,15 +82,8 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
77
82
 
78
83
  // Inline
79
84
  function getType(state) {
80
- var styles = [];
81
-
82
- if (state.strong) { styles.push(state.em ? emstrong : strong); }
83
- else if (state.em) { styles.push(em); }
84
-
85
- if (state.header) { styles.push(header); }
86
- if (state.quote) { styles.push(quote); }
87
-
88
- return styles.length ? styles.join(' ') : null;
85
+ return state.strong ? (state.em ? emstrong : strong)
86
+ : (state.em ? em : null);
89
87
  }
90
88
 
91
89
  function handleText(stream, state) {
@@ -194,9 +192,7 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
194
192
  inline: inlineNormal,
195
193
  text: handleText,
196
194
  em: false,
197
- strong: false,
198
- header: false,
199
- quote: false
195
+ strong: false
200
196
  };
201
197
  },
202
198
 
@@ -211,35 +207,36 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
211
207
  inline: s.inline,
212
208
  text: s.text,
213
209
  em: s.em,
214
- strong: s.strong,
215
- header: s.header,
216
- quote: s.quote
210
+ strong: s.strong
217
211
  };
218
212
  },
219
213
 
220
214
  token: function(stream, state) {
221
215
  if (stream.sol()) {
222
- if (stream.match(/^\s*$/, true)) { return blankLine(state); }
223
-
224
- // Reset state.header
225
- state.header = false;
226
- // Reset state.quote
227
- state.quote = false;
228
-
229
216
  state.f = state.block;
230
- var indentation = stream.match(/^\s*/, true)[0].replace(/\t/g, ' ').length;
231
- state.indentationDiff = indentation - state.indentation;
232
- state.indentation = indentation;
233
- if (indentation > 0) { return null; }
217
+ var previousIndentation = state.indentation
218
+ , currentIndentation = 0;
219
+ while (previousIndentation > 0) {
220
+ if (stream.eat(' ')) {
221
+ previousIndentation--;
222
+ currentIndentation++;
223
+ } else if (previousIndentation >= 4 && stream.eat('\t')) {
224
+ previousIndentation -= 4;
225
+ currentIndentation += 4;
226
+ } else {
227
+ break;
228
+ }
229
+ }
230
+ state.indentation = currentIndentation;
231
+
232
+ if (currentIndentation > 0) return null;
234
233
  }
235
234
  return state.f(stream, state);
236
235
  },
237
236
 
238
- blankLine: blankLine,
239
-
240
237
  getType: getType
241
238
  };
242
239
 
243
- }, "xml");
240
+ });
244
241
 
245
242
  CodeMirror.defineMIME("text/x-markdown", "markdown");
@@ -7,9 +7,11 @@ CodeMirror.defineMode("pascal", function(config) {
7
7
  var keywords = words("and array begin case const div do downto else end file for forward integer " +
8
8
  "boolean char function goto if in label mod nil not of or packed procedure " +
9
9
  "program record repeat set string then to type until var while with");
10
+ var blockKeywords = words("case do else for if switch while struct then of");
10
11
  var atoms = {"null": true};
11
12
 
12
13
  var isOperatorChar = /[+\-*&%=<>!?|\/]/;
14
+ var curPunc;
13
15
 
14
16
  function tokenBase(stream, state) {
15
17
  var ch = stream.next();
@@ -26,6 +28,7 @@ CodeMirror.defineMode("pascal", function(config) {
26
28
  return tokenComment(stream, state);
27
29
  }
28
30
  if (/[\[\]{}\(\),;\:\.]/.test(ch)) {
31
+ curPunc = ch;
29
32
  return null
30
33
  }
31
34
  if (/\d/.test(ch)) {
@@ -44,7 +47,10 @@ CodeMirror.defineMode("pascal", function(config) {
44
47
  }
45
48
  stream.eatWhile(/[\w\$_]/);
46
49
  var cur = stream.current();
47
- if (keywords.propertyIsEnumerable(cur)) return "keyword";
50
+ if (keywords.propertyIsEnumerable(cur)) {
51
+ if (blockKeywords.propertyIsEnumerable(cur)) curPunc = "newstatement";
52
+ return "keyword";
53
+ }
48
54
  if (atoms.propertyIsEnumerable(cur)) return "atom";
49
55
  return "word";
50
56
  }
@@ -73,17 +79,55 @@ CodeMirror.defineMode("pascal", function(config) {
73
79
  return "comment";
74
80
  }
75
81
 
82
+ function Context(indented, column, type, align, prev) {
83
+ this.indented = indented;
84
+ this.column = column;
85
+ this.type = type;
86
+ this.align = align;
87
+ this.prev = prev;
88
+ }
89
+ function pushContext(state, col, type) {
90
+ return state.context = new Context(state.indented, col, type, null, state.context);
91
+ }
92
+ function popContext(state) {
93
+ var t = state.context.type;
94
+ if (t == ")" || t == "]" )
95
+ state.indented = state.context.indented;
96
+ return state.context = state.context.prev;
97
+ }
98
+
76
99
  // Interface
77
100
 
78
101
  return {
79
102
  startState: function(basecolumn) {
80
- return {tokenize: null};
103
+ return {
104
+ tokenize: null,
105
+ context: new Context((basecolumn || 0) - config.indentUnit, 0, "top", false),
106
+ indented: 0,
107
+ startOfLine: true
108
+ };
81
109
  },
82
110
 
83
111
  token: function(stream, state) {
112
+ var ctx = state.context;
113
+ if (stream.sol()) {
114
+ if (ctx.align == null) ctx.align = false;
115
+ state.indented = stream.indentation();
116
+ state.startOfLine = true;
117
+ }
84
118
  if (stream.eatSpace()) return null;
119
+ curPunc = null;
85
120
  var style = (state.tokenize || tokenBase)(stream, state);
86
121
  if (style == "comment" || style == "meta") return style;
122
+ if (ctx.align == null) ctx.align = true;
123
+
124
+ if ((curPunc == ";" || curPunc == ":") && ctx.type == "statement") popContext(state);
125
+ else if (curPunc == "[") pushContext(state, stream.column(), "]");
126
+ else if (curPunc == "(") pushContext(state, stream.column(), ")");
127
+ else if (curPunc == ctx.type) popContext(state);
128
+ else if ( ctx.type == "top" || (ctx.type == "statement" && curPunc == "newstatement"))
129
+ pushContext(state, stream.column(), "statement");
130
+ state.startOfLine = false;
87
131
  return style;
88
132
  },
89
133
 
@@ -324,7 +324,7 @@ CodeMirror.defineMode("perl",function(config,parserConfig){
324
324
  hex :1, // - convert a string to a hexadecimal number
325
325
  'import' :1, // - patch a module's namespace into your own
326
326
  index :1, // - find a substring within a string
327
- 'int' :1, // - get the integer portion of a number
327
+ int :1, // - get the integer portion of a number
328
328
  ioctl :1, // - system-dependent device control system call
329
329
  'join' :1, // - join a list into a string using a separator
330
330
  keys :1, // - retrieve list of indices from a hash
@@ -13,12 +13,11 @@
13
13
  }
14
14
  var phpConfig = {
15
15
  name: "clike",
16
- keywords: keywords("abstract and array as break case catch class clone const continue declare default " +
17
- "do else elseif enddeclare endfor endforeach endif endswitch endwhile extends final " +
18
- "for foreach function global goto if implements interface instanceof namespace " +
19
- "new or private protected public static switch throw trait try use var while xor " +
20
- "die echo empty exit eval include include_once isset list require require_once return " +
21
- "print unset __halt_compiler self static parent"),
16
+ keywords: keywords("abstract and array as break case catch cfunction class clone const continue declare " +
17
+ "default do else elseif enddeclare endfor endforeach endif endswitch endwhile extends " +
18
+ "final for foreach function global goto if implements interface instanceof namespace " +
19
+ "new or private protected public static switch throw try use var while xor return" +
20
+ "die echo empty exit eval include include_once isset list require require_once print unset"),
22
21
  blockKeywords: keywords("catch do else elseif for foreach if switch try while"),
23
22
  atoms: keywords("true false null TRUE FALSE NULL"),
24
23
  multiLineStrings: true,
@@ -36,15 +35,8 @@
36
35
  return false;
37
36
  },
38
37
  "#": function(stream, state) {
39
- while (!stream.eol() && !stream.match("?>", false)) stream.next();
38
+ stream.skipToEnd();
40
39
  return "comment";
41
- },
42
- "/": function(stream, state) {
43
- if (stream.eat("/")) {
44
- while (!stream.eol() && !stream.match("?>", false)) stream.next();
45
- return "comment";
46
- }
47
- return false;
48
40
  }
49
41
  }
50
42
  };
@@ -56,57 +48,38 @@
56
48
  var phpMode = CodeMirror.getMode(config, phpConfig);
57
49
 
58
50
  function dispatch(stream, state) { // TODO open PHP inside text/css
59
- var isPHP = state.mode == "php";
60
- if (stream.sol() && state.pending != '"') state.pending = null;
61
51
  if (state.curMode == htmlMode) {
62
- if (stream.match(/^<\?\w*/)) {
52
+ var style = htmlMode.token(stream, state.curState);
53
+ if (style == "meta" && /^<\?/.test(stream.current())) {
63
54
  state.curMode = phpMode;
64
55
  state.curState = state.php;
65
- state.curClose = "?>";
66
- state.mode = "php";
67
- return "meta";
56
+ state.curClose = /^\?>/;
57
+ state.mode = 'php';
68
58
  }
69
- if (state.pending == '"') {
70
- while (!stream.eol() && stream.next() != '"') {}
71
- var style = "string";
72
- } else if (state.pending && stream.pos < state.pending.end) {
73
- stream.pos = state.pending.end;
74
- var style = state.pending.style;
75
- } else {
76
- var style = htmlMode.token(stream, state.curState);
77
- }
78
- state.pending = null;
79
- var cur = stream.current(), openPHP = cur.search(/<\?/);
80
- if (openPHP != -1) {
81
- if (style == "string" && /\"$/.test(cur) && !/\?>/.test(cur)) state.pending = '"';
82
- else state.pending = {end: stream.pos, style: style};
83
- stream.backUp(cur.length - openPHP);
84
- } else if (style == "tag" && stream.current() == ">" && state.curState.context) {
59
+ else if (style == "tag" && stream.current() == ">" && state.curState.context) {
85
60
  if (/^script$/i.test(state.curState.context.tagName)) {
86
61
  state.curMode = jsMode;
87
62
  state.curState = jsMode.startState(htmlMode.indent(state.curState, ""));
88
63
  state.curClose = /^<\/\s*script\s*>/i;
89
- state.mode = "javascript";
64
+ state.mode = 'javascript';
90
65
  }
91
66
  else if (/^style$/i.test(state.curState.context.tagName)) {
92
67
  state.curMode = cssMode;
93
68
  state.curState = cssMode.startState(htmlMode.indent(state.curState, ""));
94
- state.curClose = /^<\/\s*style\s*>/i;
95
- state.mode = "css";
69
+ state.curClose = /^<\/\s*style\s*>/i;
70
+ state.mode = 'css';
96
71
  }
97
72
  }
98
73
  return style;
99
- } else if ((!isPHP || state.php.tokenize == null) &&
100
- stream.match(state.curClose, isPHP)) {
74
+ }
75
+ else if (stream.match(state.curClose, false)) {
101
76
  state.curMode = htmlMode;
102
77
  state.curState = state.html;
103
78
  state.curClose = null;
104
- state.mode = "html";
105
- if (isPHP) return "meta";
106
- else return dispatch(stream, state);
107
- } else {
108
- return state.curMode.token(stream, state.curState);
79
+ state.mode = 'html';
80
+ return dispatch(stream, state);
109
81
  }
82
+ else return state.curMode.token(stream, state.curState);
110
83
  }
111
84
 
112
85
  return {
@@ -114,11 +87,10 @@
114
87
  var html = htmlMode.startState();
115
88
  return {html: html,
116
89
  php: phpMode.startState(),
117
- curMode: parserConfig.startOpen ? phpMode : htmlMode,
118
- curState: parserConfig.startOpen ? phpMode.startState() : html,
119
- curClose: parserConfig.startOpen ? /^\?>/ : null,
120
- mode: parserConfig.startOpen ? "php" : "html",
121
- pending: null}
90
+ curMode: parserConfig.startOpen ? phpMode : htmlMode,
91
+ curState: parserConfig.startOpen ? phpMode.startState() : html,
92
+ curClose: parserConfig.startOpen ? /^\?>/ : null,
93
+ mode: parserConfig.startOpen ? 'php' : 'html'}
122
94
  },
123
95
 
124
96
  copyState: function(state) {
@@ -128,8 +100,7 @@
128
100
  else if (state.curState == php) cur = phpNew;
129
101
  else cur = CodeMirror.copyState(state.curMode, state.curState);
130
102
  return {html: htmlNew, php: phpNew, curMode: state.curMode, curState: cur,
131
- curClose: state.curClose, mode: state.mode,
132
- pending: state.pending};
103
+ curClose: state.curClose, mode: state.mode};
133
104
  },
134
105
 
135
106
  token: dispatch,
@@ -143,7 +114,7 @@
143
114
 
144
115
  electricChars: "/{}:"
145
116
  }
146
- }, "xml", "clike", "javascript", "css");
117
+ });
147
118
  CodeMirror.defineMIME("application/x-httpd-php", "php");
148
119
  CodeMirror.defineMIME("application/x-httpd-php-open", {name: "php", startOpen: true});
149
120
  CodeMirror.defineMIME("text/x-php", phpConfig);
@@ -249,30 +249,32 @@ CodeMirror.defineMode("python", function(conf, parserConf) {
249
249
 
250
250
  // Handle '.' connected identifiers
251
251
  if (current === '.') {
252
- style = stream.match(identifiers, false) ? null : ERRORCLASS;
253
- if (style === null && state.lastToken === 'meta') {
254
- // Apply 'meta' style to '.' connected identifiers when
255
- // appropriate.
256
- style = 'meta';
252
+ style = state.tokenize(stream, state);
253
+ current = stream.current();
254
+ if (style === 'variable' || style === 'builtin') {
255
+ return 'variable';
256
+ } else {
257
+ return ERRORCLASS;
257
258
  }
258
- return style;
259
259
  }
260
260
 
261
261
  // Handle decorators
262
262
  if (current === '@') {
263
- return stream.match(identifiers, false) ? 'meta' : ERRORCLASS;
264
- }
265
-
266
- if ((style === 'variable' || style === 'builtin')
267
- && state.lastToken === 'meta') {
268
- style = 'meta';
263
+ style = state.tokenize(stream, state);
264
+ current = stream.current();
265
+ if (style === 'variable'
266
+ || current === '@staticmethod'
267
+ || current === '@classmethod') {
268
+ return 'meta';
269
+ } else {
270
+ return ERRORCLASS;
271
+ }
269
272
  }
270
273
 
271
274
  // Handle scope changes.
272
275
  if (current === 'pass' || current === 'return') {
273
276
  state.dedent += 1;
274
277
  }
275
- if (current === 'lambda') state.lambda = true;
276
278
  if ((current === ':' && !state.lambda && state.scopes[0].type == 'py')
277
279
  || indentInfo === 'indent') {
278
280
  indent(stream, state);
@@ -314,7 +316,7 @@ CodeMirror.defineMode("python", function(conf, parserConf) {
314
316
  token: function(stream, state) {
315
317
  var style = tokenLexer(stream, state);
316
318
 
317
- state.lastToken = style;
319
+ state.lastToken = {style:style, content: stream.current()};
318
320
 
319
321
  if (stream.eol() && stream.lambda) {
320
322
  state.lambda = false;
@@ -14,7 +14,7 @@ CodeMirror.defineMode("spec", function(config, modeConfig) {
14
14
  return {
15
15
  controlFlow: false,
16
16
  macroParameters: false,
17
- section: false
17
+ section: false,
18
18
  };
19
19
  },
20
20
  token: function (stream, state) {