CodeMirror.defineMode("xquery", function (){ var keywords = function (){ function kw(type){ return { type: type, style: "keyword"} ; } var A = kw("keyword a"), B = kw("keyword b"), C = kw("keyword c"), operator = kw("operator"), atom = { type: "atom", style: "atom"} , punctuation = { type: "punctuation", style: null } , qualifier = { type: "axis_specifier", style: "qualifier"} ; var kwObj = { 'if': A, 'switch': A, 'while': A, 'for': A, 'else': B, 'then': B, 'try': B, 'finally': B, 'catch': B, 'element': C, 'attribute': C, 'let': C, 'implements': C, 'import': C, 'module': C, 'namespace': C, 'return': C, 'super': C, 'this': C, 'throws': C, 'where': C, 'private': C, ',': punctuation, 'null': atom, 'fn:false()': atom, 'fn:true()': atom} ; var basic = ['after', 'ancestor', 'ancestor-or-self', 'and', 'as', 'ascending', 'assert', 'attribute', 'before', 'by', 'case', 'cast', 'child', 'comment', 'declare', 'default', 'define', 'descendant', 'descendant-or-self', 'descending', 'document', 'document-node', 'element', 'else', 'eq', 'every', 'except', 'external', 'following', 'following-sibling', 'follows', 'for', 'function', 'if', 'import', 'in', 'instance', 'intersect', 'item', 'let', 'module', 'namespace', 'node', 'node', 'of', 'only', 'or', 'order', 'parent', 'precedes', 'preceding', 'preceding-sibling', 'processing-instruction', 'ref', 'return', 'returns', 'satisfies', 'schema', 'schema-element', 'self', 'some', 'sortby', 'stable', 'text', 'then', 'to', 'treat', 'typeswitch', 'union', 'variable', 'version', 'where', 'xquery', 'empty-sequence'] ; for (var i = 0, l = _AN_Read_length('length', basic); i < l; i++ ){ kwObj[basic[i]] = kw(basic[i]); } ; var types = ['xs:string', 'xs:float', 'xs:decimal', 'xs:double', 'xs:integer', 'xs:boolean', 'xs:date', 'xs:dateTime', 'xs:time', 'xs:duration', 'xs:dayTimeDuration', 'xs:time', 'xs:yearMonthDuration', 'numeric', 'xs:hexBinary', 'xs:base64Binary', 'xs:anyURI', 'xs:QName', 'xs:byte', 'xs:boolean', 'xs:anyURI', 'xf:yearMonthDuration'] ; for (var i = 0, l = _AN_Read_length('length', types); i < l; i++ ){ kwObj[types[i]] = atom; } ; var operators = ['eq', 'ne', 'lt', 'le', 'gt', 'ge', ':=', '=', '>', '>=', '<', '<=', '.', '|', '?', 'and', 'or', 'div', 'idiv', 'mod', '*', '/', '+', '-'] ; for (var i = 0, l = _AN_Read_length('length', operators); i < l; i++ ){ kwObj[operators[i]] = operator; } ; var axis_specifiers = ["self::", "attribute::", "child::", "descendant::", "descendant-or-self::", "parent::", "ancestor::", "ancestor-or-self::", "following::", "preceding::", "following-sibling::", "preceding-sibling::"] ; for (var i = 0, l = _AN_Read_length("length", axis_specifiers); i < l; i++ ){ kwObj[axis_specifiers[i]] = qualifier; } ; return kwObj; } (); var type, content; function ret(tp, style, cont){ type = tp; content = cont; return style; } function chain(stream, state, f){ state.tokenize = f; return f(stream, state); } function tokenBase(stream, state){ var ch = stream.next(), mightBeFunction = false , isEQName = isEQNameAhead(stream); if (ch == "<") { if (stream.match("!--", true )) return chain(stream, state, tokenXMLComment); if (stream.match("![CDATA", false )) { state.tokenize = tokenCDATA; return ret("tag", "tag"); } if (stream.match("?", false )) { return chain(stream, state, tokenPreProcessing); } var isclose = stream.eat("/"); stream.eatSpace(); var tagName = "", c; while ((c = stream.eat(/[^\s\u00a0=<>\"\'\/?]/)))tagName += c; return chain(stream, state, tokenTag(tagName, isclose)); } else if (ch == "{") { pushStateStack(state, { type: "codeblock"} ); return ret("", null ); } else if (ch == "}") { popStateStack(state); return ret("", null ); } else if (isInXmlBlock(state)) { if (ch == ">") return ret("tag", "tag"); else if (ch == "/" && stream.eat(">")) { popStateStack(state); return ret("tag", "tag"); } else return ret("word", "variable"); } else if (/\d/.test(ch)) { stream.match(/^\d*(?:\.\d*)?(?:E[+\-]?\d+)?/); return ret("number", "atom"); } else if (ch === "(" && stream.eat(":")) { pushStateStack(state, { type: "comment"} ); return chain(stream, state, tokenComment); } else if (!isEQName && (ch === '"' || ch === "'")) return chain(stream, state, tokenString(ch)); else if (ch === "$") { return chain(stream, state, tokenVariable); } else if (ch === ":" && stream.eat("=")) { return ret("operator", "keyword"); } else if (ch === "(") { pushStateStack(state, { type: "paren"} ); return ret("", null ); } else if (ch === ")") { popStateStack(state); return ret("", null ); } else if (ch === "[") { pushStateStack(state, { type: "bracket"} ); return ret("", null ); } else if (ch === "]") { popStateStack(state); return ret("", null ); } else { var known = keywords.propertyIsEnumerable(ch) && keywords[ch]; if (isEQName && ch === '\"') while (stream.next() !== '"'){ } if (isEQName && ch === '\'') while (stream.next() !== '\''){ } if (!known) stream.eatWhile(/[\w\$_-]/); var foundColon = stream.eat(":"); if (!stream.eat(":") && foundColon) { stream.eatWhile(/[\w\$_-]/); } if (stream.match(/^[ \t]*\(/, false )) { mightBeFunction = true ; } var word = stream.current(); known = keywords.propertyIsEnumerable(word) && keywords[word]; if (mightBeFunction && !known) known = { type: "function_call", style: "variable def"} ; if (isInXmlConstructor(state)) { popStateStack(state); return ret("word", "variable", word); } if (word == "element" || word == "attribute" || known.type == "axis_specifier") pushStateStack(state, { type: "xmlconstructor"} ); return known? ret(known.type, known.style, word): ret("word", "variable", word); } } function tokenComment(stream, state){ var maybeEnd = false , maybeNested = false , nestedCount = 0, ch; while (ch = stream.next()){ if (ch == ")" && maybeEnd) { if (nestedCount > 0) nestedCount-- ; else { popStateStack(state); break ; } } else if (ch == ":" && maybeNested) { nestedCount++ ; } maybeEnd = (ch == ":"); maybeNested = (ch == "("); } return ret("comment", "comment"); } function tokenString(quote, f){ return function (stream, state){ var ch; if (isInString(state) && stream.current() == quote) { popStateStack(state); if (f) state.tokenize = f; return ret("string", "string"); } pushStateStack(state, { type: "string", name: quote, tokenize: tokenString(quote, f)} ); if (stream.match("{", false ) && isInXmlAttributeBlock(state)) { state.tokenize = tokenBase; return ret("string", "string"); } while (ch = stream.next()){ if (ch == quote) { popStateStack(state); if (f) state.tokenize = f; break ; } else { if (stream.match("{", false ) && isInXmlAttributeBlock(state)) { state.tokenize = tokenBase; return ret("string", "string"); } } } return ret("string", "string"); } ; } function tokenVariable(stream, state){ var isVariableChar = /[\w\$_-]/; if (stream.eat("\"")) { while (stream.next() !== '\"'){ } ; stream.eat(":"); } else { stream.eatWhile(isVariableChar); if (!stream.match(":=", false )) stream.eat(":"); } stream.eatWhile(isVariableChar); state.tokenize = tokenBase; return ret("variable", "variable"); } function tokenTag(name, isclose){ return function (stream, state){ stream.eatSpace(); if (isclose && stream.eat(">")) { popStateStack(state); state.tokenize = tokenBase; return ret("tag", "tag"); } if (!stream.eat("/")) pushStateStack(state, { type: "tag", name: name, tokenize: tokenBase} ); if (!stream.eat(">")) { state.tokenize = tokenAttribute; return ret("tag", "tag"); } else { state.tokenize = tokenBase; } return ret("tag", "tag"); } ; } function tokenAttribute(stream, state){ var ch = stream.next(); if (ch == "/" && stream.eat(">")) { if (isInXmlAttributeBlock(state)) popStateStack(state); if (isInXmlBlock(state)) popStateStack(state); return ret("tag", "tag"); } if (ch == ">") { if (isInXmlAttributeBlock(state)) popStateStack(state); return ret("tag", "tag"); } if (ch == "=") return ret("", null ); if (ch == '"' || ch == "'") return chain(stream, state, tokenString(ch, tokenAttribute)); if (!isInXmlAttributeBlock(state)) pushStateStack(state, { type: "attribute", tokenize: tokenAttribute} ); stream.eat(/[a-zA-Z_:]/); stream.eatWhile(/[-a-zA-Z0-9_:.]/); stream.eatSpace(); if (stream.match(">", false ) || stream.match("/", false )) { popStateStack(state); state.tokenize = tokenBase; } return ret("attribute", "attribute"); } function tokenXMLComment(stream, state){ var ch; while (ch = stream.next()){ if (ch == "-" && stream.match("->", true )) { state.tokenize = tokenBase; return ret("comment", "comment"); } } } function tokenCDATA(stream, state){ var ch; while (ch = stream.next()){ if (ch == "]" && stream.match("]", true )) { state.tokenize = tokenBase; return ret("comment", "comment"); } } } function tokenPreProcessing(stream, state){ var ch; while (ch = stream.next()){ if (ch == "?" && stream.match(">", true )) { state.tokenize = tokenBase; return ret("comment", "comment meta"); } } } function isInXmlBlock(state){ return isIn(state, "tag"); } function isInXmlAttributeBlock(state){ return isIn(state, "attribute"); } function isInXmlConstructor(state){ return isIn(state, "xmlconstructor"); } function isInString(state){ return isIn(state, "string"); } function isEQNameAhead(stream){ if (stream.current() === '"') return stream.match(/^[^\"]+\"\:/, false ); else if (stream.current() === '\'') return stream.match(/^[^\"]+\'\:/, false ); else return false ; } function isIn(state, type){ return (_AN_Read_length('length', state.stack) && state.stack[_AN_Read_length('length', state.stack) - 1].type == type); } function pushStateStack(state, newState){ state.stack.push(newState); } function popStateStack(state){ state.stack.pop(); var reinstateTokenize = _AN_Read_length('length', state.stack) && state.stack[_AN_Read_length('length', state.stack) - 1].tokenize; state.tokenize = reinstateTokenize || tokenBase; } return { startState: function (){ return { tokenize: tokenBase, cc: [] , stack: [] } ; } , token: function (stream, state){ if (stream.eatSpace()) return null ; var style = state.tokenize(stream, state); return style; } , blockCommentStart: "(:", blockCommentEnd: ":)"} ; } ); CodeMirror.defineMIME("application/xquery", "xquery");