mumuki-laboratory 6.7.2 → 6.7.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1245fecef79f70f30cef408fd0791c6533b8ca6275de62f87a4b80143eca8ea1
4
- data.tar.gz: 5a582f5dcf4589376b68fab271f868be8bd462b8eba6ae816c5953468b70d2b4
3
+ metadata.gz: 1636741b645cb8e5066f55dc71ecae6397059a70cf98d63091e4b04d17d1f1c2
4
+ data.tar.gz: 4b94d32166df801a5eff64a4f6c3d4586a030086d9b49bfa6be99e62142b4fb0
5
5
  SHA512:
6
- metadata.gz: 301fb226da9efb70e86e5387d2e73414fe9db74b294238a597f0ce84820894c28dd54733151836a16d25fc71f87bd53d112460f49e45123d26d152060a059e57
7
- data.tar.gz: e0fc7c0dc9fa2634cf0364c87ccfc3d2ce647a5eec22ca33d31919f34d5240e8ec8037ab958d3072d771497fb1d88f3287cafa91cbae4ae0252694584aa2cf02
6
+ metadata.gz: 683108fa3fead68c272baa45afe07ac80baeaabe9c763f74beb41e19a3fbf662e7e3d0aa8f784ff40e1513227d684176b07088a525a3a2d2068b27317d5a2904
7
+ data.tar.gz: f38177eb7ba4f2509262c0cdc2e578579ffd691a99c3574964dfa03b21c39dcf98979f86318d8f9a84934774dd11361659290a72cec258e26cecc889b2093bee
@@ -23,6 +23,7 @@
23
23
  //= require jquery-console
24
24
 
25
25
  //= require codemirror.min
26
+ //= require codemirror-simple-mode.js
26
27
  //= require codemirror-autorefresh
27
28
  //= require codemirror-modes
28
29
  //= require analytics
@@ -71,8 +71,6 @@ var mumuki = mumuki || {};
71
71
 
72
72
 
73
73
  mumuki.load(function () {
74
- CodeMirror.currentLocale = mumuki.locale;
75
-
76
74
  mumuki.page.editors = createCodeMirrors();
77
75
  updateCodeMirrorLanguage();
78
76
  onSelectUpdateCodeMirror();
@@ -2,7 +2,7 @@ module OpenGraphHelper
2
2
  def open_graph_tags(subject)
3
3
  %Q{
4
4
  <meta property="og:site_name" content="#{Organization.current.site_name}" />
5
- <meta property="og:title" content="#{page_title subject}"/>
5
+ <meta property="og:title" content="#{h page_title(subject)}"/>
6
6
  <meta property="og:description" content="#{Organization.current.central? ? t(:mumuki_short_description) : Organization.current.description}"/>
7
7
  <meta property="og:type" content="website"/>
8
8
  <meta property="og:image" content="#{Organization.current.open_graph_image_url}"/>
@@ -1,5 +1,5 @@
1
1
  module Mumuki
2
2
  module Laboratory
3
- VERSION = '6.7.2'
3
+ VERSION = '6.7.3'
4
4
  end
5
5
  end
@@ -1,1059 +1,71 @@
1
- // Parts from Ace; see <https://raw.githubusercontent.com/ajaxorg/ace/master/LICENSE>
2
- CodeMirror.defineMode("gobstones", function(cmCfg, modeCfg) {
3
-
4
- // Fake define() function.
5
- var moduleHolder = Object.create(null);
6
-
7
- // Given a module path as a string, create the canonical version
8
- // (no leading ./, no ending .js).
9
- var canonicalPath = function(path) {
10
- return path.replace(/\.\//, '').replace(/\.js$/, '');
1
+ // https://codemirror.net/demo/simplemode.html
2
+
3
+ (function() {
4
+ var locale = document.querySelector("html").lang || 'es';
5
+
6
+ var keywords = [
7
+ "program", "procedure", "function", "interactive", "if",
8
+ "then", "else", "switch", "repeat", "while",
9
+ "foreach", "in", "not", "div", "mod",
10
+ "Skip", "return"
11
+ ];
12
+
13
+ var atoms = {
14
+ es: ["Verde", "Rojo", "Azul", "Negro", "Norte", "Sur", "Este", "Oeste", "False", "True"],
15
+ pt: ["Verde", "Vermelho", "Azul", "Preto", "Norte", "Sul", "Leste", "Oeste", "False", "True"],
16
+ en: ["Green", "Red", "Blue", "Black", "North", "South", "East", "West", "False", "True"]
11
17
  };
12
18
 
13
- // We intentionally add the `path` argument to `define()`.
14
- var define = function(path, init) {
15
- var exports = Object.create(null);
16
- init(require, exports); // module (3rd parameter) isn't supported.
17
- moduleHolder[canonicalPath(path)] = exports;
19
+ var builtins = {
20
+ es: ["Poner", "Sacar", "Mover", "IrAlBorde", "VaciarTablero", "nroBolitas", "hayBolitas", "puedeMover", "siguiente", "previo", "opuesto", "minBool", "maxBool", "minDir", "maxDir", "minColor", "maxColor"],
21
+ pt: ["Colocar", "Retirar", "Mover", "IrAlBorda", "VaciarTablero", "nroPedras", "haPedras", "podeMover", "seguinte", "previo", "oposto", "minBool", "maxBool", "minDir", "maxDir", "minCor", "maxCor"],
22
+ en: ["Put", "Grab", "Move", "GoToEdge", "EmptyBoardContents", "numStones", "anyStones", "canMove", "next", "prev", "opposite", "minBool", "maxBool", "minDir", "maxDir", "minColor", "maxColor"]
18
23
  };
19
24
 
20
- // path: string of the location of the JS file.
21
- var require = function(path) { return moduleHolder[canonicalPath(path)]; };
22
-
23
- // All dependencies here.
24
- define("../lib/oop.js", function(require, exports, module) {
25
- "use strict";
26
-
27
- exports.inherits = function(ctor, superCtor) {
28
- ctor.super_ = superCtor;
29
- ctor.prototype = Object.create(superCtor.prototype, {
30
- constructor: {
31
- value: ctor,
32
- enumerable: false,
33
- writable: true,
34
- configurable: true
35
- }
36
- });
37
- };
38
-
39
- exports.mixin = function(obj, mixin) {
40
- for (var key in mixin) {
41
- obj[key] = mixin[key];
42
- }
43
- return obj;
44
- };
45
-
46
- exports.implement = function(proto, mixin) {
47
- exports.mixin(proto, mixin);
48
- };
49
-
50
- });
51
-
52
-
53
- define("../lib/lang.js", function(require, exports, module) {
54
- "use strict";
55
-
56
- exports.last = function(a) {
57
- return a[a.length - 1];
58
- };
59
-
60
- exports.stringReverse = function(string) {
61
- return string.split("").reverse().join("");
62
- };
63
-
64
- exports.stringRepeat = function (string, count) {
65
- var result = '';
66
- while (count > 0) {
67
- if (count & 1)
68
- result += string;
69
-
70
- if (count >>= 1)
71
- string += string;
72
- }
73
- return result;
74
- };
75
-
76
- var trimBeginRegexp = /^\s\s*/;
77
- var trimEndRegexp = /\s\s*$/;
78
-
79
- exports.stringTrimLeft = function (string) {
80
- return string.replace(trimBeginRegexp, '');
81
- };
82
-
83
- exports.stringTrimRight = function (string) {
84
- return string.replace(trimEndRegexp, '');
85
- };
86
-
87
- exports.copyObject = function(obj) {
88
- var copy = {};
89
- for (var key in obj) {
90
- copy[key] = obj[key];
91
- }
92
- return copy;
93
- };
94
-
95
- exports.copyArray = function(array){
96
- var copy = [];
97
- for (var i=0, l=array.length; i<l; i++) {
98
- if (array[i] && typeof array[i] == "object")
99
- copy[i] = this.copyObject(array[i]);
100
- else
101
- copy[i] = array[i];
102
- }
103
- return copy;
104
- };
105
-
106
- exports.deepCopy = function deepCopy(obj) {
107
- if (typeof obj !== "object" || !obj)
108
- return obj;
109
- var copy;
110
- if (Array.isArray(obj)) {
111
- copy = [];
112
- for (var key = 0; key < obj.length; key++) {
113
- copy[key] = deepCopy(obj[key]);
114
- }
115
- return copy;
116
- }
117
- if (Object.prototype.toString.call(obj) !== "[object Object]")
118
- return obj;
119
-
120
- copy = {};
121
- for (var key in obj)
122
- copy[key] = deepCopy(obj[key]);
123
- return copy;
124
- };
125
-
126
- exports.arrayToMap = function(arr) {
127
- var map = {};
128
- for (var i=0; i<arr.length; i++) {
129
- map[arr[i]] = 1;
130
- }
131
- return map;
132
-
133
- };
134
-
135
- exports.createMap = function(props) {
136
- var map = Object.create(null);
137
- for (var i in props) {
138
- map[i] = props[i];
139
- }
140
- return map;
141
- };
142
-
143
- /*
144
- * splice out of 'array' anything that === 'value'
145
- */
146
- exports.arrayRemove = function(array, value) {
147
- for (var i = 0; i <= array.length; i++) {
148
- if (value === array[i]) {
149
- array.splice(i, 1);
150
- }
151
- }
152
- };
153
-
154
- exports.escapeRegExp = function(str) {
155
- return str.replace(/([.*+?^${}()|[\]\/\\])/g, '\\$1');
156
- };
157
-
158
- exports.escapeHTML = function(str) {
159
- return str.replace(/&/g, "&#38;").replace(/"/g, "&#34;").replace(/'/g, "&#39;").replace(/</g, "&#60;");
160
- };
161
-
162
- exports.getMatchOffsets = function(string, regExp) {
163
- var matches = [];
164
-
165
- string.replace(regExp, function(str) {
166
- matches.push({
167
- offset: arguments[arguments.length-2],
168
- length: str.length
169
- });
170
- });
171
-
172
- return matches;
173
- };
174
-
175
- /* deprecated */
176
- exports.deferredCall = function(fcn) {
177
- var timer = null;
178
- var callback = function() {
179
- timer = null;
180
- fcn();
181
- };
182
-
183
- var deferred = function(timeout) {
184
- deferred.cancel();
185
- timer = setTimeout(callback, timeout || 0);
186
- return deferred;
187
- };
188
-
189
- deferred.schedule = deferred;
190
-
191
- deferred.call = function() {
192
- this.cancel();
193
- fcn();
194
- return deferred;
195
- };
196
-
197
- deferred.cancel = function() {
198
- clearTimeout(timer);
199
- timer = null;
200
- return deferred;
201
- };
202
-
203
- deferred.isPending = function() {
204
- return timer;
205
- };
206
-
207
- return deferred;
208
- };
209
-
210
-
211
- exports.delayedCall = function(fcn, defaultTimeout) {
212
- var timer = null;
213
- var callback = function() {
214
- timer = null;
215
- fcn();
216
- };
217
-
218
- var _self = function(timeout) {
219
- if (timer == null)
220
- timer = setTimeout(callback, timeout || defaultTimeout);
221
- };
222
-
223
- _self.delay = function(timeout) {
224
- timer && clearTimeout(timer);
225
- timer = setTimeout(callback, timeout || defaultTimeout);
226
- };
227
- _self.schedule = _self;
228
-
229
- _self.call = function() {
230
- this.cancel();
231
- fcn();
232
- };
233
-
234
- _self.cancel = function() {
235
- timer && clearTimeout(timer);
236
- timer = null;
237
- };
238
-
239
- _self.isPending = function() {
240
- return timer;
241
- };
242
-
243
- return _self;
244
- };
245
- });
246
-
247
-
248
- define("./text_highlight_rules.js", function(require, exports, module) {
249
- "use strict";
250
-
251
- var lang = require("../lib/lang");
252
-
253
- var TextHighlightRules = function() {
254
-
255
- // regexp must not have capturing parentheses
256
- // regexps are ordered -> the first match is used
257
-
258
- this.$rules = {
259
- "start" : [{
260
- token : "empty_line",
261
- regex : '^$'
262
- }, {
263
- defaultToken : "text"
264
- }]
265
- };
266
- };
267
-
268
- (function() {
269
-
270
- this.addRules = function(rules, prefix) {
271
- if (!prefix) {
272
- for (var key in rules)
273
- this.$rules[key] = rules[key];
274
- return;
275
- }
276
- for (var key in rules) {
277
- var state = rules[key];
278
- for (var i = 0; i < state.length; i++) {
279
- var rule = state[i];
280
- if (rule.next || rule.onMatch) {
281
- if (typeof rule.next == "string") {
282
- if (rule.next.indexOf(prefix) !== 0)
283
- rule.next = prefix + rule.next;
284
- }
285
- if (rule.nextState && rule.nextState.indexOf(prefix) !== 0)
286
- rule.nextState = prefix + rule.nextState;
287
- }
288
- }
289
- this.$rules[prefix + key] = state;
290
- }
291
- };
292
-
293
- this.getRules = function() {
294
- return this.$rules;
295
- };
296
-
297
- this.embedRules = function (HighlightRules, prefix, escapeRules, states, append) {
298
- var embedRules = typeof HighlightRules == "function"
299
- ? new HighlightRules().getRules()
300
- : HighlightRules;
301
- if (states) {
302
- for (var i = 0; i < states.length; i++)
303
- states[i] = prefix + states[i];
304
- } else {
305
- states = [];
306
- for (var key in embedRules)
307
- states.push(prefix + key);
308
- }
309
-
310
- this.addRules(embedRules, prefix);
311
-
312
- if (escapeRules) {
313
- var addRules = Array.prototype[append ? "push" : "unshift"];
314
- for (var i = 0; i < states.length; i++)
315
- addRules.apply(this.$rules[states[i]], lang.deepCopy(escapeRules));
316
- }
317
-
318
- if (!this.$embeds)
319
- this.$embeds = [];
320
- this.$embeds.push(prefix);
321
- };
322
-
323
- this.getEmbeds = function() {
324
- return this.$embeds;
325
- };
326
-
327
- var pushState = function(currentState, stack) {
328
- if (currentState != "start" || stack.length)
329
- stack.unshift(this.nextState, currentState);
330
- return this.nextState;
331
- };
332
- var popState = function(currentState, stack) {
333
- // if (stack[0] === currentState)
334
- stack.shift();
335
- return stack.shift() || "start";
336
- };
337
-
338
- this.normalizeRules = function() {
339
- var id = 0;
340
- var rules = this.$rules;
341
- function processState(key) {
342
- var state = rules[key];
343
- state.processed = true;
344
- for (var i = 0; i < state.length; i++) {
345
- var rule = state[i];
346
- var toInsert = null;
347
- if (Array.isArray(rule)) {
348
- toInsert = rule;
349
- rule = {};
350
- }
351
- if (!rule.regex && rule.start) {
352
- rule.regex = rule.start;
353
- if (!rule.next)
354
- rule.next = [];
355
- rule.next.push({
356
- defaultToken: rule.token
357
- }, {
358
- token: rule.token + ".end",
359
- regex: rule.end || rule.start,
360
- next: "pop"
361
- });
362
- rule.token = rule.token + ".start";
363
- rule.push = true;
364
- }
365
- var next = rule.next || rule.push;
366
- if (next && Array.isArray(next)) {
367
- var stateName = rule.stateName;
368
- if (!stateName) {
369
- stateName = rule.token;
370
- if (typeof stateName != "string")
371
- stateName = stateName[0] || "";
372
- if (rules[stateName])
373
- stateName += id++;
374
- }
375
- rules[stateName] = next;
376
- rule.next = stateName;
377
- processState(stateName);
378
- } else if (next == "pop") {
379
- rule.next = popState;
380
- }
381
-
382
- if (rule.push) {
383
- rule.nextState = rule.next || rule.push;
384
- rule.next = pushState;
385
- delete rule.push;
386
- }
387
-
388
- if (rule.rules) {
389
- for (var r in rule.rules) {
390
- if (rules[r]) {
391
- if (rules[r].push)
392
- rules[r].push.apply(rules[r], rule.rules[r]);
393
- } else {
394
- rules[r] = rule.rules[r];
395
- }
396
- }
397
- }
398
- var includeName = typeof rule == "string" ? rule : rule.include;
399
- if (includeName) {
400
- if (Array.isArray(includeName))
401
- toInsert = includeName.map(function(x) { return rules[x]; });
402
- else
403
- toInsert = rules[includeName];
404
- }
405
-
406
- if (toInsert) {
407
- var args = [i, 1].concat(toInsert);
408
- if (rule.noEscape)
409
- args = args.filter(function(x) {return !x.next;});
410
- state.splice.apply(state, args);
411
- // skip included rules since they are already processed
412
- //i += args.length - 3;
413
- i--;
414
- }
415
-
416
- if (rule.keywordMap) {
417
- rule.token = this.createKeywordMapper(
418
- rule.keywordMap, rule.defaultToken || "text", rule.caseInsensitive
419
- );
420
- delete rule.defaultToken;
421
- }
422
- }
423
- }
424
- Object.keys(rules).forEach(processState, this);
425
- };
426
-
427
- this.createKeywordMapper = function(map, defaultToken, ignoreCase, splitChar) {
428
- var keywords = Object.create(null);
429
- Object.keys(map).forEach(function(className) {
430
- var a = map[className];
431
- if (ignoreCase)
432
- a = a.toLowerCase();
433
- var list = a.split(splitChar || "|");
434
- for (var i = list.length; i--; )
435
- keywords[list[i]] = className;
436
- });
437
- // in old versions of opera keywords["__proto__"] sets prototype
438
- // even on objects with __proto__=null
439
- if (Object.getPrototypeOf(keywords)) {
440
- keywords.__proto__ = null;
441
- }
442
- this.$keywordList = Object.keys(keywords);
443
- map = null;
444
- return ignoreCase
445
- ? function(value) {return keywords[value.toLowerCase()] || defaultToken; }
446
- : function(value) {return keywords[value] || defaultToken; };
447
- };
448
-
449
- this.getKeywords = function() {
450
- return this.$keywords;
451
- };
452
-
453
- }).call(TextHighlightRules.prototype);
454
-
455
- exports.TextHighlightRules = TextHighlightRules;
456
- });
457
-
458
-
459
- define("./doc_comment_highlight_rules.js", function(require, exports, module) {
460
- "use strict";
461
-
462
- var oop = require("../lib/oop");
463
- var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules;
464
-
465
- var DocCommentHighlightRules = function() {
466
- this.$rules = {
467
- "start" : [ {
468
- token : "comment.doc.tag",
469
- regex : "@[\\w\\d_]+" // TODO: fix email addresses
470
- },
471
- DocCommentHighlightRules.getTagRule(),
472
- {
473
- defaultToken : "comment.doc",
474
- caseInsensitive: true
475
- }]
476
- };
477
- };
478
-
479
- oop.inherits(DocCommentHighlightRules, TextHighlightRules);
480
-
481
- DocCommentHighlightRules.getTagRule = function(start) {
482
- return {
483
- token : "comment.doc.tag.storage.type",
484
- regex : "\\b(?:TODO|FIXME|XXX|HACK)\\b"
485
- };
486
- };
487
-
488
- DocCommentHighlightRules.getStartRule = function(start) {
489
- return {
490
- token : "comment.doc", // doc comment
491
- regex : "\\/\\*(?=\\*)",
492
- next : start
493
- };
494
- };
495
-
496
- DocCommentHighlightRules.getEndRule = function (start) {
497
- return {
498
- token : "comment.doc", // closing comment
499
- regex : "\\*\\/",
500
- next : start
501
- };
502
- };
503
-
504
-
505
- exports.DocCommentHighlightRules = DocCommentHighlightRules;
506
-
507
- });
508
-
25
+ const localizedKeywordsAndBuiltins = keywords.concat(builtins[locale]);
26
+ const localizedAtoms = atoms[locale];
509
27
 
510
- define("gobstones_highlight_rules", function(require, exports, module) {
511
- "use strict";
512
-
513
- var oop = require("../lib/oop");
514
- var DocCommentHighlightRules = require("./doc_comment_highlight_rules").DocCommentHighlightRules;
515
- var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules;
516
-
517
- var GobstonesHighlightRules = function() {
518
-
519
- var buildList = function(values) {
520
- return values.join('|');
521
- };
522
-
523
- var keywords = (
524
- "program|procedure|function|interactive|if|then|else|switch|repeat|while|foreach|in|not|div|mod|Skip|return"
525
- );
526
-
527
- var allBuiltinConstants = {
528
- es: ["Verde", "Rojo", "Azul", "Negro", "Norte", "Sur", "Este", "Oeste", "False", "True"],
529
- pt: ["Verde", "Vermelho", "Azul", "Preto", "Norte", "Sul", "Leste", "Oeste", "False", "True"],
530
- en: ["Green", "Red", "Blue", "Black", "North", "South", "East", "West", "False", "True"]
531
- };
532
-
533
- var allLangClasses = {
534
- es: ["Poner", "Sacar", "Mover", "IrAlBorde", "VaciarTablero", "nroBolitas", "hayBolitas", "puedeMover", "siguiente", "previo", "opuesto", "minBool", "maxBool", "minDir", "maxDir", "minColor", "maxColor"],
535
- pt: ["Colocar", "Retirar", "Mover", "IrAlBorda", "VaciarTablero", "nroPedras", "haPedras", "podeMover", "seguinte", "previo", "oposto", "minBool", "maxBool", "minDir", "maxDir", "minCor", "maxCor"],
536
- en: ["Put", "Grab", "Move", "GoToEdge", "EmptyBoardContents", "numStones", "anyStones", "canMove", "next", "prev", "opposite", "minBool", "maxBool", "minDir", "maxDir", "minColor", "maxColor"]
537
- };
538
-
539
- var locale = CodeMirror.currentLocale || 'es';
540
-
541
- registerAutocomplete('gobstones',
542
- keywords.split('|')
543
- .concat(allBuiltinConstants[locale])
544
- .concat(allLangClasses[locale])
545
- );
546
-
547
- var keywordMapper = this.createKeywordMapper({
548
- "keyword": keywords,
549
- "constant.language": buildList(allBuiltinConstants[locale]),
550
- "support.function": buildList(allLangClasses[locale]),
551
- "support.type": ''
552
- }, "identifier");
553
-
554
- // regexp must not have capturing parentheses. Use (?:) instead.
555
- // regexps are ordered -> the first match is used
556
-
557
- this.$rules = {
558
- "start" : [
559
- {
560
- token : "comment",
561
- regex : "\\/\\/.*$"
562
- },
563
- {
564
- token : "comment",
565
- regex : "\\-\\-.*$"
566
- },
567
- {
568
- token : "comment",
569
- regex : "#.*$"
570
- },
571
- DocCommentHighlightRules.getStartRule("doc-start"),
572
- {
573
- token : "comment", // multi line comment
574
- regex : "\\/\\*",
575
- next : "comment"
576
- }, {
577
-
578
- token : "string", // single line
579
- regex : '["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'
580
- }, {
581
- token : "string", // single line
582
- regex : "['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"
583
- }, {
584
- token : "constant.numeric", // hex
585
- regex : /0(?:[xX][0-9a-fA-F][0-9a-fA-F_]*|[bB][01][01_]*)[LlSsDdFfYy]?\b/
586
- }, {
587
- token : "constant.numeric", // float
588
- regex : /[+-]?\d[\d_]*(?:(?:\.[\d_]*)?(?:[eE][+-]?[\d_]+)?)?[LlSsDdFfYy]?\b/
589
- }, {
590
- token : "constant.language.boolean",
591
- regex : "(?:True|False)\\b"
592
- }, {
593
- token : "keyword.operator",
594
- regex : ":=|\\.\\.|,|;|\\|\\||\\/\\/|\\+|\\-|\\^|\\*|>|<|>=|=>|==|&&"
595
- }, {
596
- token : keywordMapper,
597
- // TODO: Unicode escape sequences
598
- // TODO: Unicode identifiers
599
- regex : "[a-zA-Z_$][a-zA-Z0-9_$]*\\b"
600
- }, {
601
- token : "lparen",
602
- regex : "[[({]"
603
- }, {
604
- token : "rparen",
605
- regex : "[\\])}]"
606
- }, {
607
- token : "text",
608
- regex : "\\s+"
609
- }
610
- ],
611
- "comment" : [
612
- {
613
- token : "comment", // closing comment
614
- regex : "\\*\\/",
615
- next : "start"
616
- }, {
617
- defaultToken : "comment"
618
- }
619
- ]
620
- };
621
-
622
- this.embedRules(DocCommentHighlightRules, "doc-",
623
- [ DocCommentHighlightRules.getEndRule("start") ]);
624
- };
625
-
626
- oop.inherits(GobstonesHighlightRules, TextHighlightRules);
627
-
628
- exports.GobstonesHighlightRules = GobstonesHighlightRules;
629
- });
630
-
631
-
632
-
633
- // Ace highlight rules function imported below.
634
- var HighlightRules = require("gobstones_highlight_rules").GobstonesHighlightRules;
635
-
636
-
637
-
638
- // Ace's Syntax Tokenizer.
639
-
640
- // tokenizing lines longer than this makes editor very slow
641
- var MAX_TOKEN_COUNT = 1000;
642
- var Tokenizer = function(rules) {
643
- this.states = rules;
644
-
645
- this.regExps = {};
646
- this.matchMappings = {};
647
- for (var key in this.states) {
648
- var state = this.states[key];
649
- var ruleRegExps = [];
650
- var matchTotal = 0;
651
- var mapping = this.matchMappings[key] = {defaultToken: "text"};
652
- var flag = "g";
653
-
654
- var splitterRurles = [];
655
- for (var i = 0; i < state.length; i++) {
656
- var rule = state[i];
657
- if (rule.defaultToken)
658
- mapping.defaultToken = rule.defaultToken;
659
- if (rule.caseInsensitive)
660
- flag = "gi";
661
- if (rule.regex == null)
662
- continue;
663
-
664
- if (rule.regex instanceof RegExp)
665
- rule.regex = rule.regex.toString().slice(1, -1);
666
-
667
- // Count number of matching groups. 2 extra groups from the full match
668
- // And the catch-all on the end (used to force a match);
669
- var adjustedregex = rule.regex;
670
- var matchcount = new RegExp("(?:(" + adjustedregex + ")|(.))").exec("a").length - 2;
671
- if (Array.isArray(rule.token)) {
672
- if (rule.token.length == 1 || matchcount == 1) {
673
- rule.token = rule.token[0];
674
- } else if (matchcount - 1 != rule.token.length) {
675
- throw new Error("number of classes and regexp groups in '" +
676
- rule.token + "'\n'" + rule.regex + "' doesn't match\n"
677
- + (matchcount - 1) + "!=" + rule.token.length);
678
- } else {
679
- rule.tokenArray = rule.token;
680
- rule.token = null;
681
- rule.onMatch = this.$arrayTokens;
682
- }
683
- } else if (typeof rule.token == "function" && !rule.onMatch) {
684
- if (matchcount > 1)
685
- rule.onMatch = this.$applyToken;
686
- else
687
- rule.onMatch = rule.token;
688
- }
689
-
690
- if (matchcount > 1) {
691
- if (/\\\d/.test(rule.regex)) {
692
- // Replace any backreferences and offset appropriately.
693
- adjustedregex = rule.regex.replace(/\\([0-9]+)/g, function(match, digit) {
694
- return "\\" + (parseInt(digit, 10) + matchTotal + 1);
695
- });
696
- } else {
697
- matchcount = 1;
698
- adjustedregex = this.removeCapturingGroups(rule.regex);
699
- }
700
- if (!rule.splitRegex && typeof rule.token != "string")
701
- splitterRurles.push(rule); // flag will be known only at the very end
702
- }
703
-
704
- mapping[matchTotal] = i;
705
- matchTotal += matchcount;
706
-
707
- ruleRegExps.push(adjustedregex);
708
-
709
- // makes property access faster
710
- if (!rule.onMatch)
711
- rule.onMatch = null;
712
- }
713
-
714
- splitterRurles.forEach(function(rule) {
715
- rule.splitRegex = this.createSplitterRegexp(rule.regex, flag);
716
- }, this);
717
-
718
- this.regExps[key] = new RegExp("(" + ruleRegExps.join(")|(") + ")|($)", flag);
719
- }
28
+ var buildList = function(values) {
29
+ return values.join('|');
720
30
  };
721
31
 
722
- (function() {
723
- this.$setMaxTokenCount = function(m) {
724
- MAX_TOKEN_COUNT = m | 0;
725
- };
726
-
727
- this.$applyToken = function(str) {
728
- var values = this.splitRegex.exec(str).slice(1);
729
- var types = this.token.apply(this, values);
730
-
731
- // required for compatibility with old modes
732
- if (typeof types === "string")
733
- return [{type: types, value: str}];
734
-
735
- var tokens = [];
736
- for (var i = 0, l = types.length; i < l; i++) {
737
- if (values[i])
738
- tokens[tokens.length] = {
739
- type: types[i],
740
- value: values[i]
741
- };
742
- }
743
- return tokens;
744
- },
745
-
746
- this.$arrayTokens = function(str) {
747
- if (!str)
748
- return [];
749
- var values = this.splitRegex.exec(str);
750
- if (!values)
751
- return "text";
752
- var tokens = [];
753
- var types = this.tokenArray;
754
- for (var i = 0, l = types.length; i < l; i++) {
755
- if (values[i + 1])
756
- tokens[tokens.length] = {
757
- type: types[i],
758
- value: values[i + 1]
759
- };
760
- }
761
- return tokens;
762
- };
763
-
764
- this.removeCapturingGroups = function(src) {
765
- var r = src.replace(
766
- /\[(?:\\.|[^\]])*?\]|\\.|\(\?[:=!]|(\()/g,
767
- function(x, y) {return y ? "(?:" : x;}
768
- );
769
- return r;
770
- };
771
-
772
- this.createSplitterRegexp = function(src, flag) {
773
- if (src.indexOf("(?=") != -1) {
774
- var stack = 0;
775
- var inChClass = false;
776
- var lastCapture = {};
777
- src.replace(/(\\.)|(\((?:\?[=!])?)|(\))|([\[\]])/g, function(
778
- m, esc, parenOpen, parenClose, square, index
779
- ) {
780
- if (inChClass) {
781
- inChClass = square != "]";
782
- } else if (square) {
783
- inChClass = true;
784
- } else if (parenClose) {
785
- if (stack == lastCapture.stack) {
786
- lastCapture.end = index+1;
787
- lastCapture.stack = -1;
788
- }
789
- stack--;
790
- } else if (parenOpen) {
791
- stack++;
792
- if (parenOpen.length != 1) {
793
- lastCapture.stack = stack
794
- lastCapture.start = index;
795
- }
796
- }
797
- return m;
798
- });
799
-
800
- if (lastCapture.end != null && /^\)*$/.test(src.substr(lastCapture.end)))
801
- src = src.substring(0, lastCapture.start) + src.substr(lastCapture.end);
802
- }
803
- return new RegExp(src, (flag||"").replace("g", ""));
804
- };
805
-
806
- /**
807
- * Returns an object containing two properties: `tokens`, which contains all the tokens; and `state`, the current state.
808
- * @returns {Object}
809
- **/
810
- this.getLineTokens = function(line, startState) {
811
- if (startState && typeof startState != "string") {
812
- var stack = startState.slice(0);
813
- startState = stack[0];
814
- } else
815
- var stack = [];
816
-
817
- var currentState = startState || "start";
818
- var state = this.states[currentState];
819
- if (!state) {
820
- currentState = "start";
821
- state = this.states[currentState];
822
- }
823
- var mapping = this.matchMappings[currentState];
824
- var re = this.regExps[currentState];
825
- re.lastIndex = 0;
826
-
827
- var match, tokens = [];
828
- var lastIndex = 0;
829
-
830
- var token = {type: null, value: ""};
831
-
832
- while (match = re.exec(line)) {
833
- var type = mapping.defaultToken;
834
- var rule = null;
835
- var value = match[0];
836
- var index = re.lastIndex;
837
-
838
- if (index - value.length > lastIndex) {
839
- var skipped = line.substring(lastIndex, index - value.length);
840
- if (token.type == type) {
841
- token.value += skipped;
842
- } else {
843
- if (token.type)
844
- tokens.push(token);
845
- token = {type: type, value: skipped};
846
- }
847
- }
848
-
849
- for (var i = 0; i < match.length-2; i++) {
850
- if (match[i + 1] === undefined)
851
- continue;
852
-
853
- rule = state[mapping[i]];
854
-
855
- if (rule.onMatch)
856
- type = rule.onMatch(value, currentState, stack);
857
- else
858
- type = rule.token;
859
-
860
- if (rule.next) {
861
- if (typeof rule.next == "string")
862
- currentState = rule.next;
863
- else
864
- currentState = rule.next(currentState, stack);
865
-
866
- state = this.states[currentState];
867
- if (!state) {
868
- window.console && console.error && console.error(currentState, "doesn't exist");
869
- currentState = "start";
870
- state = this.states[currentState];
871
- }
872
- mapping = this.matchMappings[currentState];
873
- lastIndex = index;
874
- re = this.regExps[currentState];
875
- re.lastIndex = index;
876
- }
877
- break;
878
- }
879
-
880
- if (value) {
881
- if (typeof type == "string") {
882
- if ((!rule || rule.merge !== false) && token.type === type) {
883
- token.value += value;
884
- } else {
885
- if (token.type)
886
- tokens.push(token);
887
- token = {type: type, value: value};
888
- }
889
- } else if (type) {
890
- if (token.type)
891
- tokens.push(token);
892
- token = {type: null, value: ""};
893
- for (var i = 0; i < type.length; i++)
894
- tokens.push(type[i]);
895
- }
896
- }
897
-
898
- if (lastIndex == line.length)
899
- break;
900
-
901
- lastIndex = index;
902
-
903
- if (tokens.length > MAX_TOKEN_COUNT) {
904
- // chrome doens't show contents of text nodes with very long text
905
- while (lastIndex < line.length) {
906
- if (token.type)
907
- tokens.push(token);
908
- token = {
909
- value: line.substring(lastIndex, lastIndex += 2000),
910
- type: "overflow"
911
- };
912
- }
913
- currentState = "start";
914
- stack = [];
915
- break;
916
- }
917
- }
918
-
919
- if (token.type)
920
- tokens.push(token);
921
-
922
- if (stack.length > 1) {
923
- if (stack[0] !== currentState)
924
- stack.unshift(currentState);
925
- }
926
- return {
927
- tokens : tokens,
928
- state : stack.length ? stack : currentState
929
- };
930
- };
931
-
932
- }).call(Tokenizer.prototype);
933
-
934
- // Token conversion.
935
- // See <https://github.com/ajaxorg/ace/wiki/Creating-or-Extending-an-Edit-Mode#common-tokens>
936
- // This is not an exact match nor the best match that can be made.
937
- var tokenFromAceToken = {
938
- empty: null,
939
- text: null,
940
-
941
- // Keyword
942
- keyword: 'keyword',
943
- control: 'keyword',
944
- operator: 'operator',
945
-
946
- // Constants
947
- constant: 'atom',
948
- numeric: 'number',
949
- character: 'atom',
950
- escape: 'atom',
951
-
952
- // Variables
953
- variable: 'variable',
954
- parameter: 'variable-3',
955
- language: 'variable-2', // Python's `self` uses that.
956
-
957
- // Comments
958
- comment: 'comment',
959
- line: 'comment',
960
- 'double-slash': 'comment',
961
- 'double-dash': 'comment',
962
- 'number-sign': 'comment',
963
- percentage: 'comment',
964
- block: 'comment',
965
- documentation: 'comment',
966
-
967
- // String
968
- string: 'string',
969
- quoted: 'string',
970
- single: 'string',
971
- double: 'string',
972
- triple: 'string',
973
- unquoted: 'string',
974
- interpolated: 'string',
975
- regexp: 'string-2',
976
-
977
- meta: 'meta',
978
- literal: 'qualifier',
979
- support: 'builtin',
980
-
981
- // Markup
982
- markup: 'tag',
983
- underline: 'link',
984
- link: 'link',
985
- bold: 'strong',
986
- heading: 'header',
987
- italic: 'em',
988
- list: 'variable-2',
989
- numbered: 'variable-2',
990
- unnumbered: 'variable-2',
991
- quote: 'quote',
992
- raw: 'variable-2', // Markdown's raw block uses that.
993
-
994
- // Invalid
995
- invalid: 'error',
996
- illegal: 'invalidchar',
997
- deprecated: 'error'
998
- };
999
-
1000
- // Takes a list of Ace tokens, returns a (string) CodeMirror token.
1001
- var cmTokenFromAceTokens = function(tokens) {
1002
- var token = null;
1003
- for (var i = 0; i < tokens.length; i++) {
1004
- // Find the most specific token.
1005
- if (tokenFromAceToken[tokens[i]] !== undefined) {
1006
- token = tokenFromAceToken[tokens[i]];
1007
- }
32
+ CodeMirror.defineSimpleMode("gobstones", {
33
+ // The start state contains the rules that are intially used
34
+ start: [
35
+ // The regex matches the token, the token property contains the type
36
+ {regex: /"(?:[^\\]|\\.)*?(?:"|$)/, token: "string"},
37
+ // You can match multiple tokens at once. Note that the captured
38
+ // groups must span the whole string in this case
39
+ {regex: /(function|procedure)(\s+)([a-zA-Z$][\w$]*)/, token: ["keyword", null, "variable-2"]},
40
+ // Rules are matched in the order in which they appear, so there is
41
+ // no ambiguity between this one and the one above
42
+ {regex: new RegExp(`(?:${buildList(localizedKeywordsAndBuiltins)})\\b`), token: "keyword"},
43
+ {regex: new RegExp(buildList(localizedAtoms)), token: "atom"},
44
+ {regex: /[-+]?(\d+)/i, token: "number"},
45
+ {regex: /\/\/.*/, token: "comment"},
46
+ {regex: /\/(?:[^\\]|\\.)*?\//, token: "variable-3"},
47
+ // A next property will cause the mode to move to a different state
48
+ {regex: /\/\*/, token: "comment", next: "comment"},
49
+ {regex: /(-|\+|\/|\*|\^|\|\||&&|:=|==|>=|<=|!=|<|>|!|div|mod)/, token: "operator"},
50
+ // indent and dedent properties guide autoindentation
51
+ {regex: /[\{\[\(]/, indent: true},
52
+ {regex: /[\}\]\)]/, dedent: true},
53
+ {regex: /[a-z]\w*/, token: "variable"}
54
+ ],
55
+ // The multi-line comment state.
56
+ comment: [
57
+ {regex: /.*?\*\//, token: "comment", next: "start"},
58
+ {regex: /.*/, token: "comment"}
59
+ ],
60
+ // The meta property contains global information about the mode. It
61
+ // can contain properties like lineComment, which are supported by
62
+ // all modes, and also directives like dontIndentStates, which are
63
+ // specific to simple modes.
64
+ meta: {
65
+ dontIndentStates: ["comment"],
66
+ lineComment: "//"
1008
67
  }
1009
- return token;
1010
- };
1011
-
1012
- // Consume a token from plannedTokens.
1013
- var consumeToken = function(stream, state) {
1014
- var plannedToken = state.plannedTokens.shift();
1015
- if (plannedToken === undefined) {
1016
- return null;
1017
- }
1018
- stream.match(plannedToken.value);
1019
- var tokens = plannedToken.type.split('.');
1020
- return cmTokenFromAceTokens(tokens);
1021
- };
1022
-
1023
- var matchToken = function(stream, state) {
1024
- // Anormal start: we already have planned tokens to consume.
1025
- if (state.plannedTokens.length > 0) {
1026
- return consumeToken(stream, state);
1027
- }
1028
-
1029
- // Normal start.
1030
- var currentState = state.current;
1031
- var currentLine = stream.match(/.*$/, false)[0];
1032
- var tokenized = tokenizer.getLineTokens(currentLine, currentState);
1033
- // We got a {tokens, state} object.
1034
- // Each token is a {value, type} object.
1035
- state.plannedTokens = tokenized.tokens;
1036
- state.current = tokenized.state;
1037
-
1038
- // Consume a token.
1039
- return consumeToken(stream, state);
1040
- }
1041
-
1042
- // Initialize all state.
1043
- var aceHighlightRules = new HighlightRules();
1044
- var tokenizer = new Tokenizer(aceHighlightRules.$rules);
1045
-
1046
- return {
1047
- startState: function() {
1048
- return {
1049
- current: 'start',
1050
- // List of {value, type}, with type being an Ace token string.
1051
- plannedTokens: []
1052
- };
1053
- },
1054
- blankLine: function(state) { matchToken('', state); },
1055
- token: matchToken
1056
- };
1057
- });
68
+ });
1058
69
 
1059
- CodeMirror.defineMIME("text/x-gobstones", "gobstones");
70
+ CodeMirror.defineMIME("text/x-gobstones", "gobstones");
71
+ })();