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 | +}()); | ... | ... |