UNPKG

5.08 kBJavaScriptView Raw
1/*
2Language: HTML, XML
3Website: https://www.w3.org/XML/
4Category: common, web
5Audit: 2020
6*/
7
8/** @type LanguageFn */
9function xml(hljs) {
10 const regex = hljs.regex;
11 // Element names can contain letters, digits, hyphens, underscores, and periods
12 const TAG_NAME_RE = regex.concat(/[A-Z_]/, regex.optional(/[A-Z0-9_.-]*:/), /[A-Z0-9_.-]*/);
13 const XML_IDENT_RE = /[A-Za-z0-9._:-]+/;
14 const XML_ENTITIES = {
15 className: 'symbol',
16 begin: /&[a-z]+;|&#[0-9]+;|&#x[a-f0-9]+;/
17 };
18 const XML_META_KEYWORDS = {
19 begin: /\s/,
20 contains: [
21 {
22 className: 'keyword',
23 begin: /#?[a-z_][a-z1-9_-]+/,
24 illegal: /\n/
25 }
26 ]
27 };
28 const XML_META_PAR_KEYWORDS = hljs.inherit(XML_META_KEYWORDS, {
29 begin: /\(/,
30 end: /\)/
31 });
32 const APOS_META_STRING_MODE = hljs.inherit(hljs.APOS_STRING_MODE, {
33 className: 'string'
34 });
35 const QUOTE_META_STRING_MODE = hljs.inherit(hljs.QUOTE_STRING_MODE, {
36 className: 'string'
37 });
38 const TAG_INTERNALS = {
39 endsWithParent: true,
40 illegal: /</,
41 relevance: 0,
42 contains: [
43 {
44 className: 'attr',
45 begin: XML_IDENT_RE,
46 relevance: 0
47 },
48 {
49 begin: /=\s*/,
50 relevance: 0,
51 contains: [
52 {
53 className: 'string',
54 endsParent: true,
55 variants: [
56 {
57 begin: /"/,
58 end: /"/,
59 contains: [ XML_ENTITIES ]
60 },
61 {
62 begin: /'/,
63 end: /'/,
64 contains: [ XML_ENTITIES ]
65 },
66 {
67 begin: /[^\s"'=<>`]+/
68 }
69 ]
70 }
71 ]
72 }
73 ]
74 };
75 return {
76 name: 'HTML, XML',
77 aliases: [
78 'html',
79 'xhtml',
80 'rss',
81 'atom',
82 'xjb',
83 'xsd',
84 'xsl',
85 'plist',
86 'wsf',
87 'svg'
88 ],
89 case_insensitive: true,
90 contains: [
91 {
92 className: 'meta',
93 begin: /<![a-z]/,
94 end: />/,
95 relevance: 10,
96 contains: [
97 XML_META_KEYWORDS,
98 QUOTE_META_STRING_MODE,
99 APOS_META_STRING_MODE,
100 XML_META_PAR_KEYWORDS,
101 {
102 begin: /\[/,
103 end: /\]/,
104 contains: [
105 {
106 className: 'meta',
107 begin: /<![a-z]/,
108 end: />/,
109 contains: [
110 XML_META_KEYWORDS,
111 XML_META_PAR_KEYWORDS,
112 QUOTE_META_STRING_MODE,
113 APOS_META_STRING_MODE
114 ]
115 }
116 ]
117 }
118 ]
119 },
120 hljs.COMMENT(
121 /<!--/,
122 /-->/,
123 {
124 relevance: 10
125 }
126 ),
127 {
128 begin: /<!\[CDATA\[/,
129 end: /\]\]>/,
130 relevance: 10
131 },
132 XML_ENTITIES,
133 {
134 className: 'meta',
135 begin: /<\?xml/,
136 end: /\?>/,
137 relevance: 10
138 },
139 {
140 className: 'tag',
141 /*
142 The lookahead pattern (?=...) ensures that 'begin' only matches
143 '<style' as a single word, followed by a whitespace or an
144 ending bracket.
145 */
146 begin: /<style(?=\s|>)/,
147 end: />/,
148 keywords: {
149 name: 'style'
150 },
151 contains: [ TAG_INTERNALS ],
152 starts: {
153 end: /<\/style>/,
154 returnEnd: true,
155 subLanguage: [
156 'css',
157 'xml'
158 ]
159 }
160 },
161 {
162 className: 'tag',
163 // See the comment in the <style tag about the lookahead pattern
164 begin: /<script(?=\s|>)/,
165 end: />/,
166 keywords: {
167 name: 'script'
168 },
169 contains: [ TAG_INTERNALS ],
170 starts: {
171 end: /<\/script>/,
172 returnEnd: true,
173 subLanguage: [
174 'javascript',
175 'handlebars',
176 'xml'
177 ]
178 }
179 },
180 // we need this for now for jSX
181 {
182 className: 'tag',
183 begin: /<>|<\/>/
184 },
185 // open tag
186 {
187 className: 'tag',
188 begin: regex.concat(
189 /</,
190 regex.lookahead(regex.concat(
191 TAG_NAME_RE,
192 // <tag/>
193 // <tag>
194 // <tag ...
195 regex.either(/\/>/, />/, /\s/)
196 ))
197 ),
198 end: /\/?>/,
199 contains: [
200 {
201 className: 'name',
202 begin: TAG_NAME_RE,
203 relevance: 0,
204 starts: TAG_INTERNALS
205 }
206 ]
207 },
208 // close tag
209 {
210 className: 'tag',
211 begin: regex.concat(
212 /<\//,
213 regex.lookahead(regex.concat(
214 TAG_NAME_RE, />/
215 ))
216 ),
217 contains: [
218 {
219 className: 'name',
220 begin: TAG_NAME_RE,
221 relevance: 0
222 },
223 {
224 begin: />/,
225 relevance: 0,
226 endsParent: true
227 }
228 ]
229 }
230 ]
231 };
232}
233
234export { xml as default };