288 lines
		
	
	
		
			5.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			288 lines
		
	
	
		
			5.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| /**
 | |
|  * @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;
 |