source: node_modules/highlight.js/lib/languages/xml.js@ d24f17c

main
Last change on this file since d24f17c was d24f17c, checked in by Aleksandar Panovski <apano77@…>, 15 months ago

Initial commit

  • Property mode set to 100644
File size: 5.9 KB
Line 
1/**
2 * @param {string} value
3 * @returns {RegExp}
4 * */
5
6/**
7 * @param {RegExp | string } re
8 * @returns {string}
9 */
10function source(re) {
11 if (!re) return null;
12 if (typeof re === "string") return re;
13
14 return re.source;
15}
16
17/**
18 * @param {RegExp | string } re
19 * @returns {string}
20 */
21function lookahead(re) {
22 return concat('(?=', re, ')');
23}
24
25/**
26 * @param {RegExp | string } re
27 * @returns {string}
28 */
29function optional(re) {
30 return concat('(', re, ')?');
31}
32
33/**
34 * @param {...(RegExp | string) } args
35 * @returns {string}
36 */
37function concat(...args) {
38 const joined = args.map((x) => source(x)).join("");
39 return joined;
40}
41
42/**
43 * Any of the passed expresssions may match
44 *
45 * Creates a huge this | this | that | that match
46 * @param {(RegExp | string)[] } args
47 * @returns {string}
48 */
49function either(...args) {
50 const joined = '(' + args.map((x) => source(x)).join("|") + ")";
51 return joined;
52}
53
54/*
55Language: HTML, XML
56Website: https://www.w3.org/XML/
57Category: common
58Audit: 2020
59*/
60
61/** @type LanguageFn */
62function xml(hljs) {
63 // Element names can contain letters, digits, hyphens, underscores, and periods
64 const TAG_NAME_RE = concat(/[A-Z_]/, optional(/[A-Z0-9_.-]*:/), /[A-Z0-9_.-]*/);
65 const XML_IDENT_RE = /[A-Za-z0-9._:-]+/;
66 const XML_ENTITIES = {
67 className: 'symbol',
68 begin: /&[a-z]+;|&#[0-9]+;|&#x[a-f0-9]+;/
69 };
70 const XML_META_KEYWORDS = {
71 begin: /\s/,
72 contains: [
73 {
74 className: 'meta-keyword',
75 begin: /#?[a-z_][a-z1-9_-]+/,
76 illegal: /\n/
77 }
78 ]
79 };
80 const XML_META_PAR_KEYWORDS = hljs.inherit(XML_META_KEYWORDS, {
81 begin: /\(/,
82 end: /\)/
83 });
84 const APOS_META_STRING_MODE = hljs.inherit(hljs.APOS_STRING_MODE, {
85 className: 'meta-string'
86 });
87 const QUOTE_META_STRING_MODE = hljs.inherit(hljs.QUOTE_STRING_MODE, {
88 className: 'meta-string'
89 });
90 const TAG_INTERNALS = {
91 endsWithParent: true,
92 illegal: /</,
93 relevance: 0,
94 contains: [
95 {
96 className: 'attr',
97 begin: XML_IDENT_RE,
98 relevance: 0
99 },
100 {
101 begin: /=\s*/,
102 relevance: 0,
103 contains: [
104 {
105 className: 'string',
106 endsParent: true,
107 variants: [
108 {
109 begin: /"/,
110 end: /"/,
111 contains: [ XML_ENTITIES ]
112 },
113 {
114 begin: /'/,
115 end: /'/,
116 contains: [ XML_ENTITIES ]
117 },
118 {
119 begin: /[^\s"'=<>`]+/
120 }
121 ]
122 }
123 ]
124 }
125 ]
126 };
127 return {
128 name: 'HTML, XML',
129 aliases: [
130 'html',
131 'xhtml',
132 'rss',
133 'atom',
134 'xjb',
135 'xsd',
136 'xsl',
137 'plist',
138 'wsf',
139 'svg'
140 ],
141 case_insensitive: true,
142 contains: [
143 {
144 className: 'meta',
145 begin: /<![a-z]/,
146 end: />/,
147 relevance: 10,
148 contains: [
149 XML_META_KEYWORDS,
150 QUOTE_META_STRING_MODE,
151 APOS_META_STRING_MODE,
152 XML_META_PAR_KEYWORDS,
153 {
154 begin: /\[/,
155 end: /\]/,
156 contains: [
157 {
158 className: 'meta',
159 begin: /<![a-z]/,
160 end: />/,
161 contains: [
162 XML_META_KEYWORDS,
163 XML_META_PAR_KEYWORDS,
164 QUOTE_META_STRING_MODE,
165 APOS_META_STRING_MODE
166 ]
167 }
168 ]
169 }
170 ]
171 },
172 hljs.COMMENT(
173 /<!--/,
174 /-->/,
175 {
176 relevance: 10
177 }
178 ),
179 {
180 begin: /<!\[CDATA\[/,
181 end: /\]\]>/,
182 relevance: 10
183 },
184 XML_ENTITIES,
185 {
186 className: 'meta',
187 begin: /<\?xml/,
188 end: /\?>/,
189 relevance: 10
190 },
191 {
192 className: 'tag',
193 /*
194 The lookahead pattern (?=...) ensures that 'begin' only matches
195 '<style' as a single word, followed by a whitespace or an
196 ending braket. The '$' is needed for the lexeme to be recognized
197 by hljs.subMode() that tests lexemes outside the stream.
198 */
199 begin: /<style(?=\s|>)/,
200 end: />/,
201 keywords: {
202 name: 'style'
203 },
204 contains: [ TAG_INTERNALS ],
205 starts: {
206 end: /<\/style>/,
207 returnEnd: true,
208 subLanguage: [
209 'css',
210 'xml'
211 ]
212 }
213 },
214 {
215 className: 'tag',
216 // See the comment in the <style tag about the lookahead pattern
217 begin: /<script(?=\s|>)/,
218 end: />/,
219 keywords: {
220 name: 'script'
221 },
222 contains: [ TAG_INTERNALS ],
223 starts: {
224 end: /<\/script>/,
225 returnEnd: true,
226 subLanguage: [
227 'javascript',
228 'handlebars',
229 'xml'
230 ]
231 }
232 },
233 // we need this for now for jSX
234 {
235 className: 'tag',
236 begin: /<>|<\/>/
237 },
238 // open tag
239 {
240 className: 'tag',
241 begin: concat(
242 /</,
243 lookahead(concat(
244 TAG_NAME_RE,
245 // <tag/>
246 // <tag>
247 // <tag ...
248 either(/\/>/, />/, /\s/)
249 ))
250 ),
251 end: /\/?>/,
252 contains: [
253 {
254 className: 'name',
255 begin: TAG_NAME_RE,
256 relevance: 0,
257 starts: TAG_INTERNALS
258 }
259 ]
260 },
261 // close tag
262 {
263 className: 'tag',
264 begin: concat(
265 /<\//,
266 lookahead(concat(
267 TAG_NAME_RE, />/
268 ))
269 ),
270 contains: [
271 {
272 className: 'name',
273 begin: TAG_NAME_RE,
274 relevance: 0
275 },
276 {
277 begin: />/,
278 relevance: 0,
279 endsParent: true
280 }
281 ]
282 }
283 ]
284 };
285}
286
287module.exports = xml;
Note: See TracBrowser for help on using the repository browser.