/* Language: XQuery Author: Dirk Kirsten Contributor: Duncan Paterson Description: Supports XQuery 3.1 including XQuery Update 3, so also XPath (as it is a superset) Refactored to process xml constructor syntax and function-bodies. Added missing data-types, xpath operands, inbuilt functions, and query prologs Website: https://www.w3.org/XML/Query/ Category: functional Audit: 2020 */ /** @type LanguageFn */ function xquery(_hljs) { // see https://www.w3.org/TR/xquery/#id-terminal-delimitation const KEYWORDS = [ "module", "schema", "namespace", "boundary-space", "preserve", "no-preserve", "strip", "default", "collation", "base-uri", "ordering", "context", "decimal-format", "decimal-separator", "copy-namespaces", "empty-sequence", "except", "exponent-separator", "external", "grouping-separator", "inherit", "no-inherit", "lax", "minus-sign", "per-mille", "percent", "schema-attribute", "schema-element", "strict", "unordered", "zero-digit", "declare", "import", "option", "function", "validate", "variable", "for", "at", "in", "let", "where", "order", "group", "by", "return", "if", "then", "else", "tumbling", "sliding", "window", "start", "when", "only", "end", "previous", "next", "stable", "ascending", "descending", "allowing", "empty", "greatest", "least", "some", "every", "satisfies", "switch", "case", "typeswitch", "try", "catch", "and", "or", "to", "union", "intersect", "instance", "of", "treat", "as", "castable", "cast", "map", "array", "delete", "insert", "into", "replace", "value", "rename", "copy", "modify", "update" ]; // Node Types (sorted by inheritance) // atomic types (sorted by inheritance) const TYPES = [ "item", "document-node", "node", "attribute", "document", "element", "comment", "namespace", "namespace-node", "processing-instruction", "text", "construction", "xs:anyAtomicType", "xs:untypedAtomic", "xs:duration", "xs:time", "xs:decimal", "xs:float", "xs:double", "xs:gYearMonth", "xs:gYear", "xs:gMonthDay", "xs:gMonth", "xs:gDay", "xs:boolean", "xs:base64Binary", "xs:hexBinary", "xs:anyURI", "xs:QName", "xs:NOTATION", "xs:dateTime", "xs:dateTimeStamp", "xs:date", "xs:string", "xs:normalizedString", "xs:token", "xs:language", "xs:NMTOKEN", "xs:Name", "xs:NCName", "xs:ID", "xs:IDREF", "xs:ENTITY", "xs:integer", "xs:nonPositiveInteger", "xs:negativeInteger", "xs:long", "xs:int", "xs:short", "xs:byte", "xs:nonNegativeInteger", "xs:unisignedLong", "xs:unsignedInt", "xs:unsignedShort", "xs:unsignedByte", "xs:positiveInteger", "xs:yearMonthDuration", "xs:dayTimeDuration" ]; const LITERALS = [ "eq", "ne", "lt", "le", "gt", "ge", "is", "self::", "child::", "descendant::", "descendant-or-self::", "attribute::", "following::", "following-sibling::", "parent::", "ancestor::", "ancestor-or-self::", "preceding::", "preceding-sibling::", "NaN" ]; // functions (TODO: find regex for op: without breaking build) const BUILT_IN = { className: 'built_in', variants: [ { begin: /\barray:/, end: /(?:append|filter|flatten|fold-(?:left|right)|for-each(?:-pair)?|get|head|insert-before|join|put|remove|reverse|size|sort|subarray|tail)\b/ }, { begin: /\bmap:/, end: /(?:contains|entry|find|for-each|get|keys|merge|put|remove|size)\b/ }, { begin: /\bmath:/, end: /(?:a(?:cos|sin|tan[2]?)|cos|exp(?:10)?|log(?:10)?|pi|pow|sin|sqrt|tan)\b/ }, { begin: /\bop:/, end: /\(/, excludeEnd: true }, { begin: /\bfn:/, end: /\(/, excludeEnd: true }, // do not highlight inbuilt strings as variable or xml element names { begin: /[^/, end: /(\/[\w._:-]+>)/, subLanguage: 'xml', contains: [ { begin: /\{/, end: /\}/, subLanguage: 'xquery' }, 'self' ] }; const CONTAINS = [ VAR, BUILT_IN, STRING, NUMBER, COMMENT, ANNOTATION, TITLE, COMPUTED, DIRECT ]; return { name: 'XQuery', aliases: [ 'xpath', 'xq' ], case_insensitive: false, illegal: /(proc)|(abstract)|(extends)|(until)|(#)/, keywords: { $pattern: /[a-zA-Z$][a-zA-Z0-9_:-]*/, keyword: KEYWORDS, type: TYPES, literal: LITERALS }, contains: CONTAINS }; } module.exports = xquery;