Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Avatar for KuCalc : devops.
Download
50665 views
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"), require("../javascript/javascript"), require("../css/css"), require("../htmlmixed/htmlmixed"));
7
else if (typeof define == "function" && define.amd) // AMD
8
define(["../../lib/codemirror", "../javascript/javascript", "../css/css", "../htmlmixed/htmlmixed"], mod);
9
else // Plain browser env
10
mod(CodeMirror);
11
})(function(CodeMirror) {
12
"use strict";
13
14
CodeMirror.defineMode('jade', function (config) {
15
// token types
16
var KEYWORD = 'keyword';
17
var DOCTYPE = 'meta';
18
var ID = 'builtin';
19
var CLASS = 'qualifier';
20
21
var ATTRS_NEST = {
22
'{': '}',
23
'(': ')',
24
'[': ']'
25
};
26
27
var jsMode = CodeMirror.getMode(config, 'javascript');
28
29
function State() {
30
this.javaScriptLine = false;
31
this.javaScriptLineExcludesColon = false;
32
33
this.javaScriptArguments = false;
34
this.javaScriptArgumentsDepth = 0;
35
36
this.isInterpolating = false;
37
this.interpolationNesting = 0;
38
39
this.jsState = jsMode.startState();
40
41
this.restOfLine = '';
42
43
this.isIncludeFiltered = false;
44
this.isEach = false;
45
46
this.lastTag = '';
47
this.scriptType = '';
48
49
// Attributes Mode
50
this.isAttrs = false;
51
this.attrsNest = [];
52
this.inAttributeName = true;
53
this.attributeIsType = false;
54
this.attrValue = '';
55
56
// Indented Mode
57
this.indentOf = Infinity;
58
this.indentToken = '';
59
60
this.innerMode = null;
61
this.innerState = null;
62
63
this.innerModeForLine = false;
64
}
65
/**
66
* Safely copy a state
67
*
68
* @return {State}
69
*/
70
State.prototype.copy = function () {
71
var res = new State();
72
res.javaScriptLine = this.javaScriptLine;
73
res.javaScriptLineExcludesColon = this.javaScriptLineExcludesColon;
74
res.javaScriptArguments = this.javaScriptArguments;
75
res.javaScriptArgumentsDepth = this.javaScriptArgumentsDepth;
76
res.isInterpolating = this.isInterpolating;
77
res.interpolationNesting = this.intpolationNesting;
78
79
res.jsState = CodeMirror.copyState(jsMode, this.jsState);
80
81
res.innerMode = this.innerMode;
82
if (this.innerMode && this.innerState) {
83
res.innerState = CodeMirror.copyState(this.innerMode, this.innerState);
84
}
85
86
res.restOfLine = this.restOfLine;
87
88
res.isIncludeFiltered = this.isIncludeFiltered;
89
res.isEach = this.isEach;
90
res.lastTag = this.lastTag;
91
res.scriptType = this.scriptType;
92
res.isAttrs = this.isAttrs;
93
res.attrsNest = this.attrsNest.slice();
94
res.inAttributeName = this.inAttributeName;
95
res.attributeIsType = this.attributeIsType;
96
res.attrValue = this.attrValue;
97
res.indentOf = this.indentOf;
98
res.indentToken = this.indentToken;
99
100
res.innerModeForLine = this.innerModeForLine;
101
102
return res;
103
};
104
105
function javaScript(stream, state) {
106
if (stream.sol()) {
107
// if javaScriptLine was set at end of line, ignore it
108
state.javaScriptLine = false;
109
state.javaScriptLineExcludesColon = false;
110
}
111
if (state.javaScriptLine) {
112
if (state.javaScriptLineExcludesColon && stream.peek() === ':') {
113
state.javaScriptLine = false;
114
state.javaScriptLineExcludesColon = false;
115
return;
116
}
117
var tok = jsMode.token(stream, state.jsState);
118
if (stream.eol()) state.javaScriptLine = false;
119
return tok || true;
120
}
121
}
122
function javaScriptArguments(stream, state) {
123
if (state.javaScriptArguments) {
124
if (state.javaScriptArgumentsDepth === 0 && stream.peek() !== '(') {
125
state.javaScriptArguments = false;
126
return;
127
}
128
if (stream.peek() === '(') {
129
state.javaScriptArgumentsDepth++;
130
} else if (stream.peek() === ')') {
131
state.javaScriptArgumentsDepth--;
132
}
133
if (state.javaScriptArgumentsDepth === 0) {
134
state.javaScriptArguments = false;
135
return;
136
}
137
138
var tok = jsMode.token(stream, state.jsState);
139
return tok || true;
140
}
141
}
142
143
function yieldStatement(stream) {
144
if (stream.match(/^yield\b/)) {
145
return 'keyword';
146
}
147
}
148
149
function doctype(stream) {
150
if (stream.match(/^(?:doctype) *([^\n]+)?/)) {
151
return DOCTYPE;
152
}
153
}
154
155
function interpolation(stream, state) {
156
if (stream.match('#{')) {
157
state.isInterpolating = true;
158
state.interpolationNesting = 0;
159
return 'punctuation';
160
}
161
}
162
163
function interpolationContinued(stream, state) {
164
if (state.isInterpolating) {
165
if (stream.peek() === '}') {
166
state.interpolationNesting--;
167
if (state.interpolationNesting < 0) {
168
stream.next();
169
state.isInterpolating = false;
170
return 'puncutation';
171
}
172
} else if (stream.peek() === '{') {
173
state.interpolationNesting++;
174
}
175
return jsMode.token(stream, state.jsState) || true;
176
}
177
}
178
179
function caseStatement(stream, state) {
180
if (stream.match(/^case\b/)) {
181
state.javaScriptLine = true;
182
return KEYWORD;
183
}
184
}
185
186
function when(stream, state) {
187
if (stream.match(/^when\b/)) {
188
state.javaScriptLine = true;
189
state.javaScriptLineExcludesColon = true;
190
return KEYWORD;
191
}
192
}
193
194
function defaultStatement(stream) {
195
if (stream.match(/^default\b/)) {
196
return KEYWORD;
197
}
198
}
199
200
function extendsStatement(stream, state) {
201
if (stream.match(/^extends?\b/)) {
202
state.restOfLine = 'string';
203
return KEYWORD;
204
}
205
}
206
207
function append(stream, state) {
208
if (stream.match(/^append\b/)) {
209
state.restOfLine = 'variable';
210
return KEYWORD;
211
}
212
}
213
function prepend(stream, state) {
214
if (stream.match(/^prepend\b/)) {
215
state.restOfLine = 'variable';
216
return KEYWORD;
217
}
218
}
219
function block(stream, state) {
220
if (stream.match(/^block\b *(?:(prepend|append)\b)?/)) {
221
state.restOfLine = 'variable';
222
return KEYWORD;
223
}
224
}
225
226
function include(stream, state) {
227
if (stream.match(/^include\b/)) {
228
state.restOfLine = 'string';
229
return KEYWORD;
230
}
231
}
232
233
function includeFiltered(stream, state) {
234
if (stream.match(/^include:([a-zA-Z0-9\-]+)/, false) && stream.match('include')) {
235
state.isIncludeFiltered = true;
236
return KEYWORD;
237
}
238
}
239
240
function includeFilteredContinued(stream, state) {
241
if (state.isIncludeFiltered) {
242
var tok = filter(stream, state);
243
state.isIncludeFiltered = false;
244
state.restOfLine = 'string';
245
return tok;
246
}
247
}
248
249
function mixin(stream, state) {
250
if (stream.match(/^mixin\b/)) {
251
state.javaScriptLine = true;
252
return KEYWORD;
253
}
254
}
255
256
function call(stream, state) {
257
if (stream.match(/^\+([-\w]+)/)) {
258
if (!stream.match(/^\( *[-\w]+ *=/, false)) {
259
state.javaScriptArguments = true;
260
state.javaScriptArgumentsDepth = 0;
261
}
262
return 'variable';
263
}
264
if (stream.match(/^\+#{/, false)) {
265
stream.next();
266
state.mixinCallAfter = true;
267
return interpolation(stream, state);
268
}
269
}
270
function callArguments(stream, state) {
271
if (state.mixinCallAfter) {
272
state.mixinCallAfter = false;
273
if (!stream.match(/^\( *[-\w]+ *=/, false)) {
274
state.javaScriptArguments = true;
275
state.javaScriptArgumentsDepth = 0;
276
}
277
return true;
278
}
279
}
280
281
function conditional(stream, state) {
282
if (stream.match(/^(if|unless|else if|else)\b/)) {
283
state.javaScriptLine = true;
284
return KEYWORD;
285
}
286
}
287
288
function each(stream, state) {
289
if (stream.match(/^(- *)?(each|for)\b/)) {
290
state.isEach = true;
291
return KEYWORD;
292
}
293
}
294
function eachContinued(stream, state) {
295
if (state.isEach) {
296
if (stream.match(/^ in\b/)) {
297
state.javaScriptLine = true;
298
state.isEach = false;
299
return KEYWORD;
300
} else if (stream.sol() || stream.eol()) {
301
state.isEach = false;
302
} else if (stream.next()) {
303
while (!stream.match(/^ in\b/, false) && stream.next());
304
return 'variable';
305
}
306
}
307
}
308
309
function whileStatement(stream, state) {
310
if (stream.match(/^while\b/)) {
311
state.javaScriptLine = true;
312
return KEYWORD;
313
}
314
}
315
316
function tag(stream, state) {
317
var captures;
318
if (captures = stream.match(/^(\w(?:[-:\w]*\w)?)\/?/)) {
319
state.lastTag = captures[1].toLowerCase();
320
if (state.lastTag === 'script') {
321
state.scriptType = 'application/javascript';
322
}
323
return 'tag';
324
}
325
}
326
327
function filter(stream, state) {
328
if (stream.match(/^:([\w\-]+)/)) {
329
var innerMode;
330
if (config && config.innerModes) {
331
innerMode = config.innerModes(stream.current().substring(1));
332
}
333
if (!innerMode) {
334
innerMode = stream.current().substring(1);
335
}
336
if (typeof innerMode === 'string') {
337
innerMode = CodeMirror.getMode(config, innerMode);
338
}
339
setInnerMode(stream, state, innerMode);
340
return 'atom';
341
}
342
}
343
344
function code(stream, state) {
345
if (stream.match(/^(!?=|-)/)) {
346
state.javaScriptLine = true;
347
return 'punctuation';
348
}
349
}
350
351
function id(stream) {
352
if (stream.match(/^#([\w-]+)/)) {
353
return ID;
354
}
355
}
356
357
function className(stream) {
358
if (stream.match(/^\.([\w-]+)/)) {
359
return CLASS;
360
}
361
}
362
363
function attrs(stream, state) {
364
if (stream.peek() == '(') {
365
stream.next();
366
state.isAttrs = true;
367
state.attrsNest = [];
368
state.inAttributeName = true;
369
state.attrValue = '';
370
state.attributeIsType = false;
371
return 'punctuation';
372
}
373
}
374
375
function attrsContinued(stream, state) {
376
if (state.isAttrs) {
377
if (ATTRS_NEST[stream.peek()]) {
378
state.attrsNest.push(ATTRS_NEST[stream.peek()]);
379
}
380
if (state.attrsNest[state.attrsNest.length - 1] === stream.peek()) {
381
state.attrsNest.pop();
382
} else if (stream.eat(')')) {
383
state.isAttrs = false;
384
return 'punctuation';
385
}
386
if (state.inAttributeName && stream.match(/^[^=,\)!]+/)) {
387
if (stream.peek() === '=' || stream.peek() === '!') {
388
state.inAttributeName = false;
389
state.jsState = jsMode.startState();
390
if (state.lastTag === 'script' && stream.current().trim().toLowerCase() === 'type') {
391
state.attributeIsType = true;
392
} else {
393
state.attributeIsType = false;
394
}
395
}
396
return 'attribute';
397
}
398
399
var tok = jsMode.token(stream, state.jsState);
400
if (state.attributeIsType && tok === 'string') {
401
state.scriptType = stream.current().toString();
402
}
403
if (state.attrsNest.length === 0 && (tok === 'string' || tok === 'variable' || tok === 'keyword')) {
404
try {
405
Function('', 'var x ' + state.attrValue.replace(/,\s*$/, '').replace(/^!/, ''));
406
state.inAttributeName = true;
407
state.attrValue = '';
408
stream.backUp(stream.current().length);
409
return attrsContinued(stream, state);
410
} catch (ex) {
411
//not the end of an attribute
412
}
413
}
414
state.attrValue += stream.current();
415
return tok || true;
416
}
417
}
418
419
function attributesBlock(stream, state) {
420
if (stream.match(/^&attributes\b/)) {
421
state.javaScriptArguments = true;
422
state.javaScriptArgumentsDepth = 0;
423
return 'keyword';
424
}
425
}
426
427
function indent(stream) {
428
if (stream.sol() && stream.eatSpace()) {
429
return 'indent';
430
}
431
}
432
433
function comment(stream, state) {
434
if (stream.match(/^ *\/\/(-)?([^\n]*)/)) {
435
state.indentOf = stream.indentation();
436
state.indentToken = 'comment';
437
return 'comment';
438
}
439
}
440
441
function colon(stream) {
442
if (stream.match(/^: */)) {
443
return 'colon';
444
}
445
}
446
447
function text(stream, state) {
448
if (stream.match(/^(?:\| ?| )([^\n]+)/)) {
449
return 'string';
450
}
451
if (stream.match(/^(<[^\n]*)/, false)) {
452
// html string
453
setInnerMode(stream, state, 'htmlmixed');
454
state.innerModeForLine = true;
455
return innerMode(stream, state, true);
456
}
457
}
458
459
function dot(stream, state) {
460
if (stream.eat('.')) {
461
var innerMode = null;
462
if (state.lastTag === 'script' && state.scriptType.toLowerCase().indexOf('javascript') != -1) {
463
innerMode = state.scriptType.toLowerCase().replace(/"|'/g, '');
464
} else if (state.lastTag === 'style') {
465
innerMode = 'css';
466
}
467
setInnerMode(stream, state, innerMode);
468
return 'dot';
469
}
470
}
471
472
function fail(stream) {
473
stream.next();
474
return null;
475
}
476
477
478
function setInnerMode(stream, state, mode) {
479
mode = CodeMirror.mimeModes[mode] || mode;
480
mode = config.innerModes ? config.innerModes(mode) || mode : mode;
481
mode = CodeMirror.mimeModes[mode] || mode;
482
mode = CodeMirror.getMode(config, mode);
483
state.indentOf = stream.indentation();
484
485
if (mode && mode.name !== 'null') {
486
state.innerMode = mode;
487
} else {
488
state.indentToken = 'string';
489
}
490
}
491
function innerMode(stream, state, force) {
492
if (stream.indentation() > state.indentOf || (state.innerModeForLine && !stream.sol()) || force) {
493
if (state.innerMode) {
494
if (!state.innerState) {
495
state.innerState = state.innerMode.startState ? state.innerMode.startState(stream.indentation()) : {};
496
}
497
return stream.hideFirstChars(state.indentOf + 2, function () {
498
return state.innerMode.token(stream, state.innerState) || true;
499
});
500
} else {
501
stream.skipToEnd();
502
return state.indentToken;
503
}
504
} else if (stream.sol()) {
505
state.indentOf = Infinity;
506
state.indentToken = null;
507
state.innerMode = null;
508
state.innerState = null;
509
}
510
}
511
function restOfLine(stream, state) {
512
if (stream.sol()) {
513
// if restOfLine was set at end of line, ignore it
514
state.restOfLine = '';
515
}
516
if (state.restOfLine) {
517
stream.skipToEnd();
518
var tok = state.restOfLine;
519
state.restOfLine = '';
520
return tok;
521
}
522
}
523
524
525
function startState() {
526
return new State();
527
}
528
function copyState(state) {
529
return state.copy();
530
}
531
/**
532
* Get the next token in the stream
533
*
534
* @param {Stream} stream
535
* @param {State} state
536
*/
537
function nextToken(stream, state) {
538
var tok = innerMode(stream, state)
539
|| restOfLine(stream, state)
540
|| interpolationContinued(stream, state)
541
|| includeFilteredContinued(stream, state)
542
|| eachContinued(stream, state)
543
|| attrsContinued(stream, state)
544
|| javaScript(stream, state)
545
|| javaScriptArguments(stream, state)
546
|| callArguments(stream, state)
547
548
|| yieldStatement(stream, state)
549
|| doctype(stream, state)
550
|| interpolation(stream, state)
551
|| caseStatement(stream, state)
552
|| when(stream, state)
553
|| defaultStatement(stream, state)
554
|| extendsStatement(stream, state)
555
|| append(stream, state)
556
|| prepend(stream, state)
557
|| block(stream, state)
558
|| include(stream, state)
559
|| includeFiltered(stream, state)
560
|| mixin(stream, state)
561
|| call(stream, state)
562
|| conditional(stream, state)
563
|| each(stream, state)
564
|| whileStatement(stream, state)
565
|| tag(stream, state)
566
|| filter(stream, state)
567
|| code(stream, state)
568
|| id(stream, state)
569
|| className(stream, state)
570
|| attrs(stream, state)
571
|| attributesBlock(stream, state)
572
|| indent(stream, state)
573
|| text(stream, state)
574
|| comment(stream, state)
575
|| colon(stream, state)
576
|| dot(stream, state)
577
|| fail(stream, state);
578
579
return tok === true ? null : tok;
580
}
581
return {
582
startState: startState,
583
copyState: copyState,
584
token: nextToken
585
};
586
});
587
588
CodeMirror.defineMIME('text/x-jade', 'jade');
589
590
});
591
592