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("../htmlmixed/htmlmixed"), require("../ruby/ruby"));
7
else if (typeof define == "function" && define.amd) // AMD
8
define(["../../lib/codemirror", "../htmlmixed/htmlmixed", "../ruby/ruby"], mod);
9
else // Plain browser env
10
mod(CodeMirror);
11
})(function(CodeMirror) {
12
"use strict";
13
14
// full haml mode. This handled embeded ruby and html fragments too
15
CodeMirror.defineMode("haml", function(config) {
16
var htmlMode = CodeMirror.getMode(config, {name: "htmlmixed"});
17
var rubyMode = CodeMirror.getMode(config, "ruby");
18
19
function rubyInQuote(endQuote) {
20
return function(stream, state) {
21
var ch = stream.peek();
22
if (ch == endQuote && state.rubyState.tokenize.length == 1) {
23
// step out of ruby context as it seems to complete processing all the braces
24
stream.next();
25
state.tokenize = html;
26
return "closeAttributeTag";
27
} else {
28
return ruby(stream, state);
29
}
30
};
31
}
32
33
function ruby(stream, state) {
34
if (stream.match("-#")) {
35
stream.skipToEnd();
36
return "comment";
37
}
38
return rubyMode.token(stream, state.rubyState);
39
}
40
41
function html(stream, state) {
42
var ch = stream.peek();
43
44
// handle haml declarations. All declarations that cant be handled here
45
// will be passed to html mode
46
if (state.previousToken.style == "comment" ) {
47
if (state.indented > state.previousToken.indented) {
48
stream.skipToEnd();
49
return "commentLine";
50
}
51
}
52
53
if (state.startOfLine) {
54
if (ch == "!" && stream.match("!!")) {
55
stream.skipToEnd();
56
return "tag";
57
} else if (stream.match(/^%[\w:#\.]+=/)) {
58
state.tokenize = ruby;
59
return "hamlTag";
60
} else if (stream.match(/^%[\w:]+/)) {
61
return "hamlTag";
62
} else if (ch == "/" ) {
63
stream.skipToEnd();
64
return "comment";
65
}
66
}
67
68
if (state.startOfLine || state.previousToken.style == "hamlTag") {
69
if ( ch == "#" || ch == ".") {
70
stream.match(/[\w-#\.]*/);
71
return "hamlAttribute";
72
}
73
}
74
75
// donot handle --> as valid ruby, make it HTML close comment instead
76
if (state.startOfLine && !stream.match("-->", false) && (ch == "=" || ch == "-" )) {
77
state.tokenize = ruby;
78
return state.tokenize(stream, state);
79
}
80
81
if (state.previousToken.style == "hamlTag" ||
82
state.previousToken.style == "closeAttributeTag" ||
83
state.previousToken.style == "hamlAttribute") {
84
if (ch == "(") {
85
state.tokenize = rubyInQuote(")");
86
return state.tokenize(stream, state);
87
} else if (ch == "{") {
88
state.tokenize = rubyInQuote("}");
89
return state.tokenize(stream, state);
90
}
91
}
92
93
return htmlMode.token(stream, state.htmlState);
94
}
95
96
return {
97
// default to html mode
98
startState: function() {
99
var htmlState = htmlMode.startState();
100
var rubyState = rubyMode.startState();
101
return {
102
htmlState: htmlState,
103
rubyState: rubyState,
104
indented: 0,
105
previousToken: { style: null, indented: 0},
106
tokenize: html
107
};
108
},
109
110
copyState: function(state) {
111
return {
112
htmlState : CodeMirror.copyState(htmlMode, state.htmlState),
113
rubyState: CodeMirror.copyState(rubyMode, state.rubyState),
114
indented: state.indented,
115
previousToken: state.previousToken,
116
tokenize: state.tokenize
117
};
118
},
119
120
token: function(stream, state) {
121
if (stream.sol()) {
122
state.indented = stream.indentation();
123
state.startOfLine = true;
124
}
125
if (stream.eatSpace()) return null;
126
var style = state.tokenize(stream, state);
127
state.startOfLine = false;
128
// dont record comment line as we only want to measure comment line with
129
// the opening comment block
130
if (style && style != "commentLine") {
131
state.previousToken = { style: style, indented: state.indented };
132
}
133
// if current state is ruby and the previous token is not `,` reset the
134
// tokenize to html
135
if (stream.eol() && state.tokenize == ruby) {
136
stream.backUp(1);
137
var ch = stream.peek();
138
stream.next();
139
if (ch && ch != ",") {
140
state.tokenize = html;
141
}
142
}
143
// reprocess some of the specific style tag when finish setting previousToken
144
if (style == "hamlTag") {
145
style = "tag";
146
} else if (style == "commentLine") {
147
style = "comment";
148
} else if (style == "hamlAttribute") {
149
style = "attribute";
150
} else if (style == "closeAttributeTag") {
151
style = null;
152
}
153
return style;
154
}
155
};
156
}, "htmlmixed", "ruby");
157
158
CodeMirror.defineMIME("text/x-haml", "haml");
159
});
160
161