123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287 |
- /**
- * @param {string} value
- * @returns {RegExp}
- * */
- /**
- * @param {RegExp | string } re
- * @returns {string}
- */
- function source(re) {
- if (!re) return null;
- if (typeof re === "string") return re;
- return re.source;
- }
- /**
- * @param {RegExp | string } re
- * @returns {string}
- */
- function lookahead(re) {
- return concat('(?=', re, ')');
- }
- /**
- * @param {RegExp | string } re
- * @returns {string}
- */
- function optional(re) {
- return concat('(', re, ')?');
- }
- /**
- * @param {...(RegExp | string) } args
- * @returns {string}
- */
- function concat(...args) {
- const joined = args.map((x) => source(x)).join("");
- return joined;
- }
- /**
- * Any of the passed expresssions may match
- *
- * Creates a huge this | this | that | that match
- * @param {(RegExp | string)[] } args
- * @returns {string}
- */
- function either(...args) {
- const joined = '(' + args.map((x) => source(x)).join("|") + ")";
- return joined;
- }
- /*
- Language: HTML, XML
- Website: https://www.w3.org/XML/
- Category: common
- Audit: 2020
- */
- /** @type LanguageFn */
- function xml(hljs) {
- // Element names can contain letters, digits, hyphens, underscores, and periods
- const TAG_NAME_RE = concat(/[A-Z_]/, optional(/[A-Z0-9_.-]*:/), /[A-Z0-9_.-]*/);
- const XML_IDENT_RE = /[A-Za-z0-9._:-]+/;
- const XML_ENTITIES = {
- className: 'symbol',
- begin: /&[a-z]+;|&#[0-9]+;|&#x[a-f0-9]+;/
- };
- const XML_META_KEYWORDS = {
- begin: /\s/,
- contains: [
- {
- className: 'meta-keyword',
- begin: /#?[a-z_][a-z1-9_-]+/,
- illegal: /\n/
- }
- ]
- };
- const XML_META_PAR_KEYWORDS = hljs.inherit(XML_META_KEYWORDS, {
- begin: /\(/,
- end: /\)/
- });
- const APOS_META_STRING_MODE = hljs.inherit(hljs.APOS_STRING_MODE, {
- className: 'meta-string'
- });
- const QUOTE_META_STRING_MODE = hljs.inherit(hljs.QUOTE_STRING_MODE, {
- className: 'meta-string'
- });
- const TAG_INTERNALS = {
- endsWithParent: true,
- illegal: /</,
- relevance: 0,
- contains: [
- {
- className: 'attr',
- begin: XML_IDENT_RE,
- relevance: 0
- },
- {
- begin: /=\s*/,
- relevance: 0,
- contains: [
- {
- className: 'string',
- endsParent: true,
- variants: [
- {
- begin: /"/,
- end: /"/,
- contains: [ XML_ENTITIES ]
- },
- {
- begin: /'/,
- end: /'/,
- contains: [ XML_ENTITIES ]
- },
- {
- begin: /[^\s"'=<>`]+/
- }
- ]
- }
- ]
- }
- ]
- };
- return {
- name: 'HTML, XML',
- aliases: [
- 'html',
- 'xhtml',
- 'rss',
- 'atom',
- 'xjb',
- 'xsd',
- 'xsl',
- 'plist',
- 'wsf',
- 'svg'
- ],
- case_insensitive: true,
- contains: [
- {
- className: 'meta',
- begin: /<![a-z]/,
- end: />/,
- relevance: 10,
- contains: [
- XML_META_KEYWORDS,
- QUOTE_META_STRING_MODE,
- APOS_META_STRING_MODE,
- XML_META_PAR_KEYWORDS,
- {
- begin: /\[/,
- end: /\]/,
- contains: [
- {
- className: 'meta',
- begin: /<![a-z]/,
- end: />/,
- contains: [
- XML_META_KEYWORDS,
- XML_META_PAR_KEYWORDS,
- QUOTE_META_STRING_MODE,
- APOS_META_STRING_MODE
- ]
- }
- ]
- }
- ]
- },
- hljs.COMMENT(
- /<!--/,
- /-->/,
- {
- relevance: 10
- }
- ),
- {
- begin: /<!\[CDATA\[/,
- end: /\]\]>/,
- relevance: 10
- },
- XML_ENTITIES,
- {
- className: 'meta',
- begin: /<\?xml/,
- end: /\?>/,
- relevance: 10
- },
- {
- className: 'tag',
- /*
- The lookahead pattern (?=...) ensures that 'begin' only matches
- '<style' as a single word, followed by a whitespace or an
- ending braket. The '$' is needed for the lexeme to be recognized
- by hljs.subMode() that tests lexemes outside the stream.
- */
- begin: /<style(?=\s|>)/,
- end: />/,
- keywords: {
- name: 'style'
- },
- contains: [ TAG_INTERNALS ],
- starts: {
- end: /<\/style>/,
- returnEnd: true,
- subLanguage: [
- 'css',
- 'xml'
- ]
- }
- },
- {
- className: 'tag',
- // See the comment in the <style tag about the lookahead pattern
- begin: /<script(?=\s|>)/,
- end: />/,
- keywords: {
- name: 'script'
- },
- contains: [ TAG_INTERNALS ],
- starts: {
- end: /<\/script>/,
- returnEnd: true,
- subLanguage: [
- 'javascript',
- 'handlebars',
- 'xml'
- ]
- }
- },
- // we need this for now for jSX
- {
- className: 'tag',
- begin: /<>|<\/>/
- },
- // open tag
- {
- className: 'tag',
- begin: concat(
- /</,
- lookahead(concat(
- TAG_NAME_RE,
- // <tag/>
- // <tag>
- // <tag ...
- either(/\/>/, />/, /\s/)
- ))
- ),
- end: /\/?>/,
- contains: [
- {
- className: 'name',
- begin: TAG_NAME_RE,
- relevance: 0,
- starts: TAG_INTERNALS
- }
- ]
- },
- // close tag
- {
- className: 'tag',
- begin: concat(
- /<\//,
- lookahead(concat(
- TAG_NAME_RE, />/
- ))
- ),
- contains: [
- {
- className: 'name',
- begin: TAG_NAME_RE,
- relevance: 0
- },
- {
- begin: />/,
- relevance: 0,
- endsParent: true
- }
- ]
- }
- ]
- };
- }
- module.exports = xml;
|