annotate .cms/lib/codemirror/mode/haml/haml.js @ 1:1d486627aa1e draft default tip

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