diff options
| author | Armand Philippot <git@armandphilippot.com> | 2021-12-30 19:47:21 +0100 |
|---|---|---|
| committer | Armand Philippot <git@armandphilippot.com> | 2021-12-30 19:47:21 +0100 |
| commit | a98b5ea6fe8e8cc98a55e0fd793e6e8660ea31c1 (patch) | |
| tree | 542810ab5aef99150db228bb54fd58303dcb31c7 /public/prism/prism-xquery.js | |
| parent | ab355897a12b7bda1089a44de326d41455a0f7a3 (diff) | |
chore: add prismjs for syntax highlighting
Diffstat (limited to 'public/prism/prism-xquery.js')
| -rw-r--r-- | public/prism/prism-xquery.js | 199 |
1 files changed, 199 insertions, 0 deletions
diff --git a/public/prism/prism-xquery.js b/public/prism/prism-xquery.js new file mode 100644 index 0000000..5b65f0c --- /dev/null +++ b/public/prism/prism-xquery.js @@ -0,0 +1,199 @@ +(function (Prism) { + Prism.languages.xquery = Prism.languages.extend('markup', { + 'xquery-comment': { + pattern: /\(:[\s\S]*?:\)/, + greedy: true, + alias: 'comment', + }, + string: { + pattern: /(["'])(?:\1\1|(?!\1)[\s\S])*\1/, + greedy: true, + }, + extension: { + pattern: /\(#.+?#\)/, + alias: 'symbol', + }, + variable: /\$[-\w:]+/, + axis: { + pattern: + /(^|[^-])(?:ancestor(?:-or-self)?|attribute|child|descendant(?:-or-self)?|following(?:-sibling)?|parent|preceding(?:-sibling)?|self)(?=::)/, + lookbehind: true, + alias: 'operator', + }, + 'keyword-operator': { + pattern: + /(^|[^:-])\b(?:and|castable as|div|eq|except|ge|gt|idiv|instance of|intersect|is|le|lt|mod|ne|or|union)\b(?=$|[^:-])/, + lookbehind: true, + alias: 'operator', + }, + keyword: { + pattern: + /(^|[^:-])\b(?:as|ascending|at|base-uri|boundary-space|case|cast as|collation|construction|copy-namespaces|declare|default|descending|else|empty (?:greatest|least)|encoding|every|external|for|function|if|import|in|inherit|lax|let|map|module|namespace|no-inherit|no-preserve|option|order(?: by|ed|ing)?|preserve|return|satisfies|schema|some|stable|strict|strip|then|to|treat as|typeswitch|unordered|validate|variable|version|where|xquery)\b(?=$|[^:-])/, + lookbehind: true, + }, + function: /[\w-]+(?::[\w-]+)*(?=\s*\()/, + 'xquery-element': { + pattern: /(element\s+)[\w-]+(?::[\w-]+)*/, + lookbehind: true, + alias: 'tag', + }, + 'xquery-attribute': { + pattern: /(attribute\s+)[\w-]+(?::[\w-]+)*/, + lookbehind: true, + alias: 'attr-name', + }, + builtin: { + pattern: + /(^|[^:-])\b(?:attribute|comment|document|element|processing-instruction|text|xs:(?:ENTITIES|ENTITY|ID|IDREFS?|NCName|NMTOKENS?|NOTATION|Name|QName|anyAtomicType|anyType|anyURI|base64Binary|boolean|byte|date|dateTime|dayTimeDuration|decimal|double|duration|float|gDay|gMonth|gMonthDay|gYear|gYearMonth|hexBinary|int|integer|language|long|negativeInteger|nonNegativeInteger|nonPositiveInteger|normalizedString|positiveInteger|short|string|time|token|unsigned(?:Byte|Int|Long|Short)|untyped(?:Atomic)?|yearMonthDuration))\b(?=$|[^:-])/, + lookbehind: true, + }, + number: /\b\d+(?:\.\d+)?(?:E[+-]?\d+)?/, + operator: [ + /[+*=?|@]|\.\.?|:=|!=|<[=<]?|>[=>]?/, + { + pattern: /(\s)-(?=\s)/, + lookbehind: true, + }, + ], + punctuation: /[[\](){},;:/]/, + }); + + Prism.languages.xquery.tag.pattern = + /<\/?(?!\d)[^\s>\/=$<%]+(?:\s+[^\s>\/=]+(?:=(?:("|')(?:\\[\s\S]|\{(?!\{)(?:\{(?:\{[^{}]*\}|[^{}])*\}|[^{}])+\}|(?!\1)[^\\])*\1|[^\s'">=]+))?)*\s*\/?>/; + Prism.languages.xquery['tag'].inside['attr-value'].pattern = + /=(?:("|')(?:\\[\s\S]|\{(?!\{)(?:\{(?:\{[^{}]*\}|[^{}])*\}|[^{}])+\}|(?!\1)[^\\])*\1|[^\s'">=]+)/; + Prism.languages.xquery['tag'].inside['attr-value'].inside['punctuation'] = + /^="|"$/; + Prism.languages.xquery['tag'].inside['attr-value'].inside['expression'] = { + // Allow for two levels of nesting + pattern: /\{(?!\{)(?:\{(?:\{[^{}]*\}|[^{}])*\}|[^{}])+\}/, + inside: Prism.languages.xquery, + alias: 'language-xquery', + }; + + // The following will handle plain text inside tags + var stringifyToken = function (token) { + if (typeof token === 'string') { + return token; + } + if (typeof token.content === 'string') { + return token.content; + } + return token.content.map(stringifyToken).join(''); + }; + + var walkTokens = function (tokens) { + var openedTags = []; + for (var i = 0; i < tokens.length; i++) { + var token = tokens[i]; + var notTagNorBrace = false; + + if (typeof token !== 'string') { + if ( + token.type === 'tag' && + token.content[0] && + token.content[0].type === 'tag' + ) { + // We found a tag, now find its kind + + if (token.content[0].content[0].content === '</') { + // Closing tag + if ( + openedTags.length > 0 && + openedTags[openedTags.length - 1].tagName === + stringifyToken(token.content[0].content[1]) + ) { + // Pop matching opening tag + openedTags.pop(); + } + } else { + if (token.content[token.content.length - 1].content === '/>') { + // Autoclosed tag, ignore + } else { + // Opening tag + openedTags.push({ + tagName: stringifyToken(token.content[0].content[1]), + openedBraces: 0, + }); + } + } + } else if ( + openedTags.length > 0 && + token.type === 'punctuation' && + token.content === '{' && + // Ignore `{{` + (!tokens[i + 1] || + tokens[i + 1].type !== 'punctuation' || + tokens[i + 1].content !== '{') && + (!tokens[i - 1] || + tokens[i - 1].type !== 'plain-text' || + tokens[i - 1].content !== '{') + ) { + // Here we might have entered an XQuery expression inside a tag + openedTags[openedTags.length - 1].openedBraces++; + } else if ( + openedTags.length > 0 && + openedTags[openedTags.length - 1].openedBraces > 0 && + token.type === 'punctuation' && + token.content === '}' + ) { + // Here we might have left an XQuery expression inside a tag + openedTags[openedTags.length - 1].openedBraces--; + } else if (token.type !== 'comment') { + notTagNorBrace = true; + } + } + if (notTagNorBrace || typeof token === 'string') { + if ( + openedTags.length > 0 && + openedTags[openedTags.length - 1].openedBraces === 0 + ) { + // Here we are inside a tag, and not inside an XQuery expression. + // That's plain text: drop any tokens matched. + var plainText = stringifyToken(token); + + // And merge text with adjacent text + if ( + i < tokens.length - 1 && + (typeof tokens[i + 1] === 'string' || + tokens[i + 1].type === 'plain-text') + ) { + plainText += stringifyToken(tokens[i + 1]); + tokens.splice(i + 1, 1); + } + if ( + i > 0 && + (typeof tokens[i - 1] === 'string' || + tokens[i - 1].type === 'plain-text') + ) { + plainText = stringifyToken(tokens[i - 1]) + plainText; + tokens.splice(i - 1, 1); + i--; + } + + if (/^\s+$/.test(plainText)) { + tokens[i] = plainText; + } else { + tokens[i] = new Prism.Token( + 'plain-text', + plainText, + null, + plainText + ); + } + } + } + + if (token.content && typeof token.content !== 'string') { + walkTokens(token.content); + } + } + }; + + Prism.hooks.add('after-tokenize', function (env) { + if (env.language !== 'xquery') { + return; + } + walkTokens(env.tokens); + }); +})(Prism); |
