Commit dc4e739c113f1302360544465c0db31ca46b22a2
1 parent
9d99be84
Exists in
master
and in
7 other branches
Inclusão do mode scribe obtido do scribeUI para uso no editor de mapfiles com codemirror
Showing
4 changed files
with
907 additions
and
0 deletions
Show diff stats
... | ... | @@ -0,0 +1,325 @@ |
1 | +CodeMirror.defineMode("xml", function(config, parserConfig) { | |
2 | + var indentUnit = config.indentUnit; | |
3 | + var Kludges = parserConfig.mapfileMode ? { | |
4 | + autoSelfClosers: {'area': true, 'base': true, 'br': true, 'col': true, 'command': true, | |
5 | + 'embed': true, 'frame': true, 'hr': true, 'img': true, 'input': true, | |
6 | + 'keygen': true, 'link': true, 'meta': true, 'param': true, 'source': true, | |
7 | + 'track': true, 'wbr': true}, | |
8 | + implicitlyClosed: {'dd': true, 'li': true, 'optgroup': true, 'option': true, 'p': true, | |
9 | + 'rp': true, 'rt': true, 'tbody': true, 'td': true, 'tfoot': true, | |
10 | + 'th': true, 'tr': true}, | |
11 | + contextGrabbers: { | |
12 | + 'dd': {'dd': true, 'dt': true}, | |
13 | + 'dt': {'dd': true, 'dt': true}, | |
14 | + 'li': {'li': true}, | |
15 | + 'option': {'option': true, 'optgroup': true}, | |
16 | + 'optgroup': {'optgroup': true}, | |
17 | + 'p': {'address': true, 'article': true, 'aside': true, 'blockquote': true, 'dir': true, | |
18 | + 'div': true, 'dl': true, 'fieldset': true, 'footer': true, 'form': true, | |
19 | + 'h1': true, 'h2': true, 'h3': true, 'h4': true, 'h5': true, 'h6': true, | |
20 | + 'header': true, 'hgroup': true, 'hr': true, 'menu': true, 'nav': true, 'ol': true, | |
21 | + 'p': true, 'pre': true, 'section': true, 'table': true, 'ul': true}, | |
22 | + 'rp': {'rp': true, 'rt': true}, | |
23 | + 'rt': {'rp': true, 'rt': true}, | |
24 | + 'tbody': {'tbody': true, 'tfoot': true}, | |
25 | + 'td': {'td': true, 'th': true}, | |
26 | + 'tfoot': {'tbody': true}, | |
27 | + 'th': {'td': true, 'th': true}, | |
28 | + 'thead': {'tbody': true, 'tfoot': true}, | |
29 | + 'tr': {'tr': true} | |
30 | + }, | |
31 | + doNotIndent: {"pre": true}, | |
32 | + allowUnquoted: true, | |
33 | + allowMissing: false | |
34 | + } : { | |
35 | + autoSelfClosers: {}, | |
36 | + implicitlyClosed: {}, | |
37 | + contextGrabbers: {}, | |
38 | + doNotIndent: {}, | |
39 | + allowUnquoted: false, | |
40 | + allowMissing: false | |
41 | + }; | |
42 | + var alignCDATA = parserConfig.alignCDATA; | |
43 | + | |
44 | + // Return variables for tokenizers | |
45 | + var tagName, type; | |
46 | + | |
47 | + function inText(stream, state) { | |
48 | + function chain(parser) { | |
49 | + state.tokenize = parser; | |
50 | + return parser(stream, state); | |
51 | + } | |
52 | + | |
53 | + var ch = stream.next(); | |
54 | + if (ch == "<") { | |
55 | + if (stream.eat("!")) { | |
56 | + if (stream.eat("[")) { | |
57 | + if (stream.match("CDATA[")) return chain(inBlock("atom", "]]>")); | |
58 | + else return null; | |
59 | + } | |
60 | + else if (stream.match("--")) return chain(inBlock("comment", "-->")); | |
61 | + else if (stream.match("DOCTYPE", true, true)) { | |
62 | + stream.eatWhile(/[\w\._\-]/); | |
63 | + return chain(doctype(1)); | |
64 | + } | |
65 | + else return null; | |
66 | + } | |
67 | + else if (stream.eat("?")) { | |
68 | + stream.eatWhile(/[\w\._\-]/); | |
69 | + state.tokenize = inBlock("meta", "?>"); | |
70 | + return "meta"; | |
71 | + } | |
72 | + else { | |
73 | + type = stream.eat("/") ? "closeTag" : "openTag"; | |
74 | + stream.eatSpace(); | |
75 | + tagName = ""; | |
76 | + var c; | |
77 | + while ((c = stream.eat(/[^\s\u00a0=<>\"\'\/?]/))) tagName += c; | |
78 | + state.tokenize = inTag; | |
79 | + return "tag"; | |
80 | + } | |
81 | + } | |
82 | + else if (ch == "&") { | |
83 | + var ok; | |
84 | + if (stream.eat("#")) { | |
85 | + if (stream.eat("x")) { | |
86 | + ok = stream.eatWhile(/[a-fA-F\d]/) && stream.eat(";"); | |
87 | + } else { | |
88 | + ok = stream.eatWhile(/[\d]/) && stream.eat(";"); | |
89 | + } | |
90 | + } else { | |
91 | + ok = stream.eatWhile(/[\w\.\-:]/) && stream.eat(";"); | |
92 | + } | |
93 | + return ok ? "atom" : "error"; | |
94 | + } | |
95 | + else { | |
96 | + stream.eatWhile(/[^&<]/); | |
97 | + return null; | |
98 | + } | |
99 | + } | |
100 | + | |
101 | + function inTag(stream, state) { | |
102 | + var ch = stream.next(); | |
103 | + if (ch == ">" || (ch == "/" && stream.eat(">"))) { | |
104 | + state.tokenize = inText; | |
105 | + type = ch == ">" ? "endTag" : "selfcloseTag"; | |
106 | + return "tag"; | |
107 | + } | |
108 | + else if (ch == "=") { | |
109 | + type = "equals"; | |
110 | + return null; | |
111 | + } | |
112 | + else if (/[\'\"]/.test(ch)) { | |
113 | + state.tokenize = inAttribute(ch); | |
114 | + return state.tokenize(stream, state); | |
115 | + } | |
116 | + else { | |
117 | + stream.eatWhile(/[^\s\u00a0=<>\"\'\/?]/); | |
118 | + return "word"; | |
119 | + } | |
120 | + } | |
121 | + | |
122 | + function inAttribute(quote) { | |
123 | + return function(stream, state) { | |
124 | + while (!stream.eol()) { | |
125 | + if (stream.next() == quote) { | |
126 | + state.tokenize = inTag; | |
127 | + break; | |
128 | + } | |
129 | + } | |
130 | + return "string"; | |
131 | + }; | |
132 | + } | |
133 | + | |
134 | + function inBlock(style, terminator) { | |
135 | + return function(stream, state) { | |
136 | + while (!stream.eol()) { | |
137 | + if (stream.match(terminator)) { | |
138 | + state.tokenize = inText; | |
139 | + break; | |
140 | + } | |
141 | + stream.next(); | |
142 | + } | |
143 | + return style; | |
144 | + }; | |
145 | + } | |
146 | + function doctype(depth) { | |
147 | + return function(stream, state) { | |
148 | + var ch; | |
149 | + while ((ch = stream.next()) != null) { | |
150 | + if (ch == "<") { | |
151 | + state.tokenize = doctype(depth + 1); | |
152 | + return state.tokenize(stream, state); | |
153 | + } else if (ch == ">") { | |
154 | + if (depth == 1) { | |
155 | + state.tokenize = inText; | |
156 | + break; | |
157 | + } else { | |
158 | + state.tokenize = doctype(depth - 1); | |
159 | + return state.tokenize(stream, state); | |
160 | + } | |
161 | + } | |
162 | + } | |
163 | + return "meta"; | |
164 | + }; | |
165 | + } | |
166 | + | |
167 | + var curState, setStyle; | |
168 | + function pass() { | |
169 | + for (var i = arguments.length - 1; i >= 0; i--) curState.cc.push(arguments[i]); | |
170 | + } | |
171 | + function cont() { | |
172 | + pass.apply(null, arguments); | |
173 | + return true; | |
174 | + } | |
175 | + | |
176 | + function pushContext(tagName, startOfLine) { | |
177 | + var noIndent = Kludges.doNotIndent.hasOwnProperty(tagName) || (curState.context && curState.context.noIndent); | |
178 | + curState.context = { | |
179 | + prev: curState.context, | |
180 | + tagName: tagName, | |
181 | + indent: curState.indented, | |
182 | + startOfLine: startOfLine, | |
183 | + noIndent: noIndent | |
184 | + }; | |
185 | + } | |
186 | + function popContext() { | |
187 | + if (curState.context) curState.context = curState.context.prev; | |
188 | + } | |
189 | + | |
190 | + function element(type) { | |
191 | + if (type == "openTag") { | |
192 | + curState.tagName = tagName; | |
193 | + return cont(attributes, endtag(curState.startOfLine)); | |
194 | + } else if (type == "closeTag") { | |
195 | + var err = false; | |
196 | + if (curState.context) { | |
197 | + if (curState.context.tagName != tagName) { | |
198 | + if (Kludges.implicitlyClosed.hasOwnProperty(curState.context.tagName.toLowerCase())) { | |
199 | + popContext(); | |
200 | + } | |
201 | + err = !curState.context || curState.context.tagName != tagName; | |
202 | + } | |
203 | + } else { | |
204 | + err = true; | |
205 | + } | |
206 | + if (err) setStyle = "error"; | |
207 | + return cont(endclosetag(err)); | |
208 | + } | |
209 | + return cont(); | |
210 | + } | |
211 | + function endtag(startOfLine) { | |
212 | + return function(type) { | |
213 | + if (type == "selfcloseTag" || | |
214 | + (type == "endTag" && Kludges.autoSelfClosers.hasOwnProperty(curState.tagName.toLowerCase()))) { | |
215 | + maybePopContext(curState.tagName.toLowerCase()); | |
216 | + return cont(); | |
217 | + } | |
218 | + if (type == "endTag") { | |
219 | + maybePopContext(curState.tagName.toLowerCase()); | |
220 | + pushContext(curState.tagName, startOfLine); | |
221 | + return cont(); | |
222 | + } | |
223 | + return cont(); | |
224 | + }; | |
225 | + } | |
226 | + function endclosetag(err) { | |
227 | + return function(type) { | |
228 | + if (err) setStyle = "error"; | |
229 | + if (type == "endTag") { popContext(); return cont(); } | |
230 | + setStyle = "error"; | |
231 | + return cont(arguments.callee); | |
232 | + } | |
233 | + } | |
234 | + function maybePopContext(nextTagName) { | |
235 | + var parentTagName; | |
236 | + while (true) { | |
237 | + if (!curState.context) { | |
238 | + return; | |
239 | + } | |
240 | + parentTagName = curState.context.tagName.toLowerCase(); | |
241 | + if (!Kludges.contextGrabbers.hasOwnProperty(parentTagName) || | |
242 | + !Kludges.contextGrabbers[parentTagName].hasOwnProperty(nextTagName)) { | |
243 | + return; | |
244 | + } | |
245 | + popContext(); | |
246 | + } | |
247 | + } | |
248 | + | |
249 | + function attributes(type) { | |
250 | + if (type == "word") {setStyle = "attribute"; return cont(attribute, attributes);} | |
251 | + if (type == "endTag" || type == "selfcloseTag") return pass(); | |
252 | + setStyle = "error"; | |
253 | + return cont(attributes); | |
254 | + } | |
255 | + function attribute(type) { | |
256 | + if (type == "equals") return cont(attvalue, attributes); | |
257 | + if (!Kludges.allowMissing) setStyle = "error"; | |
258 | + return (type == "endTag" || type == "selfcloseTag") ? pass() : cont(); | |
259 | + } | |
260 | + function attvalue(type) { | |
261 | + if (type == "string") return cont(attvaluemaybe); | |
262 | + if (type == "word" && Kludges.allowUnquoted) {setStyle = "string"; return cont();} | |
263 | + setStyle = "error"; | |
264 | + return (type == "endTag" || type == "selfCloseTag") ? pass() : cont(); | |
265 | + } | |
266 | + function attvaluemaybe(type) { | |
267 | + if (type == "string") return cont(attvaluemaybe); | |
268 | + else return pass(); | |
269 | + } | |
270 | + | |
271 | + return { | |
272 | + startState: function() { | |
273 | + return {tokenize: inText, cc: [], indented: 0, startOfLine: true, tagName: null, context: null}; | |
274 | + }, | |
275 | + | |
276 | + token: function(stream, state) { | |
277 | + if (stream.sol()) { | |
278 | + state.startOfLine = true; | |
279 | + state.indented = stream.indentation(); | |
280 | + } | |
281 | + if (stream.eatSpace()) return null; | |
282 | + | |
283 | + setStyle = type = tagName = null; | |
284 | + var style = state.tokenize(stream, state); | |
285 | + state.type = type; | |
286 | + if ((style || type) && style != "comment") { | |
287 | + curState = state; | |
288 | + while (true) { | |
289 | + var comb = state.cc.pop() || element; | |
290 | + if (comb(type || style)) break; | |
291 | + } | |
292 | + } | |
293 | + state.startOfLine = false; | |
294 | + return setStyle || style; | |
295 | + }, | |
296 | + | |
297 | + indent: function(state, textAfter, fullLine) { | |
298 | + var context = state.context; | |
299 | + if ((state.tokenize != inTag && state.tokenize != inText) || | |
300 | + context && context.noIndent) | |
301 | + return fullLine ? fullLine.match(/^(\s*)/)[0].length : 0; | |
302 | + if (alignCDATA && /<!\[CDATA\[/.test(textAfter)) return 0; | |
303 | + if (context && /^<\//.test(textAfter)) | |
304 | + context = context.prev; | |
305 | + while (context && !context.startOfLine) | |
306 | + context = context.prev; | |
307 | + if (context) return context.indent + indentUnit; | |
308 | + else return 0; | |
309 | + }, | |
310 | + | |
311 | + compareStates: function(a, b) { | |
312 | + if (a.indented != b.indented || a.tokenize != b.tokenize) return false; | |
313 | + for (var ca = a.context, cb = b.context; ; ca = ca.prev, cb = cb.prev) { | |
314 | + if (!ca || !cb) return ca == cb; | |
315 | + if (ca.tagName != cb.tagName) return false; | |
316 | + } | |
317 | + }, | |
318 | + | |
319 | + electricChars: "/" | |
320 | + }; | |
321 | +}); | |
322 | + | |
323 | +CodeMirror.defineMIME("application/xml", "xml"); | |
324 | +if (!CodeMirror.mimeModes.hasOwnProperty("text/html")) | |
325 | + CodeMirror.defineMIME("text/html", {name: "xml", htmlMode: true}); | ... | ... |
... | ... | @@ -0,0 +1,44 @@ |
1 | +<!doctype html> | |
2 | +<html> | |
3 | + <head> | |
4 | + <title>CodeMirror: XML mode</title> | |
5 | + <link rel="stylesheet" href="../../lib/codemirror.css"> | |
6 | + <script src="../../lib/codemirror.js"></script> | |
7 | + <script src="xml.js"></script> | |
8 | + <style type="text/css">.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style> | |
9 | + <link rel="stylesheet" href="../../doc/docs.css"> | |
10 | + </head> | |
11 | + <body> | |
12 | + <h1>CodeMirror: XML mode</h1> | |
13 | + <form><textarea id="code" name="code"> | |
14 | +<html style="color: green"> | |
15 | + <!-- this is a comment --> | |
16 | + <head> | |
17 | + <title>HTML Example</title> | |
18 | + </head> | |
19 | + <body> | |
20 | + The indentation tries to be <em>somewhat &quot;do what | |
21 | + I mean&quot;</em>... but might not match your style. | |
22 | + </body> | |
23 | +</html> | |
24 | +</textarea></form> | |
25 | + <script> | |
26 | + var editor = CodeMirror.fromTextArea(document.getElementById("code"), { | |
27 | + mode: {name: "xml", alignCDATA: true}, | |
28 | + lineNumbers: true | |
29 | + }); | |
30 | + </script> | |
31 | + <p>The XML mode supports two configuration parameters:</p> | |
32 | + <dl> | |
33 | + <dt><code>htmlMode (boolean)</code></dt> | |
34 | + <dd>This switches the mode to parse HTML instead of XML. This | |
35 | + means attributes do not have to be quoted, and some elements | |
36 | + (such as <code>br</code>) do not require a closing tag.</dd> | |
37 | + <dt><code>alignCDATA (boolean)</code></dt> | |
38 | + <dd>Setting this to true will force the opening tag of CDATA | |
39 | + blocks to not be indented.</dd> | |
40 | + </dl> | |
41 | + | |
42 | + <p><strong>MIME types defined:</strong> <code>application/xml</code>, <code>text/html</code>.</p> | |
43 | + </body> | |
44 | +</html> | ... | ... |
... | ... | @@ -0,0 +1,325 @@ |
1 | +CodeMirror.defineMode("xml", function(config, parserConfig) { | |
2 | + var indentUnit = config.indentUnit; | |
3 | + var Kludges = parserConfig.htmlMode ? { | |
4 | + autoSelfClosers: {'area': true, 'base': true, 'br': true, 'col': true, 'command': true, | |
5 | + 'embed': true, 'frame': true, 'hr': true, 'img': true, 'input': true, | |
6 | + 'keygen': true, 'link': true, 'meta': true, 'param': true, 'source': true, | |
7 | + 'track': true, 'wbr': true}, | |
8 | + implicitlyClosed: {'dd': true, 'li': true, 'optgroup': true, 'option': true, 'p': true, | |
9 | + 'rp': true, 'rt': true, 'tbody': true, 'td': true, 'tfoot': true, | |
10 | + 'th': true, 'tr': true}, | |
11 | + contextGrabbers: { | |
12 | + 'dd': {'dd': true, 'dt': true}, | |
13 | + 'dt': {'dd': true, 'dt': true}, | |
14 | + 'li': {'li': true}, | |
15 | + 'option': {'option': true, 'optgroup': true}, | |
16 | + 'optgroup': {'optgroup': true}, | |
17 | + 'p': {'address': true, 'article': true, 'aside': true, 'blockquote': true, 'dir': true, | |
18 | + 'div': true, 'dl': true, 'fieldset': true, 'footer': true, 'form': true, | |
19 | + 'h1': true, 'h2': true, 'h3': true, 'h4': true, 'h5': true, 'h6': true, | |
20 | + 'header': true, 'hgroup': true, 'hr': true, 'menu': true, 'nav': true, 'ol': true, | |
21 | + 'p': true, 'pre': true, 'section': true, 'table': true, 'ul': true}, | |
22 | + 'rp': {'rp': true, 'rt': true}, | |
23 | + 'rt': {'rp': true, 'rt': true}, | |
24 | + 'tbody': {'tbody': true, 'tfoot': true}, | |
25 | + 'td': {'td': true, 'th': true}, | |
26 | + 'tfoot': {'tbody': true}, | |
27 | + 'th': {'td': true, 'th': true}, | |
28 | + 'thead': {'tbody': true, 'tfoot': true}, | |
29 | + 'tr': {'tr': true} | |
30 | + }, | |
31 | + doNotIndent: {"pre": true}, | |
32 | + allowUnquoted: true, | |
33 | + allowMissing: false | |
34 | + } : { | |
35 | + autoSelfClosers: {}, | |
36 | + implicitlyClosed: {}, | |
37 | + contextGrabbers: {}, | |
38 | + doNotIndent: {}, | |
39 | + allowUnquoted: false, | |
40 | + allowMissing: false | |
41 | + }; | |
42 | + var alignCDATA = parserConfig.alignCDATA; | |
43 | + | |
44 | + // Return variables for tokenizers | |
45 | + var tagName, type; | |
46 | + | |
47 | + function inText(stream, state) { | |
48 | + function chain(parser) { | |
49 | + state.tokenize = parser; | |
50 | + return parser(stream, state); | |
51 | + } | |
52 | + | |
53 | + var ch = stream.next(); | |
54 | + if (ch == "<") { | |
55 | + if (stream.eat("!")) { | |
56 | + if (stream.eat("[")) { | |
57 | + if (stream.match("CDATA[")) return chain(inBlock("atom", "]]>")); | |
58 | + else return null; | |
59 | + } | |
60 | + else if (stream.match("--")) return chain(inBlock("comment", "-->")); | |
61 | + else if (stream.match("DOCTYPE", true, true)) { | |
62 | + stream.eatWhile(/[\w\._\-]/); | |
63 | + return chain(doctype(1)); | |
64 | + } | |
65 | + else return null; | |
66 | + } | |
67 | + else if (stream.eat("?")) { | |
68 | + stream.eatWhile(/[\w\._\-]/); | |
69 | + state.tokenize = inBlock("meta", "?>"); | |
70 | + return "meta"; | |
71 | + } | |
72 | + else { | |
73 | + type = stream.eat("/") ? "closeTag" : "openTag"; | |
74 | + stream.eatSpace(); | |
75 | + tagName = ""; | |
76 | + var c; | |
77 | + while ((c = stream.eat(/[^\s\u00a0=<>\"\'\/?]/))) tagName += c; | |
78 | + state.tokenize = inTag; | |
79 | + return "tag"; | |
80 | + } | |
81 | + } | |
82 | + else if (ch == "&") { | |
83 | + var ok; | |
84 | + if (stream.eat("#")) { | |
85 | + if (stream.eat("x")) { | |
86 | + ok = stream.eatWhile(/[a-fA-F\d]/) && stream.eat(";"); | |
87 | + } else { | |
88 | + ok = stream.eatWhile(/[\d]/) && stream.eat(";"); | |
89 | + } | |
90 | + } else { | |
91 | + ok = stream.eatWhile(/[\w\.\-:]/) && stream.eat(";"); | |
92 | + } | |
93 | + return ok ? "atom" : "error"; | |
94 | + } | |
95 | + else { | |
96 | + stream.eatWhile(/[^&<]/); | |
97 | + return null; | |
98 | + } | |
99 | + } | |
100 | + | |
101 | + function inTag(stream, state) { | |
102 | + var ch = stream.next(); | |
103 | + if (ch == ">" || (ch == "/" && stream.eat(">"))) { | |
104 | + state.tokenize = inText; | |
105 | + type = ch == ">" ? "endTag" : "selfcloseTag"; | |
106 | + return "tag"; | |
107 | + } | |
108 | + else if (ch == "=") { | |
109 | + type = "equals"; | |
110 | + return null; | |
111 | + } | |
112 | + else if (/[\'\"]/.test(ch)) { | |
113 | + state.tokenize = inAttribute(ch); | |
114 | + return state.tokenize(stream, state); | |
115 | + } | |
116 | + else { | |
117 | + stream.eatWhile(/[^\s\u00a0=<>\"\'\/?]/); | |
118 | + return "word"; | |
119 | + } | |
120 | + } | |
121 | + | |
122 | + function inAttribute(quote) { | |
123 | + return function(stream, state) { | |
124 | + while (!stream.eol()) { | |
125 | + if (stream.next() == quote) { | |
126 | + state.tokenize = inTag; | |
127 | + break; | |
128 | + } | |
129 | + } | |
130 | + return "string"; | |
131 | + }; | |
132 | + } | |
133 | + | |
134 | + function inBlock(style, terminator) { | |
135 | + return function(stream, state) { | |
136 | + while (!stream.eol()) { | |
137 | + if (stream.match(terminator)) { | |
138 | + state.tokenize = inText; | |
139 | + break; | |
140 | + } | |
141 | + stream.next(); | |
142 | + } | |
143 | + return style; | |
144 | + }; | |
145 | + } | |
146 | + function doctype(depth) { | |
147 | + return function(stream, state) { | |
148 | + var ch; | |
149 | + while ((ch = stream.next()) != null) { | |
150 | + if (ch == "<") { | |
151 | + state.tokenize = doctype(depth + 1); | |
152 | + return state.tokenize(stream, state); | |
153 | + } else if (ch == ">") { | |
154 | + if (depth == 1) { | |
155 | + state.tokenize = inText; | |
156 | + break; | |
157 | + } else { | |
158 | + state.tokenize = doctype(depth - 1); | |
159 | + return state.tokenize(stream, state); | |
160 | + } | |
161 | + } | |
162 | + } | |
163 | + return "meta"; | |
164 | + }; | |
165 | + } | |
166 | + | |
167 | + var curState, setStyle; | |
168 | + function pass() { | |
169 | + for (var i = arguments.length - 1; i >= 0; i--) curState.cc.push(arguments[i]); | |
170 | + } | |
171 | + function cont() { | |
172 | + pass.apply(null, arguments); | |
173 | + return true; | |
174 | + } | |
175 | + | |
176 | + function pushContext(tagName, startOfLine) { | |
177 | + var noIndent = Kludges.doNotIndent.hasOwnProperty(tagName) || (curState.context && curState.context.noIndent); | |
178 | + curState.context = { | |
179 | + prev: curState.context, | |
180 | + tagName: tagName, | |
181 | + indent: curState.indented, | |
182 | + startOfLine: startOfLine, | |
183 | + noIndent: noIndent | |
184 | + }; | |
185 | + } | |
186 | + function popContext() { | |
187 | + if (curState.context) curState.context = curState.context.prev; | |
188 | + } | |
189 | + | |
190 | + function element(type) { | |
191 | + if (type == "openTag") { | |
192 | + curState.tagName = tagName; | |
193 | + return cont(attributes, endtag(curState.startOfLine)); | |
194 | + } else if (type == "closeTag") { | |
195 | + var err = false; | |
196 | + if (curState.context) { | |
197 | + if (curState.context.tagName != tagName) { | |
198 | + if (Kludges.implicitlyClosed.hasOwnProperty(curState.context.tagName.toLowerCase())) { | |
199 | + popContext(); | |
200 | + } | |
201 | + err = !curState.context || curState.context.tagName != tagName; | |
202 | + } | |
203 | + } else { | |
204 | + err = true; | |
205 | + } | |
206 | + if (err) setStyle = "error"; | |
207 | + return cont(endclosetag(err)); | |
208 | + } | |
209 | + return cont(); | |
210 | + } | |
211 | + function endtag(startOfLine) { | |
212 | + return function(type) { | |
213 | + if (type == "selfcloseTag" || | |
214 | + (type == "endTag" && Kludges.autoSelfClosers.hasOwnProperty(curState.tagName.toLowerCase()))) { | |
215 | + maybePopContext(curState.tagName.toLowerCase()); | |
216 | + return cont(); | |
217 | + } | |
218 | + if (type == "endTag") { | |
219 | + maybePopContext(curState.tagName.toLowerCase()); | |
220 | + pushContext(curState.tagName, startOfLine); | |
221 | + return cont(); | |
222 | + } | |
223 | + return cont(); | |
224 | + }; | |
225 | + } | |
226 | + function endclosetag(err) { | |
227 | + return function(type) { | |
228 | + if (err) setStyle = "error"; | |
229 | + if (type == "endTag") { popContext(); return cont(); } | |
230 | + setStyle = "error"; | |
231 | + return cont(arguments.callee); | |
232 | + } | |
233 | + } | |
234 | + function maybePopContext(nextTagName) { | |
235 | + var parentTagName; | |
236 | + while (true) { | |
237 | + if (!curState.context) { | |
238 | + return; | |
239 | + } | |
240 | + parentTagName = curState.context.tagName.toLowerCase(); | |
241 | + if (!Kludges.contextGrabbers.hasOwnProperty(parentTagName) || | |
242 | + !Kludges.contextGrabbers[parentTagName].hasOwnProperty(nextTagName)) { | |
243 | + return; | |
244 | + } | |
245 | + popContext(); | |
246 | + } | |
247 | + } | |
248 | + | |
249 | + function attributes(type) { | |
250 | + if (type == "word") {setStyle = "attribute"; return cont(attribute, attributes);} | |
251 | + if (type == "endTag" || type == "selfcloseTag") return pass(); | |
252 | + setStyle = "error"; | |
253 | + return cont(attributes); | |
254 | + } | |
255 | + function attribute(type) { | |
256 | + if (type == "equals") return cont(attvalue, attributes); | |
257 | + if (!Kludges.allowMissing) setStyle = "error"; | |
258 | + return (type == "endTag" || type == "selfcloseTag") ? pass() : cont(); | |
259 | + } | |
260 | + function attvalue(type) { | |
261 | + if (type == "string") return cont(attvaluemaybe); | |
262 | + if (type == "word" && Kludges.allowUnquoted) {setStyle = "string"; return cont();} | |
263 | + setStyle = "error"; | |
264 | + return (type == "endTag" || type == "selfCloseTag") ? pass() : cont(); | |
265 | + } | |
266 | + function attvaluemaybe(type) { | |
267 | + if (type == "string") return cont(attvaluemaybe); | |
268 | + else return pass(); | |
269 | + } | |
270 | + | |
271 | + return { | |
272 | + startState: function() { | |
273 | + return {tokenize: inText, cc: [], indented: 0, startOfLine: true, tagName: null, context: null}; | |
274 | + }, | |
275 | + | |
276 | + token: function(stream, state) { | |
277 | + if (stream.sol()) { | |
278 | + state.startOfLine = true; | |
279 | + state.indented = stream.indentation(); | |
280 | + } | |
281 | + if (stream.eatSpace()) return null; | |
282 | + | |
283 | + setStyle = type = tagName = null; | |
284 | + var style = state.tokenize(stream, state); | |
285 | + state.type = type; | |
286 | + if ((style || type) && style != "comment") { | |
287 | + curState = state; | |
288 | + while (true) { | |
289 | + var comb = state.cc.pop() || element; | |
290 | + if (comb(type || style)) break; | |
291 | + } | |
292 | + } | |
293 | + state.startOfLine = false; | |
294 | + return setStyle || style; | |
295 | + }, | |
296 | + | |
297 | + indent: function(state, textAfter, fullLine) { | |
298 | + var context = state.context; | |
299 | + if ((state.tokenize != inTag && state.tokenize != inText) || | |
300 | + context && context.noIndent) | |
301 | + return fullLine ? fullLine.match(/^(\s*)/)[0].length : 0; | |
302 | + if (alignCDATA && /<!\[CDATA\[/.test(textAfter)) return 0; | |
303 | + if (context && /^<\//.test(textAfter)) | |
304 | + context = context.prev; | |
305 | + while (context && !context.startOfLine) | |
306 | + context = context.prev; | |
307 | + if (context) return context.indent + indentUnit; | |
308 | + else return 0; | |
309 | + }, | |
310 | + | |
311 | + compareStates: function(a, b) { | |
312 | + if (a.indented != b.indented || a.tokenize != b.tokenize) return false; | |
313 | + for (var ca = a.context, cb = b.context; ; ca = ca.prev, cb = cb.prev) { | |
314 | + if (!ca || !cb) return ca == cb; | |
315 | + if (ca.tagName != cb.tagName) return false; | |
316 | + } | |
317 | + }, | |
318 | + | |
319 | + electricChars: "/" | |
320 | + }; | |
321 | +}); | |
322 | + | |
323 | +CodeMirror.defineMIME("application/xml", "xml"); | |
324 | +if (!CodeMirror.mimeModes.hasOwnProperty("text/html")) | |
325 | + CodeMirror.defineMIME("text/html", {name: "xml", htmlMode: true}); | ... | ... |
... | ... | @@ -0,0 +1,213 @@ |
1 | + | |
2 | +CodeMirror.defineMode("scribe", function(config, parserConfig) { | |
3 | +//incluido por edmar | |
4 | +MSTAGS= ['METADATA', 'END', 'CLASS', 'FEATURE', 'JOIN', 'LABEL', 'LAYER', 'LEADER', 'LEGEND', 'MAP', 'OUTPUTFORMAT', 'PROJECTION', 'QUERYMAP', 'REFERENCE', 'SCALEBAR', 'STYLE', 'SYMBOL', 'VALIDATION', 'WEB']; | |
5 | +MSDOC = "http://mapserver.org/mapfile/"; | |
6 | +// | |
7 | + | |
8 | + var indentUnit = config.indentUnit, | |
9 | + keywords = parserConfig.keywords || {}, | |
10 | + blockKeywords = parserConfig.blockKeywords || {}, | |
11 | + multiLineStrings = parserConfig.multiLineStrings; | |
12 | + var isOperatorChar = /[+\-*&%=<>!?|\/]/; | |
13 | + | |
14 | + var curPunc; | |
15 | + | |
16 | + function tokenBase(stream, state) { | |
17 | + var ch = stream.next(); | |
18 | + if (ch == '"' || ch == "'") { | |
19 | + state.tokenize = tokenString(ch); | |
20 | + return state.tokenize(stream, state); | |
21 | + } | |
22 | + if (/[\[\]{}\(\),;\:\.]/.test(ch)) { | |
23 | + curPunc = ch; | |
24 | + return null; | |
25 | + } | |
26 | + if (/\d/.test(ch)) { | |
27 | + stream.eatWhile(/[\w\.]/); | |
28 | + return "number"; | |
29 | + } | |
30 | + if (ch == "/") { | |
31 | + if (stream.eat("*")) { | |
32 | + state.tokenize = tokenComment; | |
33 | + return tokenComment(stream, state); | |
34 | + } | |
35 | + if (stream.eat("/")) { | |
36 | + stream.skipToEnd(); | |
37 | + return "comment"; | |
38 | + } | |
39 | + } | |
40 | + /*---*/ | |
41 | + if (ch == "#") { | |
42 | + if (stream.eat("#")) { | |
43 | + stream.skipToEnd(); | |
44 | + return "comment"; | |
45 | + } | |
46 | + } | |
47 | + if (ch == "@") { | |
48 | + stream.eatWhile(/[\w\.]/); | |
49 | + return "variable"; | |
50 | + } | |
51 | + /*----*/ | |
52 | + if (isOperatorChar.test(ch)) { | |
53 | + stream.eatWhile(isOperatorChar); | |
54 | + return "operator"; | |
55 | + } | |
56 | + stream.eatWhile(/[\w\$_]/); | |
57 | + var cur = stream.current().toUpperCase(); | |
58 | + if (keywords.propertyIsEnumerable(cur)) { | |
59 | + if (blockKeywords.propertyIsEnumerable(cur)){ | |
60 | + curPunc = "newstatement"; | |
61 | + } | |
62 | + | |
63 | + if(MSTAGS != undefined && MSTAGS.indexOf(cur) >= 0){ | |
64 | + return "keyword block"; | |
65 | + } else{ | |
66 | + return "keyword"; | |
67 | + } | |
68 | + } | |
69 | + return "word"; | |
70 | + } | |
71 | + | |
72 | + function tokenString(quote) { | |
73 | + return function(stream, state) { | |
74 | + var escaped = false, next, end = false; | |
75 | + while ((next = stream.next()) != null) { | |
76 | + if (next == quote && !escaped) {end = true; break;} | |
77 | + escaped = !escaped && next == "\\"; | |
78 | + } | |
79 | + if (end || !(escaped || multiLineStrings)) | |
80 | + state.tokenize = null; | |
81 | + return "string"; | |
82 | + }; | |
83 | + } | |
84 | + | |
85 | + function tokenComment(stream, state) { | |
86 | + var maybeEnd = false, ch; | |
87 | + while (ch = stream.next()) { | |
88 | + if (ch == "/" && maybeEnd) { | |
89 | + state.tokenize = null; | |
90 | + break; | |
91 | + } | |
92 | + maybeEnd = (ch == "*"); | |
93 | + } | |
94 | + return "comment"; | |
95 | + } | |
96 | + | |
97 | + function Context(indented, column, type, align, prev) { | |
98 | + this.indented = indented; | |
99 | + this.column = column; | |
100 | + this.type = type; | |
101 | + this.align = align; | |
102 | + this.prev = prev; | |
103 | + } | |
104 | + function pushContext(state, col, type) { | |
105 | + return state.context = new Context(state.indented, col, type, null, state.context); | |
106 | + } | |
107 | + function popContext(state) { | |
108 | + var t = state.context.type; | |
109 | + if (t == ")" || t == "]" || t == "}") | |
110 | + state.indented = state.context.indented; | |
111 | + return state.context = state.context.prev; | |
112 | + } | |
113 | + | |
114 | + // Interface | |
115 | + | |
116 | + return { | |
117 | + startState: function(basecolumn) { | |
118 | + return { | |
119 | + tokenize: null, | |
120 | + context: new Context((basecolumn || 0) - indentUnit, 0, "top", false), | |
121 | + indented: 0, | |
122 | + startOfLine: true | |
123 | + }; | |
124 | + }, | |
125 | + | |
126 | + token: function(stream, state) { | |
127 | + var ctx = state.context; | |
128 | + if (stream.sol()) { | |
129 | + if (ctx.align == null) ctx.align = false; | |
130 | + state.indented = stream.indentation(); | |
131 | + state.startOfLine = true; | |
132 | + } | |
133 | + if (stream.eatSpace()) return null; | |
134 | + curPunc = null; | |
135 | + var style = (state.tokenize || tokenBase)(stream, state); | |
136 | + if (style == "comment" || style == "meta") return style; | |
137 | + if (ctx.align == null) ctx.align = true; | |
138 | + | |
139 | + if ((curPunc == ";" || curPunc == ":") && ctx.type == "statement") popContext(state); | |
140 | + else if (curPunc == "{") pushContext(state, stream.column(), "}"); | |
141 | + else if (curPunc == "[") pushContext(state, stream.column(), "]"); | |
142 | + else if (curPunc == "(") pushContext(state, stream.column(), ")"); | |
143 | + else if (curPunc == "}") { | |
144 | + while (ctx.type == "statement") ctx = popContext(state); | |
145 | + if (ctx.type == "}") ctx = popContext(state); | |
146 | + while (ctx.type == "statement") ctx = popContext(state); | |
147 | + } | |
148 | + else if (curPunc == ctx.type) popContext(state); | |
149 | + else if (ctx.type == "}" || ctx.type == "top" || (ctx.type == "statement" && curPunc == "newstatement")) | |
150 | + pushContext(state, stream.column(), "statement"); | |
151 | + state.startOfLine = false; | |
152 | + return style; | |
153 | + }, | |
154 | + | |
155 | + indent: function(state, textAfter) { | |
156 | + if (state.tokenize != tokenBase && state.tokenize != null) return 0; | |
157 | + var ctx = state.context, firstChar = textAfter && textAfter.charAt(0); | |
158 | + if (ctx.type == "statement" && firstChar == "}") ctx = ctx.prev; | |
159 | + var closing = firstChar == ctx.type; | |
160 | + if (ctx.type == "statement") return ctx.indented + (firstChar == "{" ? 0 : indentUnit); | |
161 | + else if (ctx.align) return ctx.column + (closing ? 0 : 1); | |
162 | + else return ctx.indented + (closing ? 0 : indentUnit); | |
163 | + }, | |
164 | + | |
165 | + electricChars: "{}" | |
166 | + }; | |
167 | +}); | |
168 | + | |
169 | +(function() { | |
170 | + function words(str) { | |
171 | + var obj = {}, words = str.split(" "); | |
172 | + for (var i = 0; i < words.length; ++i) obj[words[i]] = true; | |
173 | + return obj; | |
174 | + } | |
175 | + var cKeywords = "CLASS END FEATURE JOIN LABEL LAYER LEADER LEGEND MAP METADATA OUTPUTFORMAT PATTERN POINTS PROJECTION QUERYMAP REFERENCE SCALEBAR STYLE SYMBOL VALIDATION WEB \ | |
176 | + ALIGN ALPHACOLOR ANCHORPOINT ANGLE \ | |
177 | + BACKGROUNDCOLOR BUFFER \ | |
178 | + CENTER CHARACTER CLASSGROUP CLASSITEM COLOR COLORRANGE CONFIG CONNECTION CONNECTIONTYPE \ | |
179 | + DATA DATAPATTERN DATARANGE DEBUG DEFRESOLUTION DRIVER \ | |
180 | + EMPTY ENCODING ERROR EXPRESSION EXTENSION EXTENT \ | |
181 | + FILLED FILTER FILTERITEM FONT FONTSET FOOTER FORCE FORMATOPTION FROM \ | |
182 | + GAP GEOMTRANSFORM GRATICULE GRID GRIDSTEP GROUP HEADER \ | |
183 | + IMAGE IMAGECOLOR IMAGEMODE IMAGEPATH IMAGEQUALITY IMAGETYPE IMAGEURL INCLUDE INDEX INITIALGAP INTERVALS ITEMS \ | |
184 | + KEYIMAGE KEYSIZE KEYSPACING \ | |
185 | + LABELCACHE_MAP_EDGE_BUFFER LABELCACHE LABELFORMAT LABELITEM LABELMAXSCALEDENOM LABELMINSCALEDENOM LABELREQUIRES LABELSIZEITEM LATLON LINECAP LINEJOIN LINEJOINMAXSIZE LOG \ | |
186 | + MARKER MARKERSIZE MASK MAXARCS MAXBOXSIZE MAXDISTANCE MAXFEATURES MAXINTERVAL MAXLENGTH MAXOVERLAPANGLE MAXSCALE MAXSCALEDENOM MAXSIZE MAXSUBDIVIDE MAXTEMPLATE MAXWIDTH MIMETYPE \ | |
187 | + MINARCS MINBOXSIZE MINDISTANCE MINFEATURESIZE MININTERVAL MINSCALE MINSCALEDENOM MINSIZE MINSUBDIVIDE MINTEMPLATE MINWIDTH \ | |
188 | + NAME \ | |
189 | + OFFSET OFFSITE OPACITY OUTLINECOLOR OUTLINEWIDTH \ | |
190 | + PARTIALS POLAROFFSET POSITION POSTLABELCACHE PRIORITY PROCESSING \ | |
191 | + QUERYFORMAT \ | |
192 | + REPEATDISTANCE REQUIRES RESOLUTION \ | |
193 | + SCALE SHADOWCOLOR SHADOWSIZE SHAPEPATH SIZE SIZEUNITS STATUS STYLEITEM SYMBOLSCALE SYMBOLSCALEDENOM SYMBOLSET \ | |
194 | + TABLE TEMPLATE TEMPLATEPATTERN TEXT TILEINDEX TILEITEM TITLE TO TOLERANCE TOLERANCEUNITS TRANSFORM TRANSPAREN[T] TYPE \ | |
195 | + UNITS WIDTH WRAP"; | |
196 | + | |
197 | + // C#-style strings where "" escapes a quote. | |
198 | + function tokenAtString(stream, state) { | |
199 | + var next; | |
200 | + while ((next = stream.next()) != null) { | |
201 | + if (next == '"' && !stream.eat('"')) { | |
202 | + state.tokenize = null; | |
203 | + break; | |
204 | + } | |
205 | + } | |
206 | + return "string"; | |
207 | + } | |
208 | + | |
209 | + CodeMirror.defineMIME("scribe", { | |
210 | + name: "scribe", | |
211 | + keywords: words(cKeywords) | |
212 | + }); | |
213 | +}()); | ... | ... |