UNPKG

349 kBJavaScriptView Raw
1/*!
2 Highlight.js v11.7.0 (git: 82688fad18)
3 (c) 2006-2022 undefined and other contributors
4 License: BSD-3-Clause
5 */
6var hljs = (function () {
7 'use strict';
8
9 var deepFreezeEs6 = {exports: {}};
10
11 function deepFreeze(obj) {
12 if (obj instanceof Map) {
13 obj.clear = obj.delete = obj.set = function () {
14 throw new Error('map is read-only');
15 };
16 } else if (obj instanceof Set) {
17 obj.add = obj.clear = obj.delete = function () {
18 throw new Error('set is read-only');
19 };
20 }
21
22 // Freeze self
23 Object.freeze(obj);
24
25 Object.getOwnPropertyNames(obj).forEach(function (name) {
26 var prop = obj[name];
27
28 // Freeze prop if it is an object
29 if (typeof prop == 'object' && !Object.isFrozen(prop)) {
30 deepFreeze(prop);
31 }
32 });
33
34 return obj;
35 }
36
37 deepFreezeEs6.exports = deepFreeze;
38 deepFreezeEs6.exports.default = deepFreeze;
39
40 /** @typedef {import('highlight.js').CallbackResponse} CallbackResponse */
41 /** @typedef {import('highlight.js').CompiledMode} CompiledMode */
42 /** @implements CallbackResponse */
43
44 class Response {
45 /**
46 * @param {CompiledMode} mode
47 */
48 constructor(mode) {
49 // eslint-disable-next-line no-undefined
50 if (mode.data === undefined) mode.data = {};
51
52 this.data = mode.data;
53 this.isMatchIgnored = false;
54 }
55
56 ignoreMatch() {
57 this.isMatchIgnored = true;
58 }
59 }
60
61 /**
62 * @param {string} value
63 * @returns {string}
64 */
65 function escapeHTML(value) {
66 return value
67 .replace(/&/g, '&')
68 .replace(/</g, '&lt;')
69 .replace(/>/g, '&gt;')
70 .replace(/"/g, '&quot;')
71 .replace(/'/g, '&#x27;');
72 }
73
74 /**
75 * performs a shallow merge of multiple objects into one
76 *
77 * @template T
78 * @param {T} original
79 * @param {Record<string,any>[]} objects
80 * @returns {T} a single new object
81 */
82 function inherit$1(original, ...objects) {
83 /** @type Record<string,any> */
84 const result = Object.create(null);
85
86 for (const key in original) {
87 result[key] = original[key];
88 }
89 objects.forEach(function(obj) {
90 for (const key in obj) {
91 result[key] = obj[key];
92 }
93 });
94 return /** @type {T} */ (result);
95 }
96
97 /**
98 * @typedef {object} Renderer
99 * @property {(text: string) => void} addText
100 * @property {(node: Node) => void} openNode
101 * @property {(node: Node) => void} closeNode
102 * @property {() => string} value
103 */
104
105 /** @typedef {{scope?: string, language?: string, sublanguage?: boolean}} Node */
106 /** @typedef {{walk: (r: Renderer) => void}} Tree */
107 /** */
108
109 const SPAN_CLOSE = '</span>';
110
111 /**
112 * Determines if a node needs to be wrapped in <span>
113 *
114 * @param {Node} node */
115 const emitsWrappingTags = (node) => {
116 // rarely we can have a sublanguage where language is undefined
117 // TODO: track down why
118 return !!node.scope || (node.sublanguage && node.language);
119 };
120
121 /**
122 *
123 * @param {string} name
124 * @param {{prefix:string}} options
125 */
126 const scopeToCSSClass = (name, { prefix }) => {
127 if (name.includes(".")) {
128 const pieces = name.split(".");
129 return [
130 `${prefix}${pieces.shift()}`,
131 ...(pieces.map((x, i) => `${x}${"_".repeat(i + 1)}`))
132 ].join(" ");
133 }
134 return `${prefix}${name}`;
135 };
136
137 /** @type {Renderer} */
138 class HTMLRenderer {
139 /**
140 * Creates a new HTMLRenderer
141 *
142 * @param {Tree} parseTree - the parse tree (must support `walk` API)
143 * @param {{classPrefix: string}} options
144 */
145 constructor(parseTree, options) {
146 this.buffer = "";
147 this.classPrefix = options.classPrefix;
148 parseTree.walk(this);
149 }
150
151 /**
152 * Adds texts to the output stream
153 *
154 * @param {string} text */
155 addText(text) {
156 this.buffer += escapeHTML(text);
157 }
158
159 /**
160 * Adds a node open to the output stream (if needed)
161 *
162 * @param {Node} node */
163 openNode(node) {
164 if (!emitsWrappingTags(node)) return;
165
166 let className = "";
167 if (node.sublanguage) {
168 className = `language-${node.language}`;
169 } else {
170 className = scopeToCSSClass(node.scope, { prefix: this.classPrefix });
171 }
172 this.span(className);
173 }
174
175 /**
176 * Adds a node close to the output stream (if needed)
177 *
178 * @param {Node} node */
179 closeNode(node) {
180 if (!emitsWrappingTags(node)) return;
181
182 this.buffer += SPAN_CLOSE;
183 }
184
185 /**
186 * returns the accumulated buffer
187 */
188 value() {
189 return this.buffer;
190 }
191
192 // helpers
193
194 /**
195 * Builds a span element
196 *
197 * @param {string} className */
198 span(className) {
199 this.buffer += `<span class="${className}">`;
200 }
201 }
202
203 /** @typedef {{scope?: string, language?: string, sublanguage?: boolean, children: Node[]} | string} Node */
204 /** @typedef {{scope?: string, language?: string, sublanguage?: boolean, children: Node[]} } DataNode */
205 /** @typedef {import('highlight.js').Emitter} Emitter */
206 /** */
207
208 /** @returns {DataNode} */
209 const newNode = (opts = {}) => {
210 /** @type DataNode */
211 const result = { children: [] };
212 Object.assign(result, opts);
213 return result;
214 };
215
216 class TokenTree {
217 constructor() {
218 /** @type DataNode */
219 this.rootNode = newNode();
220 this.stack = [this.rootNode];
221 }
222
223 get top() {
224 return this.stack[this.stack.length - 1];
225 }
226
227 get root() { return this.rootNode; }
228
229 /** @param {Node} node */
230 add(node) {
231 this.top.children.push(node);
232 }
233
234 /** @param {string} scope */
235 openNode(scope) {
236 /** @type Node */
237 const node = newNode({ scope });
238 this.add(node);
239 this.stack.push(node);
240 }
241
242 closeNode() {
243 if (this.stack.length > 1) {
244 return this.stack.pop();
245 }
246 // eslint-disable-next-line no-undefined
247 return undefined;
248 }
249
250 closeAllNodes() {
251 while (this.closeNode());
252 }
253
254 toJSON() {
255 return JSON.stringify(this.rootNode, null, 4);
256 }
257
258 /**
259 * @typedef { import("./html_renderer").Renderer } Renderer
260 * @param {Renderer} builder
261 */
262 walk(builder) {
263 // this does not
264 return this.constructor._walk(builder, this.rootNode);
265 // this works
266 // return TokenTree._walk(builder, this.rootNode);
267 }
268
269 /**
270 * @param {Renderer} builder
271 * @param {Node} node
272 */
273 static _walk(builder, node) {
274 if (typeof node === "string") {
275 builder.addText(node);
276 } else if (node.children) {
277 builder.openNode(node);
278 node.children.forEach((child) => this._walk(builder, child));
279 builder.closeNode(node);
280 }
281 return builder;
282 }
283
284 /**
285 * @param {Node} node
286 */
287 static _collapse(node) {
288 if (typeof node === "string") return;
289 if (!node.children) return;
290
291 if (node.children.every(el => typeof el === "string")) {
292 // node.text = node.children.join("");
293 // delete node.children;
294 node.children = [node.children.join("")];
295 } else {
296 node.children.forEach((child) => {
297 TokenTree._collapse(child);
298 });
299 }
300 }
301 }
302
303 /**
304 Currently this is all private API, but this is the minimal API necessary
305 that an Emitter must implement to fully support the parser.
306
307 Minimal interface:
308
309 - addKeyword(text, scope)
310 - addText(text)
311 - addSublanguage(emitter, subLanguageName)
312 - finalize()
313 - openNode(scope)
314 - closeNode()
315 - closeAllNodes()
316 - toHTML()
317
318 */
319
320 /**
321 * @implements {Emitter}
322 */
323 class TokenTreeEmitter extends TokenTree {
324 /**
325 * @param {*} options
326 */
327 constructor(options) {
328 super();
329 this.options = options;
330 }
331
332 /**
333 * @param {string} text
334 * @param {string} scope
335 */
336 addKeyword(text, scope) {
337 if (text === "") { return; }
338
339 this.openNode(scope);
340 this.addText(text);
341 this.closeNode();
342 }
343
344 /**
345 * @param {string} text
346 */
347 addText(text) {
348 if (text === "") { return; }
349
350 this.add(text);
351 }
352
353 /**
354 * @param {Emitter & {root: DataNode}} emitter
355 * @param {string} name
356 */
357 addSublanguage(emitter, name) {
358 /** @type DataNode */
359 const node = emitter.root;
360 node.sublanguage = true;
361 node.language = name;
362 this.add(node);
363 }
364
365 toHTML() {
366 const renderer = new HTMLRenderer(this, this.options);
367 return renderer.value();
368 }
369
370 finalize() {
371 return true;
372 }
373 }
374
375 /**
376 * @param {string} value
377 * @returns {RegExp}
378 * */
379
380 /**
381 * @param {RegExp | string } re
382 * @returns {string}
383 */
384 function source(re) {
385 if (!re) return null;
386 if (typeof re === "string") return re;
387
388 return re.source;
389 }
390
391 /**
392 * @param {RegExp | string } re
393 * @returns {string}
394 */
395 function lookahead(re) {
396 return concat('(?=', re, ')');
397 }
398
399 /**
400 * @param {RegExp | string } re
401 * @returns {string}
402 */
403 function anyNumberOfTimes(re) {
404 return concat('(?:', re, ')*');
405 }
406
407 /**
408 * @param {RegExp | string } re
409 * @returns {string}
410 */
411 function optional(re) {
412 return concat('(?:', re, ')?');
413 }
414
415 /**
416 * @param {...(RegExp | string) } args
417 * @returns {string}
418 */
419 function concat(...args) {
420 const joined = args.map((x) => source(x)).join("");
421 return joined;
422 }
423
424 /**
425 * @param { Array<string | RegExp | Object> } args
426 * @returns {object}
427 */
428 function stripOptionsFromArgs(args) {
429 const opts = args[args.length - 1];
430
431 if (typeof opts === 'object' && opts.constructor === Object) {
432 args.splice(args.length - 1, 1);
433 return opts;
434 } else {
435 return {};
436 }
437 }
438
439 /** @typedef { {capture?: boolean} } RegexEitherOptions */
440
441 /**
442 * Any of the passed expresssions may match
443 *
444 * Creates a huge this | this | that | that match
445 * @param {(RegExp | string)[] | [...(RegExp | string)[], RegexEitherOptions]} args
446 * @returns {string}
447 */
448 function either(...args) {
449 /** @type { object & {capture?: boolean} } */
450 const opts = stripOptionsFromArgs(args);
451 const joined = '('
452 + (opts.capture ? "" : "?:")
453 + args.map((x) => source(x)).join("|") + ")";
454 return joined;
455 }
456
457 /**
458 * @param {RegExp | string} re
459 * @returns {number}
460 */
461 function countMatchGroups(re) {
462 return (new RegExp(re.toString() + '|')).exec('').length - 1;
463 }
464
465 /**
466 * Does lexeme start with a regular expression match at the beginning
467 * @param {RegExp} re
468 * @param {string} lexeme
469 */
470 function startsWith(re, lexeme) {
471 const match = re && re.exec(lexeme);
472 return match && match.index === 0;
473 }
474
475 // BACKREF_RE matches an open parenthesis or backreference. To avoid
476 // an incorrect parse, it additionally matches the following:
477 // - [...] elements, where the meaning of parentheses and escapes change
478 // - other escape sequences, so we do not misparse escape sequences as
479 // interesting elements
480 // - non-matching or lookahead parentheses, which do not capture. These
481 // follow the '(' with a '?'.
482 const BACKREF_RE = /\[(?:[^\\\]]|\\.)*\]|\(\??|\\([1-9][0-9]*)|\\./;
483
484 // **INTERNAL** Not intended for outside usage
485 // join logically computes regexps.join(separator), but fixes the
486 // backreferences so they continue to match.
487 // it also places each individual regular expression into it's own
488 // match group, keeping track of the sequencing of those match groups
489 // is currently an exercise for the caller. :-)
490 /**
491 * @param {(string | RegExp)[]} regexps
492 * @param {{joinWith: string}} opts
493 * @returns {string}
494 */
495 function _rewriteBackreferences(regexps, { joinWith }) {
496 let numCaptures = 0;
497
498 return regexps.map((regex) => {
499 numCaptures += 1;
500 const offset = numCaptures;
501 let re = source(regex);
502 let out = '';
503
504 while (re.length > 0) {
505 const match = BACKREF_RE.exec(re);
506 if (!match) {
507 out += re;
508 break;
509 }
510 out += re.substring(0, match.index);
511 re = re.substring(match.index + match[0].length);
512 if (match[0][0] === '\\' && match[1]) {
513 // Adjust the backreference.
514 out += '\\' + String(Number(match[1]) + offset);
515 } else {
516 out += match[0];
517 if (match[0] === '(') {
518 numCaptures++;
519 }
520 }
521 }
522 return out;
523 }).map(re => `(${re})`).join(joinWith);
524 }
525
526 /** @typedef {import('highlight.js').Mode} Mode */
527 /** @typedef {import('highlight.js').ModeCallback} ModeCallback */
528
529 // Common regexps
530 const MATCH_NOTHING_RE = /\b\B/;
531 const IDENT_RE$1 = '[a-zA-Z]\\w*';
532 const UNDERSCORE_IDENT_RE = '[a-zA-Z_]\\w*';
533 const NUMBER_RE = '\\b\\d+(\\.\\d+)?';
534 const C_NUMBER_RE = '(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)'; // 0x..., 0..., decimal, float
535 const BINARY_NUMBER_RE = '\\b(0b[01]+)'; // 0b...
536 const RE_STARTERS_RE = '!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~';
537
538 /**
539 * @param { Partial<Mode> & {binary?: string | RegExp} } opts
540 */
541 const SHEBANG = (opts = {}) => {
542 const beginShebang = /^#![ ]*\//;
543 if (opts.binary) {
544 opts.begin = concat(
545 beginShebang,
546 /.*\b/,
547 opts.binary,
548 /\b.*/);
549 }
550 return inherit$1({
551 scope: 'meta',
552 begin: beginShebang,
553 end: /$/,
554 relevance: 0,
555 /** @type {ModeCallback} */
556 "on:begin": (m, resp) => {
557 if (m.index !== 0) resp.ignoreMatch();
558 }
559 }, opts);
560 };
561
562 // Common modes
563 const BACKSLASH_ESCAPE = {
564 begin: '\\\\[\\s\\S]', relevance: 0
565 };
566 const APOS_STRING_MODE = {
567 scope: 'string',
568 begin: '\'',
569 end: '\'',
570 illegal: '\\n',
571 contains: [BACKSLASH_ESCAPE]
572 };
573 const QUOTE_STRING_MODE = {
574 scope: 'string',
575 begin: '"',
576 end: '"',
577 illegal: '\\n',
578 contains: [BACKSLASH_ESCAPE]
579 };
580 const PHRASAL_WORDS_MODE = {
581 begin: /\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\b/
582 };
583 /**
584 * Creates a comment mode
585 *
586 * @param {string | RegExp} begin
587 * @param {string | RegExp} end
588 * @param {Mode | {}} [modeOptions]
589 * @returns {Partial<Mode>}
590 */
591 const COMMENT = function(begin, end, modeOptions = {}) {
592 const mode = inherit$1(
593 {
594 scope: 'comment',
595 begin,
596 end,
597 contains: []
598 },
599 modeOptions
600 );
601 mode.contains.push({
602 scope: 'doctag',
603 // hack to avoid the space from being included. the space is necessary to
604 // match here to prevent the plain text rule below from gobbling up doctags
605 begin: '[ ]*(?=(TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):)',
606 end: /(TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):/,
607 excludeBegin: true,
608 relevance: 0
609 });
610 const ENGLISH_WORD = either(
611 // list of common 1 and 2 letter words in English
612 "I",
613 "a",
614 "is",
615 "so",
616 "us",
617 "to",
618 "at",
619 "if",
620 "in",
621 "it",
622 "on",
623 // note: this is not an exhaustive list of contractions, just popular ones
624 /[A-Za-z]+['](d|ve|re|ll|t|s|n)/, // contractions - can't we'd they're let's, etc
625 /[A-Za-z]+[-][a-z]+/, // `no-way`, etc.
626 /[A-Za-z][a-z]{2,}/ // allow capitalized words at beginning of sentences
627 );
628 // looking like plain text, more likely to be a comment
629 mode.contains.push(
630 {
631 // TODO: how to include ", (, ) without breaking grammars that use these for
632 // comment delimiters?
633 // begin: /[ ]+([()"]?([A-Za-z'-]{3,}|is|a|I|so|us|[tT][oO]|at|if|in|it|on)[.]?[()":]?([.][ ]|[ ]|\))){3}/
634 // ---
635
636 // this tries to find sequences of 3 english words in a row (without any
637 // "programming" type syntax) this gives us a strong signal that we've
638 // TRULY found a comment - vs perhaps scanning with the wrong language.
639 // It's possible to find something that LOOKS like the start of the
640 // comment - but then if there is no readable text - good chance it is a
641 // false match and not a comment.
642 //
643 // for a visual example please see:
644 // https://github.com/highlightjs/highlight.js/issues/2827
645
646 begin: concat(
647 /[ ]+/, // necessary to prevent us gobbling up doctags like /* @author Bob Mcgill */
648 '(',
649 ENGLISH_WORD,
650 /[.]?[:]?([.][ ]|[ ])/,
651 '){3}') // look for 3 words in a row
652 }
653 );
654 return mode;
655 };
656 const C_LINE_COMMENT_MODE = COMMENT('//', '$');
657 const C_BLOCK_COMMENT_MODE = COMMENT('/\\*', '\\*/');
658 const HASH_COMMENT_MODE = COMMENT('#', '$');
659 const NUMBER_MODE = {
660 scope: 'number',
661 begin: NUMBER_RE,
662 relevance: 0
663 };
664 const C_NUMBER_MODE = {
665 scope: 'number',
666 begin: C_NUMBER_RE,
667 relevance: 0
668 };
669 const BINARY_NUMBER_MODE = {
670 scope: 'number',
671 begin: BINARY_NUMBER_RE,
672 relevance: 0
673 };
674 const REGEXP_MODE = {
675 // this outer rule makes sure we actually have a WHOLE regex and not simply
676 // an expression such as:
677 //
678 // 3 / something
679 //
680 // (which will then blow up when regex's `illegal` sees the newline)
681 begin: /(?=\/[^/\n]*\/)/,
682 contains: [{
683 scope: 'regexp',
684 begin: /\//,
685 end: /\/[gimuy]*/,
686 illegal: /\n/,
687 contains: [
688 BACKSLASH_ESCAPE,
689 {
690 begin: /\[/,
691 end: /\]/,
692 relevance: 0,
693 contains: [BACKSLASH_ESCAPE]
694 }
695 ]
696 }]
697 };
698 const TITLE_MODE = {
699 scope: 'title',
700 begin: IDENT_RE$1,
701 relevance: 0
702 };
703 const UNDERSCORE_TITLE_MODE = {
704 scope: 'title',
705 begin: UNDERSCORE_IDENT_RE,
706 relevance: 0
707 };
708 const METHOD_GUARD = {
709 // excludes method names from keyword processing
710 begin: '\\.\\s*' + UNDERSCORE_IDENT_RE,
711 relevance: 0
712 };
713
714 /**
715 * Adds end same as begin mechanics to a mode
716 *
717 * Your mode must include at least a single () match group as that first match
718 * group is what is used for comparison
719 * @param {Partial<Mode>} mode
720 */
721 const END_SAME_AS_BEGIN = function(mode) {
722 return Object.assign(mode,
723 {
724 /** @type {ModeCallback} */
725 'on:begin': (m, resp) => { resp.data._beginMatch = m[1]; },
726 /** @type {ModeCallback} */
727 'on:end': (m, resp) => { if (resp.data._beginMatch !== m[1]) resp.ignoreMatch(); }
728 });
729 };
730
731 var MODES$1 = /*#__PURE__*/Object.freeze({
732 __proto__: null,
733 MATCH_NOTHING_RE: MATCH_NOTHING_RE,
734 IDENT_RE: IDENT_RE$1,
735 UNDERSCORE_IDENT_RE: UNDERSCORE_IDENT_RE,
736 NUMBER_RE: NUMBER_RE,
737 C_NUMBER_RE: C_NUMBER_RE,
738 BINARY_NUMBER_RE: BINARY_NUMBER_RE,
739 RE_STARTERS_RE: RE_STARTERS_RE,
740 SHEBANG: SHEBANG,
741 BACKSLASH_ESCAPE: BACKSLASH_ESCAPE,
742 APOS_STRING_MODE: APOS_STRING_MODE,
743 QUOTE_STRING_MODE: QUOTE_STRING_MODE,
744 PHRASAL_WORDS_MODE: PHRASAL_WORDS_MODE,
745 COMMENT: COMMENT,
746 C_LINE_COMMENT_MODE: C_LINE_COMMENT_MODE,
747 C_BLOCK_COMMENT_MODE: C_BLOCK_COMMENT_MODE,
748 HASH_COMMENT_MODE: HASH_COMMENT_MODE,
749 NUMBER_MODE: NUMBER_MODE,
750 C_NUMBER_MODE: C_NUMBER_MODE,
751 BINARY_NUMBER_MODE: BINARY_NUMBER_MODE,
752 REGEXP_MODE: REGEXP_MODE,
753 TITLE_MODE: TITLE_MODE,
754 UNDERSCORE_TITLE_MODE: UNDERSCORE_TITLE_MODE,
755 METHOD_GUARD: METHOD_GUARD,
756 END_SAME_AS_BEGIN: END_SAME_AS_BEGIN
757 });
758
759 /**
760 @typedef {import('highlight.js').CallbackResponse} CallbackResponse
761 @typedef {import('highlight.js').CompilerExt} CompilerExt
762 */
763
764 // Grammar extensions / plugins
765 // See: https://github.com/highlightjs/highlight.js/issues/2833
766
767 // Grammar extensions allow "syntactic sugar" to be added to the grammar modes
768 // without requiring any underlying changes to the compiler internals.
769
770 // `compileMatch` being the perfect small example of now allowing a grammar
771 // author to write `match` when they desire to match a single expression rather
772 // than being forced to use `begin`. The extension then just moves `match` into
773 // `begin` when it runs. Ie, no features have been added, but we've just made
774 // the experience of writing (and reading grammars) a little bit nicer.
775
776 // ------
777
778 // TODO: We need negative look-behind support to do this properly
779 /**
780 * Skip a match if it has a preceding dot
781 *
782 * This is used for `beginKeywords` to prevent matching expressions such as
783 * `bob.keyword.do()`. The mode compiler automatically wires this up as a
784 * special _internal_ 'on:begin' callback for modes with `beginKeywords`
785 * @param {RegExpMatchArray} match
786 * @param {CallbackResponse} response
787 */
788 function skipIfHasPrecedingDot(match, response) {
789 const before = match.input[match.index - 1];
790 if (before === ".") {
791 response.ignoreMatch();
792 }
793 }
794
795 /**
796 *
797 * @type {CompilerExt}
798 */
799 function scopeClassName(mode, _parent) {
800 // eslint-disable-next-line no-undefined
801 if (mode.className !== undefined) {
802 mode.scope = mode.className;
803 delete mode.className;
804 }
805 }
806
807 /**
808 * `beginKeywords` syntactic sugar
809 * @type {CompilerExt}
810 */
811 function beginKeywords(mode, parent) {
812 if (!parent) return;
813 if (!mode.beginKeywords) return;
814
815 // for languages with keywords that include non-word characters checking for
816 // a word boundary is not sufficient, so instead we check for a word boundary
817 // or whitespace - this does no harm in any case since our keyword engine
818 // doesn't allow spaces in keywords anyways and we still check for the boundary
819 // first
820 mode.begin = '\\b(' + mode.beginKeywords.split(' ').join('|') + ')(?!\\.)(?=\\b|\\s)';
821 mode.__beforeBegin = skipIfHasPrecedingDot;
822 mode.keywords = mode.keywords || mode.beginKeywords;
823 delete mode.beginKeywords;
824
825 // prevents double relevance, the keywords themselves provide
826 // relevance, the mode doesn't need to double it
827 // eslint-disable-next-line no-undefined
828 if (mode.relevance === undefined) mode.relevance = 0;
829 }
830
831 /**
832 * Allow `illegal` to contain an array of illegal values
833 * @type {CompilerExt}
834 */
835 function compileIllegal(mode, _parent) {
836 if (!Array.isArray(mode.illegal)) return;
837
838 mode.illegal = either(...mode.illegal);
839 }
840
841 /**
842 * `match` to match a single expression for readability
843 * @type {CompilerExt}
844 */
845 function compileMatch(mode, _parent) {
846 if (!mode.match) return;
847 if (mode.begin || mode.end) throw new Error("begin & end are not supported with match");
848
849 mode.begin = mode.match;
850 delete mode.match;
851 }
852
853 /**
854 * provides the default 1 relevance to all modes
855 * @type {CompilerExt}
856 */
857 function compileRelevance(mode, _parent) {
858 // eslint-disable-next-line no-undefined
859 if (mode.relevance === undefined) mode.relevance = 1;
860 }
861
862 // allow beforeMatch to act as a "qualifier" for the match
863 // the full match begin must be [beforeMatch][begin]
864 const beforeMatchExt = (mode, parent) => {
865 if (!mode.beforeMatch) return;
866 // starts conflicts with endsParent which we need to make sure the child
867 // rule is not matched multiple times
868 if (mode.starts) throw new Error("beforeMatch cannot be used with starts");
869
870 const originalMode = Object.assign({}, mode);
871 Object.keys(mode).forEach((key) => { delete mode[key]; });
872
873 mode.keywords = originalMode.keywords;
874 mode.begin = concat(originalMode.beforeMatch, lookahead(originalMode.begin));
875 mode.starts = {
876 relevance: 0,
877 contains: [
878 Object.assign(originalMode, { endsParent: true })
879 ]
880 };
881 mode.relevance = 0;
882
883 delete originalMode.beforeMatch;
884 };
885
886 // keywords that should have no default relevance value
887 const COMMON_KEYWORDS = [
888 'of',
889 'and',
890 'for',
891 'in',
892 'not',
893 'or',
894 'if',
895 'then',
896 'parent', // common variable name
897 'list', // common variable name
898 'value' // common variable name
899 ];
900
901 const DEFAULT_KEYWORD_SCOPE = "keyword";
902
903 /**
904 * Given raw keywords from a language definition, compile them.
905 *
906 * @param {string | Record<string,string|string[]> | Array<string>} rawKeywords
907 * @param {boolean} caseInsensitive
908 */
909 function compileKeywords(rawKeywords, caseInsensitive, scopeName = DEFAULT_KEYWORD_SCOPE) {
910 /** @type {import("highlight.js/private").KeywordDict} */
911 const compiledKeywords = Object.create(null);
912
913 // input can be a string of keywords, an array of keywords, or a object with
914 // named keys representing scopeName (which can then point to a string or array)
915 if (typeof rawKeywords === 'string') {
916 compileList(scopeName, rawKeywords.split(" "));
917 } else if (Array.isArray(rawKeywords)) {
918 compileList(scopeName, rawKeywords);
919 } else {
920 Object.keys(rawKeywords).forEach(function(scopeName) {
921 // collapse all our objects back into the parent object
922 Object.assign(
923 compiledKeywords,
924 compileKeywords(rawKeywords[scopeName], caseInsensitive, scopeName)
925 );
926 });
927 }
928 return compiledKeywords;
929
930 // ---
931
932 /**
933 * Compiles an individual list of keywords
934 *
935 * Ex: "for if when while|5"
936 *
937 * @param {string} scopeName
938 * @param {Array<string>} keywordList
939 */
940 function compileList(scopeName, keywordList) {
941 if (caseInsensitive) {
942 keywordList = keywordList.map(x => x.toLowerCase());
943 }
944 keywordList.forEach(function(keyword) {
945 const pair = keyword.split('|');
946 compiledKeywords[pair[0]] = [scopeName, scoreForKeyword(pair[0], pair[1])];
947 });
948 }
949 }
950
951 /**
952 * Returns the proper score for a given keyword
953 *
954 * Also takes into account comment keywords, which will be scored 0 UNLESS
955 * another score has been manually assigned.
956 * @param {string} keyword
957 * @param {string} [providedScore]
958 */
959 function scoreForKeyword(keyword, providedScore) {
960 // manual scores always win over common keywords
961 // so you can force a score of 1 if you really insist
962 if (providedScore) {
963 return Number(providedScore);
964 }
965
966 return commonKeyword(keyword) ? 0 : 1;
967 }
968
969 /**
970 * Determines if a given keyword is common or not
971 *
972 * @param {string} keyword */
973 function commonKeyword(keyword) {
974 return COMMON_KEYWORDS.includes(keyword.toLowerCase());
975 }
976
977 /*
978
979 For the reasoning behind this please see:
980 https://github.com/highlightjs/highlight.js/issues/2880#issuecomment-747275419
981
982 */
983
984 /**
985 * @type {Record<string, boolean>}
986 */
987 const seenDeprecations = {};
988
989 /**
990 * @param {string} message
991 */
992 const error = (message) => {
993 console.error(message);
994 };
995
996 /**
997 * @param {string} message
998 * @param {any} args
999 */
1000 const warn = (message, ...args) => {
1001 console.log(`WARN: ${message}`, ...args);
1002 };
1003
1004 /**
1005 * @param {string} version
1006 * @param {string} message
1007 */
1008 const deprecated = (version, message) => {
1009 if (seenDeprecations[`${version}/${message}`]) return;
1010
1011 console.log(`Deprecated as of ${version}. ${message}`);
1012 seenDeprecations[`${version}/${message}`] = true;
1013 };
1014
1015 /* eslint-disable no-throw-literal */
1016
1017 /**
1018 @typedef {import('highlight.js').CompiledMode} CompiledMode
1019 */
1020
1021 const MultiClassError = new Error();
1022
1023 /**
1024 * Renumbers labeled scope names to account for additional inner match
1025 * groups that otherwise would break everything.
1026 *
1027 * Lets say we 3 match scopes:
1028 *
1029 * { 1 => ..., 2 => ..., 3 => ... }
1030 *
1031 * So what we need is a clean match like this:
1032 *
1033 * (a)(b)(c) => [ "a", "b", "c" ]
1034 *
1035 * But this falls apart with inner match groups:
1036 *
1037 * (a)(((b)))(c) => ["a", "b", "b", "b", "c" ]
1038 *
1039 * Our scopes are now "out of alignment" and we're repeating `b` 3 times.
1040 * What needs to happen is the numbers are remapped:
1041 *
1042 * { 1 => ..., 2 => ..., 5 => ... }
1043 *
1044 * We also need to know that the ONLY groups that should be output
1045 * are 1, 2, and 5. This function handles this behavior.
1046 *
1047 * @param {CompiledMode} mode
1048 * @param {Array<RegExp | string>} regexes
1049 * @param {{key: "beginScope"|"endScope"}} opts
1050 */
1051 function remapScopeNames(mode, regexes, { key }) {
1052 let offset = 0;
1053 const scopeNames = mode[key];
1054 /** @type Record<number,boolean> */
1055 const emit = {};
1056 /** @type Record<number,string> */
1057 const positions = {};
1058
1059 for (let i = 1; i <= regexes.length; i++) {
1060 positions[i + offset] = scopeNames[i];
1061 emit[i + offset] = true;
1062 offset += countMatchGroups(regexes[i - 1]);
1063 }
1064 // we use _emit to keep track of which match groups are "top-level" to avoid double
1065 // output from inside match groups
1066 mode[key] = positions;
1067 mode[key]._emit = emit;
1068 mode[key]._multi = true;
1069 }
1070
1071 /**
1072 * @param {CompiledMode} mode
1073 */
1074 function beginMultiClass(mode) {
1075 if (!Array.isArray(mode.begin)) return;
1076
1077 if (mode.skip || mode.excludeBegin || mode.returnBegin) {
1078 error("skip, excludeBegin, returnBegin not compatible with beginScope: {}");
1079 throw MultiClassError;
1080 }
1081
1082 if (typeof mode.beginScope !== "object" || mode.beginScope === null) {
1083 error("beginScope must be object");
1084 throw MultiClassError;
1085 }
1086
1087 remapScopeNames(mode, mode.begin, { key: "beginScope" });
1088 mode.begin = _rewriteBackreferences(mode.begin, { joinWith: "" });
1089 }
1090
1091 /**
1092 * @param {CompiledMode} mode
1093 */
1094 function endMultiClass(mode) {
1095 if (!Array.isArray(mode.end)) return;
1096
1097 if (mode.skip || mode.excludeEnd || mode.returnEnd) {
1098 error("skip, excludeEnd, returnEnd not compatible with endScope: {}");
1099 throw MultiClassError;
1100 }
1101
1102 if (typeof mode.endScope !== "object" || mode.endScope === null) {
1103 error("endScope must be object");
1104 throw MultiClassError;
1105 }
1106
1107 remapScopeNames(mode, mode.end, { key: "endScope" });
1108 mode.end = _rewriteBackreferences(mode.end, { joinWith: "" });
1109 }
1110
1111 /**
1112 * this exists only to allow `scope: {}` to be used beside `match:`
1113 * Otherwise `beginScope` would necessary and that would look weird
1114
1115 {
1116 match: [ /def/, /\w+/ ]
1117 scope: { 1: "keyword" , 2: "title" }
1118 }
1119
1120 * @param {CompiledMode} mode
1121 */
1122 function scopeSugar(mode) {
1123 if (mode.scope && typeof mode.scope === "object" && mode.scope !== null) {
1124 mode.beginScope = mode.scope;
1125 delete mode.scope;
1126 }
1127 }
1128
1129 /**
1130 * @param {CompiledMode} mode
1131 */
1132 function MultiClass(mode) {
1133 scopeSugar(mode);
1134
1135 if (typeof mode.beginScope === "string") {
1136 mode.beginScope = { _wrap: mode.beginScope };
1137 }
1138 if (typeof mode.endScope === "string") {
1139 mode.endScope = { _wrap: mode.endScope };
1140 }
1141
1142 beginMultiClass(mode);
1143 endMultiClass(mode);
1144 }
1145
1146 /**
1147 @typedef {import('highlight.js').Mode} Mode
1148 @typedef {import('highlight.js').CompiledMode} CompiledMode
1149 @typedef {import('highlight.js').Language} Language
1150 @typedef {import('highlight.js').HLJSPlugin} HLJSPlugin
1151 @typedef {import('highlight.js').CompiledLanguage} CompiledLanguage
1152 */
1153
1154 // compilation
1155
1156 /**
1157 * Compiles a language definition result
1158 *
1159 * Given the raw result of a language definition (Language), compiles this so
1160 * that it is ready for highlighting code.
1161 * @param {Language} language
1162 * @returns {CompiledLanguage}
1163 */
1164 function compileLanguage(language) {
1165 /**
1166 * Builds a regex with the case sensitivity of the current language
1167 *
1168 * @param {RegExp | string} value
1169 * @param {boolean} [global]
1170 */
1171 function langRe(value, global) {
1172 return new RegExp(
1173 source(value),
1174 'm'
1175 + (language.case_insensitive ? 'i' : '')
1176 + (language.unicodeRegex ? 'u' : '')
1177 + (global ? 'g' : '')
1178 );
1179 }
1180
1181 /**
1182 Stores multiple regular expressions and allows you to quickly search for
1183 them all in a string simultaneously - returning the first match. It does
1184 this by creating a huge (a|b|c) regex - each individual item wrapped with ()
1185 and joined by `|` - using match groups to track position. When a match is
1186 found checking which position in the array has content allows us to figure
1187 out which of the original regexes / match groups triggered the match.
1188
1189 The match object itself (the result of `Regex.exec`) is returned but also
1190 enhanced by merging in any meta-data that was registered with the regex.
1191 This is how we keep track of which mode matched, and what type of rule
1192 (`illegal`, `begin`, end, etc).
1193 */
1194 class MultiRegex {
1195 constructor() {
1196 this.matchIndexes = {};
1197 // @ts-ignore
1198 this.regexes = [];
1199 this.matchAt = 1;
1200 this.position = 0;
1201 }
1202
1203 // @ts-ignore
1204 addRule(re, opts) {
1205 opts.position = this.position++;
1206 // @ts-ignore
1207 this.matchIndexes[this.matchAt] = opts;
1208 this.regexes.push([opts, re]);
1209 this.matchAt += countMatchGroups(re) + 1;
1210 }
1211
1212 compile() {
1213 if (this.regexes.length === 0) {
1214 // avoids the need to check length every time exec is called
1215 // @ts-ignore
1216 this.exec = () => null;
1217 }
1218 const terminators = this.regexes.map(el => el[1]);
1219 this.matcherRe = langRe(_rewriteBackreferences(terminators, { joinWith: '|' }), true);
1220 this.lastIndex = 0;
1221 }
1222
1223 /** @param {string} s */
1224 exec(s) {
1225 this.matcherRe.lastIndex = this.lastIndex;
1226 const match = this.matcherRe.exec(s);
1227 if (!match) { return null; }
1228
1229 // eslint-disable-next-line no-undefined
1230 const i = match.findIndex((el, i) => i > 0 && el !== undefined);
1231 // @ts-ignore
1232 const matchData = this.matchIndexes[i];
1233 // trim off any earlier non-relevant match groups (ie, the other regex
1234 // match groups that make up the multi-matcher)
1235 match.splice(0, i);
1236
1237 return Object.assign(match, matchData);
1238 }
1239 }
1240
1241 /*
1242 Created to solve the key deficiently with MultiRegex - there is no way to
1243 test for multiple matches at a single location. Why would we need to do
1244 that? In the future a more dynamic engine will allow certain matches to be
1245 ignored. An example: if we matched say the 3rd regex in a large group but
1246 decided to ignore it - we'd need to started testing again at the 4th
1247 regex... but MultiRegex itself gives us no real way to do that.
1248
1249 So what this class creates MultiRegexs on the fly for whatever search
1250 position they are needed.
1251
1252 NOTE: These additional MultiRegex objects are created dynamically. For most
1253 grammars most of the time we will never actually need anything more than the
1254 first MultiRegex - so this shouldn't have too much overhead.
1255
1256 Say this is our search group, and we match regex3, but wish to ignore it.
1257
1258 regex1 | regex2 | regex3 | regex4 | regex5 ' ie, startAt = 0
1259
1260 What we need is a new MultiRegex that only includes the remaining
1261 possibilities:
1262
1263 regex4 | regex5 ' ie, startAt = 3
1264
1265 This class wraps all that complexity up in a simple API... `startAt` decides
1266 where in the array of expressions to start doing the matching. It
1267 auto-increments, so if a match is found at position 2, then startAt will be
1268 set to 3. If the end is reached startAt will return to 0.
1269
1270 MOST of the time the parser will be setting startAt manually to 0.
1271 */
1272 class ResumableMultiRegex {
1273 constructor() {
1274 // @ts-ignore
1275 this.rules = [];
1276 // @ts-ignore
1277 this.multiRegexes = [];
1278 this.count = 0;
1279
1280 this.lastIndex = 0;
1281 this.regexIndex = 0;
1282 }
1283
1284 // @ts-ignore
1285 getMatcher(index) {
1286 if (this.multiRegexes[index]) return this.multiRegexes[index];
1287
1288 const matcher = new MultiRegex();
1289 this.rules.slice(index).forEach(([re, opts]) => matcher.addRule(re, opts));
1290 matcher.compile();
1291 this.multiRegexes[index] = matcher;
1292 return matcher;
1293 }
1294
1295 resumingScanAtSamePosition() {
1296 return this.regexIndex !== 0;
1297 }
1298
1299 considerAll() {
1300 this.regexIndex = 0;
1301 }
1302
1303 // @ts-ignore
1304 addRule(re, opts) {
1305 this.rules.push([re, opts]);
1306 if (opts.type === "begin") this.count++;
1307 }
1308
1309 /** @param {string} s */
1310 exec(s) {
1311 const m = this.getMatcher(this.regexIndex);
1312 m.lastIndex = this.lastIndex;
1313 let result = m.exec(s);
1314
1315 // The following is because we have no easy way to say "resume scanning at the
1316 // existing position but also skip the current rule ONLY". What happens is
1317 // all prior rules are also skipped which can result in matching the wrong
1318 // thing. Example of matching "booger":
1319
1320 // our matcher is [string, "booger", number]
1321 //
1322 // ....booger....
1323
1324 // if "booger" is ignored then we'd really need a regex to scan from the
1325 // SAME position for only: [string, number] but ignoring "booger" (if it
1326 // was the first match), a simple resume would scan ahead who knows how
1327 // far looking only for "number", ignoring potential string matches (or
1328 // future "booger" matches that might be valid.)
1329
1330 // So what we do: We execute two matchers, one resuming at the same
1331 // position, but the second full matcher starting at the position after:
1332
1333 // /--- resume first regex match here (for [number])
1334 // |/---- full match here for [string, "booger", number]
1335 // vv
1336 // ....booger....
1337
1338 // Which ever results in a match first is then used. So this 3-4 step
1339 // process essentially allows us to say "match at this position, excluding
1340 // a prior rule that was ignored".
1341 //
1342 // 1. Match "booger" first, ignore. Also proves that [string] does non match.
1343 // 2. Resume matching for [number]
1344 // 3. Match at index + 1 for [string, "booger", number]
1345 // 4. If #2 and #3 result in matches, which came first?
1346 if (this.resumingScanAtSamePosition()) {
1347 if (result && result.index === this.lastIndex) ; else { // use the second matcher result
1348 const m2 = this.getMatcher(0);
1349 m2.lastIndex = this.lastIndex + 1;
1350 result = m2.exec(s);
1351 }
1352 }
1353
1354 if (result) {
1355 this.regexIndex += result.position + 1;
1356 if (this.regexIndex === this.count) {
1357 // wrap-around to considering all matches again
1358 this.considerAll();
1359 }
1360 }
1361
1362 return result;
1363 }
1364 }
1365
1366 /**
1367 * Given a mode, builds a huge ResumableMultiRegex that can be used to walk
1368 * the content and find matches.
1369 *
1370 * @param {CompiledMode} mode
1371 * @returns {ResumableMultiRegex}
1372 */
1373 function buildModeRegex(mode) {
1374 const mm = new ResumableMultiRegex();
1375
1376 mode.contains.forEach(term => mm.addRule(term.begin, { rule: term, type: "begin" }));
1377
1378 if (mode.terminatorEnd) {
1379 mm.addRule(mode.terminatorEnd, { type: "end" });
1380 }
1381 if (mode.illegal) {
1382 mm.addRule(mode.illegal, { type: "illegal" });
1383 }
1384
1385 return mm;
1386 }
1387
1388 /** skip vs abort vs ignore
1389 *
1390 * @skip - The mode is still entered and exited normally (and contains rules apply),
1391 * but all content is held and added to the parent buffer rather than being
1392 * output when the mode ends. Mostly used with `sublanguage` to build up
1393 * a single large buffer than can be parsed by sublanguage.
1394 *
1395 * - The mode begin ands ends normally.
1396 * - Content matched is added to the parent mode buffer.
1397 * - The parser cursor is moved forward normally.
1398 *
1399 * @abort - A hack placeholder until we have ignore. Aborts the mode (as if it
1400 * never matched) but DOES NOT continue to match subsequent `contains`
1401 * modes. Abort is bad/suboptimal because it can result in modes
1402 * farther down not getting applied because an earlier rule eats the
1403 * content but then aborts.
1404 *
1405 * - The mode does not begin.
1406 * - Content matched by `begin` is added to the mode buffer.
1407 * - The parser cursor is moved forward accordingly.
1408 *
1409 * @ignore - Ignores the mode (as if it never matched) and continues to match any
1410 * subsequent `contains` modes. Ignore isn't technically possible with
1411 * the current parser implementation.
1412 *
1413 * - The mode does not begin.
1414 * - Content matched by `begin` is ignored.
1415 * - The parser cursor is not moved forward.
1416 */
1417
1418 /**
1419 * Compiles an individual mode
1420 *
1421 * This can raise an error if the mode contains certain detectable known logic
1422 * issues.
1423 * @param {Mode} mode
1424 * @param {CompiledMode | null} [parent]
1425 * @returns {CompiledMode | never}
1426 */
1427 function compileMode(mode, parent) {
1428 const cmode = /** @type CompiledMode */ (mode);
1429 if (mode.isCompiled) return cmode;
1430
1431 [
1432 scopeClassName,
1433 // do this early so compiler extensions generally don't have to worry about
1434 // the distinction between match/begin
1435 compileMatch,
1436 MultiClass,
1437 beforeMatchExt
1438 ].forEach(ext => ext(mode, parent));
1439
1440 language.compilerExtensions.forEach(ext => ext(mode, parent));
1441
1442 // __beforeBegin is considered private API, internal use only
1443 mode.__beforeBegin = null;
1444
1445 [
1446 beginKeywords,
1447 // do this later so compiler extensions that come earlier have access to the
1448 // raw array if they wanted to perhaps manipulate it, etc.
1449 compileIllegal,
1450 // default to 1 relevance if not specified
1451 compileRelevance
1452 ].forEach(ext => ext(mode, parent));
1453
1454 mode.isCompiled = true;
1455
1456 let keywordPattern = null;
1457 if (typeof mode.keywords === "object" && mode.keywords.$pattern) {
1458 // we need a copy because keywords might be compiled multiple times
1459 // so we can't go deleting $pattern from the original on the first
1460 // pass
1461 mode.keywords = Object.assign({}, mode.keywords);
1462 keywordPattern = mode.keywords.$pattern;
1463 delete mode.keywords.$pattern;
1464 }
1465 keywordPattern = keywordPattern || /\w+/;
1466
1467 if (mode.keywords) {
1468 mode.keywords = compileKeywords(mode.keywords, language.case_insensitive);
1469 }
1470
1471 cmode.keywordPatternRe = langRe(keywordPattern, true);
1472
1473 if (parent) {
1474 if (!mode.begin) mode.begin = /\B|\b/;
1475 cmode.beginRe = langRe(cmode.begin);
1476 if (!mode.end && !mode.endsWithParent) mode.end = /\B|\b/;
1477 if (mode.end) cmode.endRe = langRe(cmode.end);
1478 cmode.terminatorEnd = source(cmode.end) || '';
1479 if (mode.endsWithParent && parent.terminatorEnd) {
1480 cmode.terminatorEnd += (mode.end ? '|' : '') + parent.terminatorEnd;
1481 }
1482 }
1483 if (mode.illegal) cmode.illegalRe = langRe(/** @type {RegExp | string} */ (mode.illegal));
1484 if (!mode.contains) mode.contains = [];
1485
1486 mode.contains = [].concat(...mode.contains.map(function(c) {
1487 return expandOrCloneMode(c === 'self' ? mode : c);
1488 }));
1489 mode.contains.forEach(function(c) { compileMode(/** @type Mode */ (c), cmode); });
1490
1491 if (mode.starts) {
1492 compileMode(mode.starts, parent);
1493 }
1494
1495 cmode.matcher = buildModeRegex(cmode);
1496 return cmode;
1497 }
1498
1499 if (!language.compilerExtensions) language.compilerExtensions = [];
1500
1501 // self is not valid at the top-level
1502 if (language.contains && language.contains.includes('self')) {
1503 throw new Error("ERR: contains `self` is not supported at the top-level of a language. See documentation.");
1504 }
1505
1506 // we need a null object, which inherit will guarantee
1507 language.classNameAliases = inherit$1(language.classNameAliases || {});
1508
1509 return compileMode(/** @type Mode */ (language));
1510 }
1511
1512 /**
1513 * Determines if a mode has a dependency on it's parent or not
1514 *
1515 * If a mode does have a parent dependency then often we need to clone it if
1516 * it's used in multiple places so that each copy points to the correct parent,
1517 * where-as modes without a parent can often safely be re-used at the bottom of
1518 * a mode chain.
1519 *
1520 * @param {Mode | null} mode
1521 * @returns {boolean} - is there a dependency on the parent?
1522 * */
1523 function dependencyOnParent(mode) {
1524 if (!mode) return false;
1525
1526 return mode.endsWithParent || dependencyOnParent(mode.starts);
1527 }
1528
1529 /**
1530 * Expands a mode or clones it if necessary
1531 *
1532 * This is necessary for modes with parental dependenceis (see notes on
1533 * `dependencyOnParent`) and for nodes that have `variants` - which must then be
1534 * exploded into their own individual modes at compile time.
1535 *
1536 * @param {Mode} mode
1537 * @returns {Mode | Mode[]}
1538 * */
1539 function expandOrCloneMode(mode) {
1540 if (mode.variants && !mode.cachedVariants) {
1541 mode.cachedVariants = mode.variants.map(function(variant) {
1542 return inherit$1(mode, { variants: null }, variant);
1543 });
1544 }
1545
1546 // EXPAND
1547 // if we have variants then essentially "replace" the mode with the variants
1548 // this happens in compileMode, where this function is called from
1549 if (mode.cachedVariants) {
1550 return mode.cachedVariants;
1551 }
1552
1553 // CLONE
1554 // if we have dependencies on parents then we need a unique
1555 // instance of ourselves, so we can be reused with many
1556 // different parents without issue
1557 if (dependencyOnParent(mode)) {
1558 return inherit$1(mode, { starts: mode.starts ? inherit$1(mode.starts) : null });
1559 }
1560
1561 if (Object.isFrozen(mode)) {
1562 return inherit$1(mode);
1563 }
1564
1565 // no special dependency issues, just return ourselves
1566 return mode;
1567 }
1568
1569 var version = "11.7.0";
1570
1571 class HTMLInjectionError extends Error {
1572 constructor(reason, html) {
1573 super(reason);
1574 this.name = "HTMLInjectionError";
1575 this.html = html;
1576 }
1577 }
1578
1579 /*
1580 Syntax highlighting with language autodetection.
1581 https://highlightjs.org/
1582 */
1583
1584 /**
1585 @typedef {import('highlight.js').Mode} Mode
1586 @typedef {import('highlight.js').CompiledMode} CompiledMode
1587 @typedef {import('highlight.js').CompiledScope} CompiledScope
1588 @typedef {import('highlight.js').Language} Language
1589 @typedef {import('highlight.js').HLJSApi} HLJSApi
1590 @typedef {import('highlight.js').HLJSPlugin} HLJSPlugin
1591 @typedef {import('highlight.js').PluginEvent} PluginEvent
1592 @typedef {import('highlight.js').HLJSOptions} HLJSOptions
1593 @typedef {import('highlight.js').LanguageFn} LanguageFn
1594 @typedef {import('highlight.js').HighlightedHTMLElement} HighlightedHTMLElement
1595 @typedef {import('highlight.js').BeforeHighlightContext} BeforeHighlightContext
1596 @typedef {import('highlight.js/private').MatchType} MatchType
1597 @typedef {import('highlight.js/private').KeywordData} KeywordData
1598 @typedef {import('highlight.js/private').EnhancedMatch} EnhancedMatch
1599 @typedef {import('highlight.js/private').AnnotatedError} AnnotatedError
1600 @typedef {import('highlight.js').AutoHighlightResult} AutoHighlightResult
1601 @typedef {import('highlight.js').HighlightOptions} HighlightOptions
1602 @typedef {import('highlight.js').HighlightResult} HighlightResult
1603 */
1604
1605
1606 const escape = escapeHTML;
1607 const inherit = inherit$1;
1608 const NO_MATCH = Symbol("nomatch");
1609 const MAX_KEYWORD_HITS = 7;
1610
1611 /**
1612 * @param {any} hljs - object that is extended (legacy)
1613 * @returns {HLJSApi}
1614 */
1615 const HLJS = function(hljs) {
1616 // Global internal variables used within the highlight.js library.
1617 /** @type {Record<string, Language>} */
1618 const languages = Object.create(null);
1619 /** @type {Record<string, string>} */
1620 const aliases = Object.create(null);
1621 /** @type {HLJSPlugin[]} */
1622 const plugins = [];
1623
1624 // safe/production mode - swallows more errors, tries to keep running
1625 // even if a single syntax or parse hits a fatal error
1626 let SAFE_MODE = true;
1627 const LANGUAGE_NOT_FOUND = "Could not find the language '{}', did you forget to load/include a language module?";
1628 /** @type {Language} */
1629 const PLAINTEXT_LANGUAGE = { disableAutodetect: true, name: 'Plain text', contains: [] };
1630
1631 // Global options used when within external APIs. This is modified when
1632 // calling the `hljs.configure` function.
1633 /** @type HLJSOptions */
1634 let options = {
1635 ignoreUnescapedHTML: false,
1636 throwUnescapedHTML: false,
1637 noHighlightRe: /^(no-?highlight)$/i,
1638 languageDetectRe: /\blang(?:uage)?-([\w-]+)\b/i,
1639 classPrefix: 'hljs-',
1640 cssSelector: 'pre code',
1641 languages: null,
1642 // beta configuration options, subject to change, welcome to discuss
1643 // https://github.com/highlightjs/highlight.js/issues/1086
1644 __emitter: TokenTreeEmitter
1645 };
1646
1647 /* Utility functions */
1648
1649 /**
1650 * Tests a language name to see if highlighting should be skipped
1651 * @param {string} languageName
1652 */
1653 function shouldNotHighlight(languageName) {
1654 return options.noHighlightRe.test(languageName);
1655 }
1656
1657 /**
1658 * @param {HighlightedHTMLElement} block - the HTML element to determine language for
1659 */
1660 function blockLanguage(block) {
1661 let classes = block.className + ' ';
1662
1663 classes += block.parentNode ? block.parentNode.className : '';
1664
1665 // language-* takes precedence over non-prefixed class names.
1666 const match = options.languageDetectRe.exec(classes);
1667 if (match) {
1668 const language = getLanguage(match[1]);
1669 if (!language) {
1670 warn(LANGUAGE_NOT_FOUND.replace("{}", match[1]));
1671 warn("Falling back to no-highlight mode for this block.", block);
1672 }
1673 return language ? match[1] : 'no-highlight';
1674 }
1675
1676 return classes
1677 .split(/\s+/)
1678 .find((_class) => shouldNotHighlight(_class) || getLanguage(_class));
1679 }
1680
1681 /**
1682 * Core highlighting function.
1683 *
1684 * OLD API
1685 * highlight(lang, code, ignoreIllegals, continuation)
1686 *
1687 * NEW API
1688 * highlight(code, {lang, ignoreIllegals})
1689 *
1690 * @param {string} codeOrLanguageName - the language to use for highlighting
1691 * @param {string | HighlightOptions} optionsOrCode - the code to highlight
1692 * @param {boolean} [ignoreIllegals] - whether to ignore illegal matches, default is to bail
1693 *
1694 * @returns {HighlightResult} Result - an object that represents the result
1695 * @property {string} language - the language name
1696 * @property {number} relevance - the relevance score
1697 * @property {string} value - the highlighted HTML code
1698 * @property {string} code - the original raw code
1699 * @property {CompiledMode} top - top of the current mode stack
1700 * @property {boolean} illegal - indicates whether any illegal matches were found
1701 */
1702 function highlight(codeOrLanguageName, optionsOrCode, ignoreIllegals) {
1703 let code = "";
1704 let languageName = "";
1705 if (typeof optionsOrCode === "object") {
1706 code = codeOrLanguageName;
1707 ignoreIllegals = optionsOrCode.ignoreIllegals;
1708 languageName = optionsOrCode.language;
1709 } else {
1710 // old API
1711 deprecated("10.7.0", "highlight(lang, code, ...args) has been deprecated.");
1712 deprecated("10.7.0", "Please use highlight(code, options) instead.\nhttps://github.com/highlightjs/highlight.js/issues/2277");
1713 languageName = codeOrLanguageName;
1714 code = optionsOrCode;
1715 }
1716
1717 // https://github.com/highlightjs/highlight.js/issues/3149
1718 // eslint-disable-next-line no-undefined
1719 if (ignoreIllegals === undefined) { ignoreIllegals = true; }
1720
1721 /** @type {BeforeHighlightContext} */
1722 const context = {
1723 code,
1724 language: languageName
1725 };
1726 // the plugin can change the desired language or the code to be highlighted
1727 // just be changing the object it was passed
1728 fire("before:highlight", context);
1729
1730 // a before plugin can usurp the result completely by providing it's own
1731 // in which case we don't even need to call highlight
1732 const result = context.result
1733 ? context.result
1734 : _highlight(context.language, context.code, ignoreIllegals);
1735
1736 result.code = context.code;
1737 // the plugin can change anything in result to suite it
1738 fire("after:highlight", result);
1739
1740 return result;
1741 }
1742
1743 /**
1744 * private highlight that's used internally and does not fire callbacks
1745 *
1746 * @param {string} languageName - the language to use for highlighting
1747 * @param {string} codeToHighlight - the code to highlight
1748 * @param {boolean?} [ignoreIllegals] - whether to ignore illegal matches, default is to bail
1749 * @param {CompiledMode?} [continuation] - current continuation mode, if any
1750 * @returns {HighlightResult} - result of the highlight operation
1751 */
1752 function _highlight(languageName, codeToHighlight, ignoreIllegals, continuation) {
1753 const keywordHits = Object.create(null);
1754
1755 /**
1756 * Return keyword data if a match is a keyword
1757 * @param {CompiledMode} mode - current mode
1758 * @param {string} matchText - the textual match
1759 * @returns {KeywordData | false}
1760 */
1761 function keywordData(mode, matchText) {
1762 return mode.keywords[matchText];
1763 }
1764
1765 function processKeywords() {
1766 if (!top.keywords) {
1767 emitter.addText(modeBuffer);
1768 return;
1769 }
1770
1771 let lastIndex = 0;
1772 top.keywordPatternRe.lastIndex = 0;
1773 let match = top.keywordPatternRe.exec(modeBuffer);
1774 let buf = "";
1775
1776 while (match) {
1777 buf += modeBuffer.substring(lastIndex, match.index);
1778 const word = language.case_insensitive ? match[0].toLowerCase() : match[0];
1779 const data = keywordData(top, word);
1780 if (data) {
1781 const [kind, keywordRelevance] = data;
1782 emitter.addText(buf);
1783 buf = "";
1784
1785 keywordHits[word] = (keywordHits[word] || 0) + 1;
1786 if (keywordHits[word] <= MAX_KEYWORD_HITS) relevance += keywordRelevance;
1787 if (kind.startsWith("_")) {
1788 // _ implied for relevance only, do not highlight
1789 // by applying a class name
1790 buf += match[0];
1791 } else {
1792 const cssClass = language.classNameAliases[kind] || kind;
1793 emitter.addKeyword(match[0], cssClass);
1794 }
1795 } else {
1796 buf += match[0];
1797 }
1798 lastIndex = top.keywordPatternRe.lastIndex;
1799 match = top.keywordPatternRe.exec(modeBuffer);
1800 }
1801 buf += modeBuffer.substring(lastIndex);
1802 emitter.addText(buf);
1803 }
1804
1805 function processSubLanguage() {
1806 if (modeBuffer === "") return;
1807 /** @type HighlightResult */
1808 let result = null;
1809
1810 if (typeof top.subLanguage === 'string') {
1811 if (!languages[top.subLanguage]) {
1812 emitter.addText(modeBuffer);
1813 return;
1814 }
1815 result = _highlight(top.subLanguage, modeBuffer, true, continuations[top.subLanguage]);
1816 continuations[top.subLanguage] = /** @type {CompiledMode} */ (result._top);
1817 } else {
1818 result = highlightAuto(modeBuffer, top.subLanguage.length ? top.subLanguage : null);
1819 }
1820
1821 // Counting embedded language score towards the host language may be disabled
1822 // with zeroing the containing mode relevance. Use case in point is Markdown that
1823 // allows XML everywhere and makes every XML snippet to have a much larger Markdown
1824 // score.
1825 if (top.relevance > 0) {
1826 relevance += result.relevance;
1827 }
1828 emitter.addSublanguage(result._emitter, result.language);
1829 }
1830
1831 function processBuffer() {
1832 if (top.subLanguage != null) {
1833 processSubLanguage();
1834 } else {
1835 processKeywords();
1836 }
1837 modeBuffer = '';
1838 }
1839
1840 /**
1841 * @param {CompiledScope} scope
1842 * @param {RegExpMatchArray} match
1843 */
1844 function emitMultiClass(scope, match) {
1845 let i = 1;
1846 const max = match.length - 1;
1847 while (i <= max) {
1848 if (!scope._emit[i]) { i++; continue; }
1849 const klass = language.classNameAliases[scope[i]] || scope[i];
1850 const text = match[i];
1851 if (klass) {
1852 emitter.addKeyword(text, klass);
1853 } else {
1854 modeBuffer = text;
1855 processKeywords();
1856 modeBuffer = "";
1857 }
1858 i++;
1859 }
1860 }
1861
1862 /**
1863 * @param {CompiledMode} mode - new mode to start
1864 * @param {RegExpMatchArray} match
1865 */
1866 function startNewMode(mode, match) {
1867 if (mode.scope && typeof mode.scope === "string") {
1868 emitter.openNode(language.classNameAliases[mode.scope] || mode.scope);
1869 }
1870 if (mode.beginScope) {
1871 // beginScope just wraps the begin match itself in a scope
1872 if (mode.beginScope._wrap) {
1873 emitter.addKeyword(modeBuffer, language.classNameAliases[mode.beginScope._wrap] || mode.beginScope._wrap);
1874 modeBuffer = "";
1875 } else if (mode.beginScope._multi) {
1876 // at this point modeBuffer should just be the match
1877 emitMultiClass(mode.beginScope, match);
1878 modeBuffer = "";
1879 }
1880 }
1881
1882 top = Object.create(mode, { parent: { value: top } });
1883 return top;
1884 }
1885
1886 /**
1887 * @param {CompiledMode } mode - the mode to potentially end
1888 * @param {RegExpMatchArray} match - the latest match
1889 * @param {string} matchPlusRemainder - match plus remainder of content
1890 * @returns {CompiledMode | void} - the next mode, or if void continue on in current mode
1891 */
1892 function endOfMode(mode, match, matchPlusRemainder) {
1893 let matched = startsWith(mode.endRe, matchPlusRemainder);
1894
1895 if (matched) {
1896 if (mode["on:end"]) {
1897 const resp = new Response(mode);
1898 mode["on:end"](match, resp);
1899 if (resp.isMatchIgnored) matched = false;
1900 }
1901
1902 if (matched) {
1903 while (mode.endsParent && mode.parent) {
1904 mode = mode.parent;
1905 }
1906 return mode;
1907 }
1908 }
1909 // even if on:end fires an `ignore` it's still possible
1910 // that we might trigger the end node because of a parent mode
1911 if (mode.endsWithParent) {
1912 return endOfMode(mode.parent, match, matchPlusRemainder);
1913 }
1914 }
1915
1916 /**
1917 * Handle matching but then ignoring a sequence of text
1918 *
1919 * @param {string} lexeme - string containing full match text
1920 */
1921 function doIgnore(lexeme) {
1922 if (top.matcher.regexIndex === 0) {
1923 // no more regexes to potentially match here, so we move the cursor forward one
1924 // space
1925 modeBuffer += lexeme[0];
1926 return 1;
1927 } else {
1928 // no need to move the cursor, we still have additional regexes to try and
1929 // match at this very spot
1930 resumeScanAtSamePosition = true;
1931 return 0;
1932 }
1933 }
1934
1935 /**
1936 * Handle the start of a new potential mode match
1937 *
1938 * @param {EnhancedMatch} match - the current match
1939 * @returns {number} how far to advance the parse cursor
1940 */
1941 function doBeginMatch(match) {
1942 const lexeme = match[0];
1943 const newMode = match.rule;
1944
1945 const resp = new Response(newMode);
1946 // first internal before callbacks, then the public ones
1947 const beforeCallbacks = [newMode.__beforeBegin, newMode["on:begin"]];
1948 for (const cb of beforeCallbacks) {
1949 if (!cb) continue;
1950 cb(match, resp);
1951 if (resp.isMatchIgnored) return doIgnore(lexeme);
1952 }
1953
1954 if (newMode.skip) {
1955 modeBuffer += lexeme;
1956 } else {
1957 if (newMode.excludeBegin) {
1958 modeBuffer += lexeme;
1959 }
1960 processBuffer();
1961 if (!newMode.returnBegin && !newMode.excludeBegin) {
1962 modeBuffer = lexeme;
1963 }
1964 }
1965 startNewMode(newMode, match);
1966 return newMode.returnBegin ? 0 : lexeme.length;
1967 }
1968
1969 /**
1970 * Handle the potential end of mode
1971 *
1972 * @param {RegExpMatchArray} match - the current match
1973 */
1974 function doEndMatch(match) {
1975 const lexeme = match[0];
1976 const matchPlusRemainder = codeToHighlight.substring(match.index);
1977
1978 const endMode = endOfMode(top, match, matchPlusRemainder);
1979 if (!endMode) { return NO_MATCH; }
1980
1981 const origin = top;
1982 if (top.endScope && top.endScope._wrap) {
1983 processBuffer();
1984 emitter.addKeyword(lexeme, top.endScope._wrap);
1985 } else if (top.endScope && top.endScope._multi) {
1986 processBuffer();
1987 emitMultiClass(top.endScope, match);
1988 } else if (origin.skip) {
1989 modeBuffer += lexeme;
1990 } else {
1991 if (!(origin.returnEnd || origin.excludeEnd)) {
1992 modeBuffer += lexeme;
1993 }
1994 processBuffer();
1995 if (origin.excludeEnd) {
1996 modeBuffer = lexeme;
1997 }
1998 }
1999 do {
2000 if (top.scope) {
2001 emitter.closeNode();
2002 }
2003 if (!top.skip && !top.subLanguage) {
2004 relevance += top.relevance;
2005 }
2006 top = top.parent;
2007 } while (top !== endMode.parent);
2008 if (endMode.starts) {
2009 startNewMode(endMode.starts, match);
2010 }
2011 return origin.returnEnd ? 0 : lexeme.length;
2012 }
2013
2014 function processContinuations() {
2015 const list = [];
2016 for (let current = top; current !== language; current = current.parent) {
2017 if (current.scope) {
2018 list.unshift(current.scope);
2019 }
2020 }
2021 list.forEach(item => emitter.openNode(item));
2022 }
2023
2024 /** @type {{type?: MatchType, index?: number, rule?: Mode}}} */
2025 let lastMatch = {};
2026
2027 /**
2028 * Process an individual match
2029 *
2030 * @param {string} textBeforeMatch - text preceding the match (since the last match)
2031 * @param {EnhancedMatch} [match] - the match itself
2032 */
2033 function processLexeme(textBeforeMatch, match) {
2034 const lexeme = match && match[0];
2035
2036 // add non-matched text to the current mode buffer
2037 modeBuffer += textBeforeMatch;
2038
2039 if (lexeme == null) {
2040 processBuffer();
2041 return 0;
2042 }
2043
2044 // we've found a 0 width match and we're stuck, so we need to advance
2045 // this happens when we have badly behaved rules that have optional matchers to the degree that
2046 // sometimes they can end up matching nothing at all
2047 // Ref: https://github.com/highlightjs/highlight.js/issues/2140
2048 if (lastMatch.type === "begin" && match.type === "end" && lastMatch.index === match.index && lexeme === "") {
2049 // spit the "skipped" character that our regex choked on back into the output sequence
2050 modeBuffer += codeToHighlight.slice(match.index, match.index + 1);
2051 if (!SAFE_MODE) {
2052 /** @type {AnnotatedError} */
2053 const err = new Error(`0 width match regex (${languageName})`);
2054 err.languageName = languageName;
2055 err.badRule = lastMatch.rule;
2056 throw err;
2057 }
2058 return 1;
2059 }
2060 lastMatch = match;
2061
2062 if (match.type === "begin") {
2063 return doBeginMatch(match);
2064 } else if (match.type === "illegal" && !ignoreIllegals) {
2065 // illegal match, we do not continue processing
2066 /** @type {AnnotatedError} */
2067 const err = new Error('Illegal lexeme "' + lexeme + '" for mode "' + (top.scope || '<unnamed>') + '"');
2068 err.mode = top;
2069 throw err;
2070 } else if (match.type === "end") {
2071 const processed = doEndMatch(match);
2072 if (processed !== NO_MATCH) {
2073 return processed;
2074 }
2075 }
2076
2077 // edge case for when illegal matches $ (end of line) which is technically
2078 // a 0 width match but not a begin/end match so it's not caught by the
2079 // first handler (when ignoreIllegals is true)
2080 if (match.type === "illegal" && lexeme === "") {
2081 // advance so we aren't stuck in an infinite loop
2082 return 1;
2083 }
2084
2085 // infinite loops are BAD, this is a last ditch catch all. if we have a
2086 // decent number of iterations yet our index (cursor position in our
2087 // parsing) still 3x behind our index then something is very wrong
2088 // so we bail
2089 if (iterations > 100000 && iterations > match.index * 3) {
2090 const err = new Error('potential infinite loop, way more iterations than matches');
2091 throw err;
2092 }
2093
2094 /*
2095 Why might be find ourselves here? An potential end match that was
2096 triggered but could not be completed. IE, `doEndMatch` returned NO_MATCH.
2097 (this could be because a callback requests the match be ignored, etc)
2098
2099 This causes no real harm other than stopping a few times too many.
2100 */
2101
2102 modeBuffer += lexeme;
2103 return lexeme.length;
2104 }
2105
2106 const language = getLanguage(languageName);
2107 if (!language) {
2108 error(LANGUAGE_NOT_FOUND.replace("{}", languageName));
2109 throw new Error('Unknown language: "' + languageName + '"');
2110 }
2111
2112 const md = compileLanguage(language);
2113 let result = '';
2114 /** @type {CompiledMode} */
2115 let top = continuation || md;
2116 /** @type Record<string,CompiledMode> */
2117 const continuations = {}; // keep continuations for sub-languages
2118 const emitter = new options.__emitter(options);
2119 processContinuations();
2120 let modeBuffer = '';
2121 let relevance = 0;
2122 let index = 0;
2123 let iterations = 0;
2124 let resumeScanAtSamePosition = false;
2125
2126 try {
2127 top.matcher.considerAll();
2128
2129 for (;;) {
2130 iterations++;
2131 if (resumeScanAtSamePosition) {
2132 // only regexes not matched previously will now be
2133 // considered for a potential match
2134 resumeScanAtSamePosition = false;
2135 } else {
2136 top.matcher.considerAll();
2137 }
2138 top.matcher.lastIndex = index;
2139
2140 const match = top.matcher.exec(codeToHighlight);
2141 // console.log("match", match[0], match.rule && match.rule.begin)
2142
2143 if (!match) break;
2144
2145 const beforeMatch = codeToHighlight.substring(index, match.index);
2146 const processedCount = processLexeme(beforeMatch, match);
2147 index = match.index + processedCount;
2148 }
2149 processLexeme(codeToHighlight.substring(index));
2150 emitter.closeAllNodes();
2151 emitter.finalize();
2152 result = emitter.toHTML();
2153
2154 return {
2155 language: languageName,
2156 value: result,
2157 relevance: relevance,
2158 illegal: false,
2159 _emitter: emitter,
2160 _top: top
2161 };
2162 } catch (err) {
2163 if (err.message && err.message.includes('Illegal')) {
2164 return {
2165 language: languageName,
2166 value: escape(codeToHighlight),
2167 illegal: true,
2168 relevance: 0,
2169 _illegalBy: {
2170 message: err.message,
2171 index: index,
2172 context: codeToHighlight.slice(index - 100, index + 100),
2173 mode: err.mode,
2174 resultSoFar: result
2175 },
2176 _emitter: emitter
2177 };
2178 } else if (SAFE_MODE) {
2179 return {
2180 language: languageName,
2181 value: escape(codeToHighlight),
2182 illegal: false,
2183 relevance: 0,
2184 errorRaised: err,
2185 _emitter: emitter,
2186 _top: top
2187 };
2188 } else {
2189 throw err;
2190 }
2191 }
2192 }
2193
2194 /**
2195 * returns a valid highlight result, without actually doing any actual work,
2196 * auto highlight starts with this and it's possible for small snippets that
2197 * auto-detection may not find a better match
2198 * @param {string} code
2199 * @returns {HighlightResult}
2200 */
2201 function justTextHighlightResult(code) {
2202 const result = {
2203 value: escape(code),
2204 illegal: false,
2205 relevance: 0,
2206 _top: PLAINTEXT_LANGUAGE,
2207 _emitter: new options.__emitter(options)
2208 };
2209 result._emitter.addText(code);
2210 return result;
2211 }
2212
2213 /**
2214 Highlighting with language detection. Accepts a string with the code to
2215 highlight. Returns an object with the following properties:
2216
2217 - language (detected language)
2218 - relevance (int)
2219 - value (an HTML string with highlighting markup)
2220 - secondBest (object with the same structure for second-best heuristically
2221 detected language, may be absent)
2222
2223 @param {string} code
2224 @param {Array<string>} [languageSubset]
2225 @returns {AutoHighlightResult}
2226 */
2227 function highlightAuto(code, languageSubset) {
2228 languageSubset = languageSubset || options.languages || Object.keys(languages);
2229 const plaintext = justTextHighlightResult(code);
2230
2231 const results = languageSubset.filter(getLanguage).filter(autoDetection).map(name =>
2232 _highlight(name, code, false)
2233 );
2234 results.unshift(plaintext); // plaintext is always an option
2235
2236 const sorted = results.sort((a, b) => {
2237 // sort base on relevance
2238 if (a.relevance !== b.relevance) return b.relevance - a.relevance;
2239
2240 // always award the tie to the base language
2241 // ie if C++ and Arduino are tied, it's more likely to be C++
2242 if (a.language && b.language) {
2243 if (getLanguage(a.language).supersetOf === b.language) {
2244 return 1;
2245 } else if (getLanguage(b.language).supersetOf === a.language) {
2246 return -1;
2247 }
2248 }
2249
2250 // otherwise say they are equal, which has the effect of sorting on
2251 // relevance while preserving the original ordering - which is how ties
2252 // have historically been settled, ie the language that comes first always
2253 // wins in the case of a tie
2254 return 0;
2255 });
2256
2257 const [best, secondBest] = sorted;
2258
2259 /** @type {AutoHighlightResult} */
2260 const result = best;
2261 result.secondBest = secondBest;
2262
2263 return result;
2264 }
2265
2266 /**
2267 * Builds new class name for block given the language name
2268 *
2269 * @param {HTMLElement} element
2270 * @param {string} [currentLang]
2271 * @param {string} [resultLang]
2272 */
2273 function updateClassName(element, currentLang, resultLang) {
2274 const language = (currentLang && aliases[currentLang]) || resultLang;
2275
2276 element.classList.add("hljs");
2277 element.classList.add(`language-${language}`);
2278 }
2279
2280 /**
2281 * Applies highlighting to a DOM node containing code.
2282 *
2283 * @param {HighlightedHTMLElement} element - the HTML element to highlight
2284 */
2285 function highlightElement(element) {
2286 /** @type HTMLElement */
2287 let node = null;
2288 const language = blockLanguage(element);
2289
2290 if (shouldNotHighlight(language)) return;
2291
2292 fire("before:highlightElement",
2293 { el: element, language: language });
2294
2295 // we should be all text, no child nodes (unescaped HTML) - this is possibly
2296 // an HTML injection attack - it's likely too late if this is already in
2297 // production (the code has likely already done its damage by the time
2298 // we're seeing it)... but we yell loudly about this so that hopefully it's
2299 // more likely to be caught in development before making it to production
2300 if (element.children.length > 0) {
2301 if (!options.ignoreUnescapedHTML) {
2302 console.warn("One of your code blocks includes unescaped HTML. This is a potentially serious security risk.");
2303 console.warn("https://github.com/highlightjs/highlight.js/wiki/security");
2304 console.warn("The element with unescaped HTML:");
2305 console.warn(element);
2306 }
2307 if (options.throwUnescapedHTML) {
2308 const err = new HTMLInjectionError(
2309 "One of your code blocks includes unescaped HTML.",
2310 element.innerHTML
2311 );
2312 throw err;
2313 }
2314 }
2315
2316 node = element;
2317 const text = node.textContent;
2318 const result = language ? highlight(text, { language, ignoreIllegals: true }) : highlightAuto(text);
2319
2320 element.innerHTML = result.value;
2321 updateClassName(element, language, result.language);
2322 element.result = {
2323 language: result.language,
2324 // TODO: remove with version 11.0
2325 re: result.relevance,
2326 relevance: result.relevance
2327 };
2328 if (result.secondBest) {
2329 element.secondBest = {
2330 language: result.secondBest.language,
2331 relevance: result.secondBest.relevance
2332 };
2333 }
2334
2335 fire("after:highlightElement", { el: element, result, text });
2336 }
2337
2338 /**
2339 * Updates highlight.js global options with the passed options
2340 *
2341 * @param {Partial<HLJSOptions>} userOptions
2342 */
2343 function configure(userOptions) {
2344 options = inherit(options, userOptions);
2345 }
2346
2347 // TODO: remove v12, deprecated
2348 const initHighlighting = () => {
2349 highlightAll();
2350 deprecated("10.6.0", "initHighlighting() deprecated. Use highlightAll() now.");
2351 };
2352
2353 // TODO: remove v12, deprecated
2354 function initHighlightingOnLoad() {
2355 highlightAll();
2356 deprecated("10.6.0", "initHighlightingOnLoad() deprecated. Use highlightAll() now.");
2357 }
2358
2359 let wantsHighlight = false;
2360
2361 /**
2362 * auto-highlights all pre>code elements on the page
2363 */
2364 function highlightAll() {
2365 // if we are called too early in the loading process
2366 if (document.readyState === "loading") {
2367 wantsHighlight = true;
2368 return;
2369 }
2370
2371 const blocks = document.querySelectorAll(options.cssSelector);
2372 blocks.forEach(highlightElement);
2373 }
2374
2375 function boot() {
2376 // if a highlight was requested before DOM was loaded, do now
2377 if (wantsHighlight) highlightAll();
2378 }
2379
2380 // make sure we are in the browser environment
2381 if (typeof window !== 'undefined' && window.addEventListener) {
2382 window.addEventListener('DOMContentLoaded', boot, false);
2383 }
2384
2385 /**
2386 * Register a language grammar module
2387 *
2388 * @param {string} languageName
2389 * @param {LanguageFn} languageDefinition
2390 */
2391 function registerLanguage(languageName, languageDefinition) {
2392 let lang = null;
2393 try {
2394 lang = languageDefinition(hljs);
2395 } catch (error$1) {
2396 error("Language definition for '{}' could not be registered.".replace("{}", languageName));
2397 // hard or soft error
2398 if (!SAFE_MODE) { throw error$1; } else { error(error$1); }
2399 // languages that have serious errors are replaced with essentially a
2400 // "plaintext" stand-in so that the code blocks will still get normal
2401 // css classes applied to them - and one bad language won't break the
2402 // entire highlighter
2403 lang = PLAINTEXT_LANGUAGE;
2404 }
2405 // give it a temporary name if it doesn't have one in the meta-data
2406 if (!lang.name) lang.name = languageName;
2407 languages[languageName] = lang;
2408 lang.rawDefinition = languageDefinition.bind(null, hljs);
2409
2410 if (lang.aliases) {
2411 registerAliases(lang.aliases, { languageName });
2412 }
2413 }
2414
2415 /**
2416 * Remove a language grammar module
2417 *
2418 * @param {string} languageName
2419 */
2420 function unregisterLanguage(languageName) {
2421 delete languages[languageName];
2422 for (const alias of Object.keys(aliases)) {
2423 if (aliases[alias] === languageName) {
2424 delete aliases[alias];
2425 }
2426 }
2427 }
2428
2429 /**
2430 * @returns {string[]} List of language internal names
2431 */
2432 function listLanguages() {
2433 return Object.keys(languages);
2434 }
2435
2436 /**
2437 * @param {string} name - name of the language to retrieve
2438 * @returns {Language | undefined}
2439 */
2440 function getLanguage(name) {
2441 name = (name || '').toLowerCase();
2442 return languages[name] || languages[aliases[name]];
2443 }
2444
2445 /**
2446 *
2447 * @param {string|string[]} aliasList - single alias or list of aliases
2448 * @param {{languageName: string}} opts
2449 */
2450 function registerAliases(aliasList, { languageName }) {
2451 if (typeof aliasList === 'string') {
2452 aliasList = [aliasList];
2453 }
2454 aliasList.forEach(alias => { aliases[alias.toLowerCase()] = languageName; });
2455 }
2456
2457 /**
2458 * Determines if a given language has auto-detection enabled
2459 * @param {string} name - name of the language
2460 */
2461 function autoDetection(name) {
2462 const lang = getLanguage(name);
2463 return lang && !lang.disableAutodetect;
2464 }
2465
2466 /**
2467 * Upgrades the old highlightBlock plugins to the new
2468 * highlightElement API
2469 * @param {HLJSPlugin} plugin
2470 */
2471 function upgradePluginAPI(plugin) {
2472 // TODO: remove with v12
2473 if (plugin["before:highlightBlock"] && !plugin["before:highlightElement"]) {
2474 plugin["before:highlightElement"] = (data) => {
2475 plugin["before:highlightBlock"](
2476 Object.assign({ block: data.el }, data)
2477 );
2478 };
2479 }
2480 if (plugin["after:highlightBlock"] && !plugin["after:highlightElement"]) {
2481 plugin["after:highlightElement"] = (data) => {
2482 plugin["after:highlightBlock"](
2483 Object.assign({ block: data.el }, data)
2484 );
2485 };
2486 }
2487 }
2488
2489 /**
2490 * @param {HLJSPlugin} plugin
2491 */
2492 function addPlugin(plugin) {
2493 upgradePluginAPI(plugin);
2494 plugins.push(plugin);
2495 }
2496
2497 /**
2498 *
2499 * @param {PluginEvent} event
2500 * @param {any} args
2501 */
2502 function fire(event, args) {
2503 const cb = event;
2504 plugins.forEach(function(plugin) {
2505 if (plugin[cb]) {
2506 plugin[cb](args);
2507 }
2508 });
2509 }
2510
2511 /**
2512 * DEPRECATED
2513 * @param {HighlightedHTMLElement} el
2514 */
2515 function deprecateHighlightBlock(el) {
2516 deprecated("10.7.0", "highlightBlock will be removed entirely in v12.0");
2517 deprecated("10.7.0", "Please use highlightElement now.");
2518
2519 return highlightElement(el);
2520 }
2521
2522 /* Interface definition */
2523 Object.assign(hljs, {
2524 highlight,
2525 highlightAuto,
2526 highlightAll,
2527 highlightElement,
2528 // TODO: Remove with v12 API
2529 highlightBlock: deprecateHighlightBlock,
2530 configure,
2531 initHighlighting,
2532 initHighlightingOnLoad,
2533 registerLanguage,
2534 unregisterLanguage,
2535 listLanguages,
2536 getLanguage,
2537 registerAliases,
2538 autoDetection,
2539 inherit,
2540 addPlugin
2541 });
2542
2543 hljs.debugMode = function() { SAFE_MODE = false; };
2544 hljs.safeMode = function() { SAFE_MODE = true; };
2545 hljs.versionString = version;
2546
2547 hljs.regex = {
2548 concat: concat,
2549 lookahead: lookahead,
2550 either: either,
2551 optional: optional,
2552 anyNumberOfTimes: anyNumberOfTimes
2553 };
2554
2555 for (const key in MODES$1) {
2556 // @ts-ignore
2557 if (typeof MODES$1[key] === "object") {
2558 // @ts-ignore
2559 deepFreezeEs6.exports(MODES$1[key]);
2560 }
2561 }
2562
2563 // merge all the modes/regexes into our main object
2564 Object.assign(hljs, MODES$1);
2565
2566 return hljs;
2567 };
2568
2569 // export an "instance" of the highlighter
2570 var HighlightJS = HLJS({});
2571
2572 /*
2573 Language: Bash
2574 Author: vah <vahtenberg@gmail.com>
2575 Contributrors: Benjamin Pannell <contact@sierrasoftworks.com>
2576 Website: https://www.gnu.org/software/bash/
2577 Category: common
2578 */
2579
2580 /** @type LanguageFn */
2581 function bash(hljs) {
2582 const regex = hljs.regex;
2583 const VAR = {};
2584 const BRACED_VAR = {
2585 begin: /\$\{/,
2586 end: /\}/,
2587 contains: [
2588 "self",
2589 {
2590 begin: /:-/,
2591 contains: [ VAR ]
2592 } // default values
2593 ]
2594 };
2595 Object.assign(VAR, {
2596 className: 'variable',
2597 variants: [
2598 { begin: regex.concat(/\$[\w\d#@][\w\d_]*/,
2599 // negative look-ahead tries to avoid matching patterns that are not
2600 // Perl at all like $ident$, @ident@, etc.
2601 `(?![\\w\\d])(?![$])`) },
2602 BRACED_VAR
2603 ]
2604 });
2605
2606 const SUBST = {
2607 className: 'subst',
2608 begin: /\$\(/,
2609 end: /\)/,
2610 contains: [ hljs.BACKSLASH_ESCAPE ]
2611 };
2612 const HERE_DOC = {
2613 begin: /<<-?\s*(?=\w+)/,
2614 starts: { contains: [
2615 hljs.END_SAME_AS_BEGIN({
2616 begin: /(\w+)/,
2617 end: /(\w+)/,
2618 className: 'string'
2619 })
2620 ] }
2621 };
2622 const QUOTE_STRING = {
2623 className: 'string',
2624 begin: /"/,
2625 end: /"/,
2626 contains: [
2627 hljs.BACKSLASH_ESCAPE,
2628 VAR,
2629 SUBST
2630 ]
2631 };
2632 SUBST.contains.push(QUOTE_STRING);
2633 const ESCAPED_QUOTE = {
2634 className: '',
2635 begin: /\\"/
2636
2637 };
2638 const APOS_STRING = {
2639 className: 'string',
2640 begin: /'/,
2641 end: /'/
2642 };
2643 const ARITHMETIC = {
2644 begin: /\$?\(\(/,
2645 end: /\)\)/,
2646 contains: [
2647 {
2648 begin: /\d+#[0-9a-f]+/,
2649 className: "number"
2650 },
2651 hljs.NUMBER_MODE,
2652 VAR
2653 ]
2654 };
2655 const SH_LIKE_SHELLS = [
2656 "fish",
2657 "bash",
2658 "zsh",
2659 "sh",
2660 "csh",
2661 "ksh",
2662 "tcsh",
2663 "dash",
2664 "scsh",
2665 ];
2666 const KNOWN_SHEBANG = hljs.SHEBANG({
2667 binary: `(${SH_LIKE_SHELLS.join("|")})`,
2668 relevance: 10
2669 });
2670 const FUNCTION = {
2671 className: 'function',
2672 begin: /\w[\w\d_]*\s*\(\s*\)\s*\{/,
2673 returnBegin: true,
2674 contains: [ hljs.inherit(hljs.TITLE_MODE, { begin: /\w[\w\d_]*/ }) ],
2675 relevance: 0
2676 };
2677
2678 const KEYWORDS = [
2679 "if",
2680 "then",
2681 "else",
2682 "elif",
2683 "fi",
2684 "for",
2685 "while",
2686 "in",
2687 "do",
2688 "done",
2689 "case",
2690 "esac",
2691 "function"
2692 ];
2693
2694 const LITERALS = [
2695 "true",
2696 "false"
2697 ];
2698
2699 // to consume paths to prevent keyword matches inside them
2700 const PATH_MODE = { match: /(\/[a-z._-]+)+/ };
2701
2702 // http://www.gnu.org/software/bash/manual/html_node/Shell-Builtin-Commands.html
2703 const SHELL_BUILT_INS = [
2704 "break",
2705 "cd",
2706 "continue",
2707 "eval",
2708 "exec",
2709 "exit",
2710 "export",
2711 "getopts",
2712 "hash",
2713 "pwd",
2714 "readonly",
2715 "return",
2716 "shift",
2717 "test",
2718 "times",
2719 "trap",
2720 "umask",
2721 "unset"
2722 ];
2723
2724 const BASH_BUILT_INS = [
2725 "alias",
2726 "bind",
2727 "builtin",
2728 "caller",
2729 "command",
2730 "declare",
2731 "echo",
2732 "enable",
2733 "help",
2734 "let",
2735 "local",
2736 "logout",
2737 "mapfile",
2738 "printf",
2739 "read",
2740 "readarray",
2741 "source",
2742 "type",
2743 "typeset",
2744 "ulimit",
2745 "unalias"
2746 ];
2747
2748 const ZSH_BUILT_INS = [
2749 "autoload",
2750 "bg",
2751 "bindkey",
2752 "bye",
2753 "cap",
2754 "chdir",
2755 "clone",
2756 "comparguments",
2757 "compcall",
2758 "compctl",
2759 "compdescribe",
2760 "compfiles",
2761 "compgroups",
2762 "compquote",
2763 "comptags",
2764 "comptry",
2765 "compvalues",
2766 "dirs",
2767 "disable",
2768 "disown",
2769 "echotc",
2770 "echoti",
2771 "emulate",
2772 "fc",
2773 "fg",
2774 "float",
2775 "functions",
2776 "getcap",
2777 "getln",
2778 "history",
2779 "integer",
2780 "jobs",
2781 "kill",
2782 "limit",
2783 "log",
2784 "noglob",
2785 "popd",
2786 "print",
2787 "pushd",
2788 "pushln",
2789 "rehash",
2790 "sched",
2791 "setcap",
2792 "setopt",
2793 "stat",
2794 "suspend",
2795 "ttyctl",
2796 "unfunction",
2797 "unhash",
2798 "unlimit",
2799 "unsetopt",
2800 "vared",
2801 "wait",
2802 "whence",
2803 "where",
2804 "which",
2805 "zcompile",
2806 "zformat",
2807 "zftp",
2808 "zle",
2809 "zmodload",
2810 "zparseopts",
2811 "zprof",
2812 "zpty",
2813 "zregexparse",
2814 "zsocket",
2815 "zstyle",
2816 "ztcp"
2817 ];
2818
2819 const GNU_CORE_UTILS = [
2820 "chcon",
2821 "chgrp",
2822 "chown",
2823 "chmod",
2824 "cp",
2825 "dd",
2826 "df",
2827 "dir",
2828 "dircolors",
2829 "ln",
2830 "ls",
2831 "mkdir",
2832 "mkfifo",
2833 "mknod",
2834 "mktemp",
2835 "mv",
2836 "realpath",
2837 "rm",
2838 "rmdir",
2839 "shred",
2840 "sync",
2841 "touch",
2842 "truncate",
2843 "vdir",
2844 "b2sum",
2845 "base32",
2846 "base64",
2847 "cat",
2848 "cksum",
2849 "comm",
2850 "csplit",
2851 "cut",
2852 "expand",
2853 "fmt",
2854 "fold",
2855 "head",
2856 "join",
2857 "md5sum",
2858 "nl",
2859 "numfmt",
2860 "od",
2861 "paste",
2862 "ptx",
2863 "pr",
2864 "sha1sum",
2865 "sha224sum",
2866 "sha256sum",
2867 "sha384sum",
2868 "sha512sum",
2869 "shuf",
2870 "sort",
2871 "split",
2872 "sum",
2873 "tac",
2874 "tail",
2875 "tr",
2876 "tsort",
2877 "unexpand",
2878 "uniq",
2879 "wc",
2880 "arch",
2881 "basename",
2882 "chroot",
2883 "date",
2884 "dirname",
2885 "du",
2886 "echo",
2887 "env",
2888 "expr",
2889 "factor",
2890 // "false", // keyword literal already
2891 "groups",
2892 "hostid",
2893 "id",
2894 "link",
2895 "logname",
2896 "nice",
2897 "nohup",
2898 "nproc",
2899 "pathchk",
2900 "pinky",
2901 "printenv",
2902 "printf",
2903 "pwd",
2904 "readlink",
2905 "runcon",
2906 "seq",
2907 "sleep",
2908 "stat",
2909 "stdbuf",
2910 "stty",
2911 "tee",
2912 "test",
2913 "timeout",
2914 // "true", // keyword literal already
2915 "tty",
2916 "uname",
2917 "unlink",
2918 "uptime",
2919 "users",
2920 "who",
2921 "whoami",
2922 "yes"
2923 ];
2924
2925 return {
2926 name: 'Bash',
2927 aliases: [ 'sh' ],
2928 keywords: {
2929 $pattern: /\b[a-z][a-z0-9._-]+\b/,
2930 keyword: KEYWORDS,
2931 literal: LITERALS,
2932 built_in: [
2933 ...SHELL_BUILT_INS,
2934 ...BASH_BUILT_INS,
2935 // Shell modifiers
2936 "set",
2937 "shopt",
2938 ...ZSH_BUILT_INS,
2939 ...GNU_CORE_UTILS
2940 ]
2941 },
2942 contains: [
2943 KNOWN_SHEBANG, // to catch known shells and boost relevancy
2944 hljs.SHEBANG(), // to catch unknown shells but still highlight the shebang
2945 FUNCTION,
2946 ARITHMETIC,
2947 hljs.HASH_COMMENT_MODE,
2948 HERE_DOC,
2949 PATH_MODE,
2950 QUOTE_STRING,
2951 ESCAPED_QUOTE,
2952 APOS_STRING,
2953 VAR
2954 ]
2955 };
2956 }
2957
2958 /*
2959 Language: C
2960 Category: common, system
2961 Website: https://en.wikipedia.org/wiki/C_(programming_language)
2962 */
2963
2964 /** @type LanguageFn */
2965 function c(hljs) {
2966 const regex = hljs.regex;
2967 // added for historic reasons because `hljs.C_LINE_COMMENT_MODE` does
2968 // not include such support nor can we be sure all the grammars depending
2969 // on it would desire this behavior
2970 const C_LINE_COMMENT_MODE = hljs.COMMENT('//', '$', { contains: [ { begin: /\\\n/ } ] });
2971 const DECLTYPE_AUTO_RE = 'decltype\\(auto\\)';
2972 const NAMESPACE_RE = '[a-zA-Z_]\\w*::';
2973 const TEMPLATE_ARGUMENT_RE = '<[^<>]+>';
2974 const FUNCTION_TYPE_RE = '('
2975 + DECLTYPE_AUTO_RE + '|'
2976 + regex.optional(NAMESPACE_RE)
2977 + '[a-zA-Z_]\\w*' + regex.optional(TEMPLATE_ARGUMENT_RE)
2978 + ')';
2979
2980
2981 const TYPES = {
2982 className: 'type',
2983 variants: [
2984 { begin: '\\b[a-z\\d_]*_t\\b' },
2985 { match: /\batomic_[a-z]{3,6}\b/ }
2986 ]
2987
2988 };
2989
2990 // https://en.cppreference.com/w/cpp/language/escape
2991 // \\ \x \xFF \u2837 \u00323747 \374
2992 const CHARACTER_ESCAPES = '\\\\(x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4,8}|[0-7]{3}|\\S)';
2993 const STRINGS = {
2994 className: 'string',
2995 variants: [
2996 {
2997 begin: '(u8?|U|L)?"',
2998 end: '"',
2999 illegal: '\\n',
3000 contains: [ hljs.BACKSLASH_ESCAPE ]
3001 },
3002 {
3003 begin: '(u8?|U|L)?\'(' + CHARACTER_ESCAPES + "|.)",
3004 end: '\'',
3005 illegal: '.'
3006 },
3007 hljs.END_SAME_AS_BEGIN({
3008 begin: /(?:u8?|U|L)?R"([^()\\ ]{0,16})\(/,
3009 end: /\)([^()\\ ]{0,16})"/
3010 })
3011 ]
3012 };
3013
3014 const NUMBERS = {
3015 className: 'number',
3016 variants: [
3017 { begin: '\\b(0b[01\']+)' },
3018 { begin: '(-?)\\b([\\d\']+(\\.[\\d\']*)?|\\.[\\d\']+)((ll|LL|l|L)(u|U)?|(u|U)(ll|LL|l|L)?|f|F|b|B)' },
3019 { begin: '(-?)(\\b0[xX][a-fA-F0-9\']+|(\\b[\\d\']+(\\.[\\d\']*)?|\\.[\\d\']+)([eE][-+]?[\\d\']+)?)' }
3020 ],
3021 relevance: 0
3022 };
3023
3024 const PREPROCESSOR = {
3025 className: 'meta',
3026 begin: /#\s*[a-z]+\b/,
3027 end: /$/,
3028 keywords: { keyword:
3029 'if else elif endif define undef warning error line '
3030 + 'pragma _Pragma ifdef ifndef include' },
3031 contains: [
3032 {
3033 begin: /\\\n/,
3034 relevance: 0
3035 },
3036 hljs.inherit(STRINGS, { className: 'string' }),
3037 {
3038 className: 'string',
3039 begin: /<.*?>/
3040 },
3041 C_LINE_COMMENT_MODE,
3042 hljs.C_BLOCK_COMMENT_MODE
3043 ]
3044 };
3045
3046 const TITLE_MODE = {
3047 className: 'title',
3048 begin: regex.optional(NAMESPACE_RE) + hljs.IDENT_RE,
3049 relevance: 0
3050 };
3051
3052 const FUNCTION_TITLE = regex.optional(NAMESPACE_RE) + hljs.IDENT_RE + '\\s*\\(';
3053
3054 const C_KEYWORDS = [
3055 "asm",
3056 "auto",
3057 "break",
3058 "case",
3059 "continue",
3060 "default",
3061 "do",
3062 "else",
3063 "enum",
3064 "extern",
3065 "for",
3066 "fortran",
3067 "goto",
3068 "if",
3069 "inline",
3070 "register",
3071 "restrict",
3072 "return",
3073 "sizeof",
3074 "struct",
3075 "switch",
3076 "typedef",
3077 "union",
3078 "volatile",
3079 "while",
3080 "_Alignas",
3081 "_Alignof",
3082 "_Atomic",
3083 "_Generic",
3084 "_Noreturn",
3085 "_Static_assert",
3086 "_Thread_local",
3087 // aliases
3088 "alignas",
3089 "alignof",
3090 "noreturn",
3091 "static_assert",
3092 "thread_local",
3093 // not a C keyword but is, for all intents and purposes, treated exactly like one.
3094 "_Pragma"
3095 ];
3096
3097 const C_TYPES = [
3098 "float",
3099 "double",
3100 "signed",
3101 "unsigned",
3102 "int",
3103 "short",
3104 "long",
3105 "char",
3106 "void",
3107 "_Bool",
3108 "_Complex",
3109 "_Imaginary",
3110 "_Decimal32",
3111 "_Decimal64",
3112 "_Decimal128",
3113 // modifiers
3114 "const",
3115 "static",
3116 // aliases
3117 "complex",
3118 "bool",
3119 "imaginary"
3120 ];
3121
3122 const KEYWORDS = {
3123 keyword: C_KEYWORDS,
3124 type: C_TYPES,
3125 literal: 'true false NULL',
3126 // TODO: apply hinting work similar to what was done in cpp.js
3127 built_in: 'std string wstring cin cout cerr clog stdin stdout stderr stringstream istringstream ostringstream '
3128 + 'auto_ptr deque list queue stack vector map set pair bitset multiset multimap unordered_set '
3129 + 'unordered_map unordered_multiset unordered_multimap priority_queue make_pair array shared_ptr abort terminate abs acos '
3130 + 'asin atan2 atan calloc ceil cosh cos exit exp fabs floor fmod fprintf fputs free frexp '
3131 + 'fscanf future isalnum isalpha iscntrl isdigit isgraph islower isprint ispunct isspace isupper '
3132 + 'isxdigit tolower toupper labs ldexp log10 log malloc realloc memchr memcmp memcpy memset modf pow '
3133 + 'printf putchar puts scanf sinh sin snprintf sprintf sqrt sscanf strcat strchr strcmp '
3134 + 'strcpy strcspn strlen strncat strncmp strncpy strpbrk strrchr strspn strstr tanh tan '
3135 + 'vfprintf vprintf vsprintf endl initializer_list unique_ptr',
3136 };
3137
3138 const EXPRESSION_CONTAINS = [
3139 PREPROCESSOR,
3140 TYPES,
3141 C_LINE_COMMENT_MODE,
3142 hljs.C_BLOCK_COMMENT_MODE,
3143 NUMBERS,
3144 STRINGS
3145 ];
3146
3147 const EXPRESSION_CONTEXT = {
3148 // This mode covers expression context where we can't expect a function
3149 // definition and shouldn't highlight anything that looks like one:
3150 // `return some()`, `else if()`, `(x*sum(1, 2))`
3151 variants: [
3152 {
3153 begin: /=/,
3154 end: /;/
3155 },
3156 {
3157 begin: /\(/,
3158 end: /\)/
3159 },
3160 {
3161 beginKeywords: 'new throw return else',
3162 end: /;/
3163 }
3164 ],
3165 keywords: KEYWORDS,
3166 contains: EXPRESSION_CONTAINS.concat([
3167 {
3168 begin: /\(/,
3169 end: /\)/,
3170 keywords: KEYWORDS,
3171 contains: EXPRESSION_CONTAINS.concat([ 'self' ]),
3172 relevance: 0
3173 }
3174 ]),
3175 relevance: 0
3176 };
3177
3178 const FUNCTION_DECLARATION = {
3179 begin: '(' + FUNCTION_TYPE_RE + '[\\*&\\s]+)+' + FUNCTION_TITLE,
3180 returnBegin: true,
3181 end: /[{;=]/,
3182 excludeEnd: true,
3183 keywords: KEYWORDS,
3184 illegal: /[^\w\s\*&:<>.]/,
3185 contains: [
3186 { // to prevent it from being confused as the function title
3187 begin: DECLTYPE_AUTO_RE,
3188 keywords: KEYWORDS,
3189 relevance: 0
3190 },
3191 {
3192 begin: FUNCTION_TITLE,
3193 returnBegin: true,
3194 contains: [ hljs.inherit(TITLE_MODE, { className: "title.function" }) ],
3195 relevance: 0
3196 },
3197 // allow for multiple declarations, e.g.:
3198 // extern void f(int), g(char);
3199 {
3200 relevance: 0,
3201 match: /,/
3202 },
3203 {
3204 className: 'params',
3205 begin: /\(/,
3206 end: /\)/,
3207 keywords: KEYWORDS,
3208 relevance: 0,
3209 contains: [
3210 C_LINE_COMMENT_MODE,
3211 hljs.C_BLOCK_COMMENT_MODE,
3212 STRINGS,
3213 NUMBERS,
3214 TYPES,
3215 // Count matching parentheses.
3216 {
3217 begin: /\(/,
3218 end: /\)/,
3219 keywords: KEYWORDS,
3220 relevance: 0,
3221 contains: [
3222 'self',
3223 C_LINE_COMMENT_MODE,
3224 hljs.C_BLOCK_COMMENT_MODE,
3225 STRINGS,
3226 NUMBERS,
3227 TYPES
3228 ]
3229 }
3230 ]
3231 },
3232 TYPES,
3233 C_LINE_COMMENT_MODE,
3234 hljs.C_BLOCK_COMMENT_MODE,
3235 PREPROCESSOR
3236 ]
3237 };
3238
3239 return {
3240 name: "C",
3241 aliases: [ 'h' ],
3242 keywords: KEYWORDS,
3243 // Until differentiations are added between `c` and `cpp`, `c` will
3244 // not be auto-detected to avoid auto-detect conflicts between C and C++
3245 disableAutodetect: true,
3246 illegal: '</',
3247 contains: [].concat(
3248 EXPRESSION_CONTEXT,
3249 FUNCTION_DECLARATION,
3250 EXPRESSION_CONTAINS,
3251 [
3252 PREPROCESSOR,
3253 {
3254 begin: hljs.IDENT_RE + '::',
3255 keywords: KEYWORDS
3256 },
3257 {
3258 className: 'class',
3259 beginKeywords: 'enum class struct union',
3260 end: /[{;:<>=]/,
3261 contains: [
3262 { beginKeywords: "final class struct" },
3263 hljs.TITLE_MODE
3264 ]
3265 }
3266 ]),
3267 exports: {
3268 preprocessor: PREPROCESSOR,
3269 strings: STRINGS,
3270 keywords: KEYWORDS
3271 }
3272 };
3273 }
3274
3275 /*
3276 Language: C++
3277 Category: common, system
3278 Website: https://isocpp.org
3279 */
3280
3281 /** @type LanguageFn */
3282 function cpp(hljs) {
3283 const regex = hljs.regex;
3284 // added for historic reasons because `hljs.C_LINE_COMMENT_MODE` does
3285 // not include such support nor can we be sure all the grammars depending
3286 // on it would desire this behavior
3287 const C_LINE_COMMENT_MODE = hljs.COMMENT('//', '$', { contains: [ { begin: /\\\n/ } ] });
3288 const DECLTYPE_AUTO_RE = 'decltype\\(auto\\)';
3289 const NAMESPACE_RE = '[a-zA-Z_]\\w*::';
3290 const TEMPLATE_ARGUMENT_RE = '<[^<>]+>';
3291 const FUNCTION_TYPE_RE = '(?!struct)('
3292 + DECLTYPE_AUTO_RE + '|'
3293 + regex.optional(NAMESPACE_RE)
3294 + '[a-zA-Z_]\\w*' + regex.optional(TEMPLATE_ARGUMENT_RE)
3295 + ')';
3296
3297 const CPP_PRIMITIVE_TYPES = {
3298 className: 'type',
3299 begin: '\\b[a-z\\d_]*_t\\b'
3300 };
3301
3302 // https://en.cppreference.com/w/cpp/language/escape
3303 // \\ \x \xFF \u2837 \u00323747 \374
3304 const CHARACTER_ESCAPES = '\\\\(x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4,8}|[0-7]{3}|\\S)';
3305 const STRINGS = {
3306 className: 'string',
3307 variants: [
3308 {
3309 begin: '(u8?|U|L)?"',
3310 end: '"',
3311 illegal: '\\n',
3312 contains: [ hljs.BACKSLASH_ESCAPE ]
3313 },
3314 {
3315 begin: '(u8?|U|L)?\'(' + CHARACTER_ESCAPES + '|.)',
3316 end: '\'',
3317 illegal: '.'
3318 },
3319 hljs.END_SAME_AS_BEGIN({
3320 begin: /(?:u8?|U|L)?R"([^()\\ ]{0,16})\(/,
3321 end: /\)([^()\\ ]{0,16})"/
3322 })
3323 ]
3324 };
3325
3326 const NUMBERS = {
3327 className: 'number',
3328 variants: [
3329 { begin: '\\b(0b[01\']+)' },
3330 { begin: '(-?)\\b([\\d\']+(\\.[\\d\']*)?|\\.[\\d\']+)((ll|LL|l|L)(u|U)?|(u|U)(ll|LL|l|L)?|f|F|b|B)' },
3331 { begin: '(-?)(\\b0[xX][a-fA-F0-9\']+|(\\b[\\d\']+(\\.[\\d\']*)?|\\.[\\d\']+)([eE][-+]?[\\d\']+)?)' }
3332 ],
3333 relevance: 0
3334 };
3335
3336 const PREPROCESSOR = {
3337 className: 'meta',
3338 begin: /#\s*[a-z]+\b/,
3339 end: /$/,
3340 keywords: { keyword:
3341 'if else elif endif define undef warning error line '
3342 + 'pragma _Pragma ifdef ifndef include' },
3343 contains: [
3344 {
3345 begin: /\\\n/,
3346 relevance: 0
3347 },
3348 hljs.inherit(STRINGS, { className: 'string' }),
3349 {
3350 className: 'string',
3351 begin: /<.*?>/
3352 },
3353 C_LINE_COMMENT_MODE,
3354 hljs.C_BLOCK_COMMENT_MODE
3355 ]
3356 };
3357
3358 const TITLE_MODE = {
3359 className: 'title',
3360 begin: regex.optional(NAMESPACE_RE) + hljs.IDENT_RE,
3361 relevance: 0
3362 };
3363
3364 const FUNCTION_TITLE = regex.optional(NAMESPACE_RE) + hljs.IDENT_RE + '\\s*\\(';
3365
3366 // https://en.cppreference.com/w/cpp/keyword
3367 const RESERVED_KEYWORDS = [
3368 'alignas',
3369 'alignof',
3370 'and',
3371 'and_eq',
3372 'asm',
3373 'atomic_cancel',
3374 'atomic_commit',
3375 'atomic_noexcept',
3376 'auto',
3377 'bitand',
3378 'bitor',
3379 'break',
3380 'case',
3381 'catch',
3382 'class',
3383 'co_await',
3384 'co_return',
3385 'co_yield',
3386 'compl',
3387 'concept',
3388 'const_cast|10',
3389 'consteval',
3390 'constexpr',
3391 'constinit',
3392 'continue',
3393 'decltype',
3394 'default',
3395 'delete',
3396 'do',
3397 'dynamic_cast|10',
3398 'else',
3399 'enum',
3400 'explicit',
3401 'export',
3402 'extern',
3403 'false',
3404 'final',
3405 'for',
3406 'friend',
3407 'goto',
3408 'if',
3409 'import',
3410 'inline',
3411 'module',
3412 'mutable',
3413 'namespace',
3414 'new',
3415 'noexcept',
3416 'not',
3417 'not_eq',
3418 'nullptr',
3419 'operator',
3420 'or',
3421 'or_eq',
3422 'override',
3423 'private',
3424 'protected',
3425 'public',
3426 'reflexpr',
3427 'register',
3428 'reinterpret_cast|10',
3429 'requires',
3430 'return',
3431 'sizeof',
3432 'static_assert',
3433 'static_cast|10',
3434 'struct',
3435 'switch',
3436 'synchronized',
3437 'template',
3438 'this',
3439 'thread_local',
3440 'throw',
3441 'transaction_safe',
3442 'transaction_safe_dynamic',
3443 'true',
3444 'try',
3445 'typedef',
3446 'typeid',
3447 'typename',
3448 'union',
3449 'using',
3450 'virtual',
3451 'volatile',
3452 'while',
3453 'xor',
3454 'xor_eq'
3455 ];
3456
3457 // https://en.cppreference.com/w/cpp/keyword
3458 const RESERVED_TYPES = [
3459 'bool',
3460 'char',
3461 'char16_t',
3462 'char32_t',
3463 'char8_t',
3464 'double',
3465 'float',
3466 'int',
3467 'long',
3468 'short',
3469 'void',
3470 'wchar_t',
3471 'unsigned',
3472 'signed',
3473 'const',
3474 'static'
3475 ];
3476
3477 const TYPE_HINTS = [
3478 'any',
3479 'auto_ptr',
3480 'barrier',
3481 'binary_semaphore',
3482 'bitset',
3483 'complex',
3484 'condition_variable',
3485 'condition_variable_any',
3486 'counting_semaphore',
3487 'deque',
3488 'false_type',
3489 'future',
3490 'imaginary',
3491 'initializer_list',
3492 'istringstream',
3493 'jthread',
3494 'latch',
3495 'lock_guard',
3496 'multimap',
3497 'multiset',
3498 'mutex',
3499 'optional',
3500 'ostringstream',
3501 'packaged_task',
3502 'pair',
3503 'promise',
3504 'priority_queue',
3505 'queue',
3506 'recursive_mutex',
3507 'recursive_timed_mutex',
3508 'scoped_lock',
3509 'set',
3510 'shared_future',
3511 'shared_lock',
3512 'shared_mutex',
3513 'shared_timed_mutex',
3514 'shared_ptr',
3515 'stack',
3516 'string_view',
3517 'stringstream',
3518 'timed_mutex',
3519 'thread',
3520 'true_type',
3521 'tuple',
3522 'unique_lock',
3523 'unique_ptr',
3524 'unordered_map',
3525 'unordered_multimap',
3526 'unordered_multiset',
3527 'unordered_set',
3528 'variant',
3529 'vector',
3530 'weak_ptr',
3531 'wstring',
3532 'wstring_view'
3533 ];
3534
3535 const FUNCTION_HINTS = [
3536 'abort',
3537 'abs',
3538 'acos',
3539 'apply',
3540 'as_const',
3541 'asin',
3542 'atan',
3543 'atan2',
3544 'calloc',
3545 'ceil',
3546 'cerr',
3547 'cin',
3548 'clog',
3549 'cos',
3550 'cosh',
3551 'cout',
3552 'declval',
3553 'endl',
3554 'exchange',
3555 'exit',
3556 'exp',
3557 'fabs',
3558 'floor',
3559 'fmod',
3560 'forward',
3561 'fprintf',
3562 'fputs',
3563 'free',
3564 'frexp',
3565 'fscanf',
3566 'future',
3567 'invoke',
3568 'isalnum',
3569 'isalpha',
3570 'iscntrl',
3571 'isdigit',
3572 'isgraph',
3573 'islower',
3574 'isprint',
3575 'ispunct',
3576 'isspace',
3577 'isupper',
3578 'isxdigit',
3579 'labs',
3580 'launder',
3581 'ldexp',
3582 'log',
3583 'log10',
3584 'make_pair',
3585 'make_shared',
3586 'make_shared_for_overwrite',
3587 'make_tuple',
3588 'make_unique',
3589 'malloc',
3590 'memchr',
3591 'memcmp',
3592 'memcpy',
3593 'memset',
3594 'modf',
3595 'move',
3596 'pow',
3597 'printf',
3598 'putchar',
3599 'puts',
3600 'realloc',
3601 'scanf',
3602 'sin',
3603 'sinh',
3604 'snprintf',
3605 'sprintf',
3606 'sqrt',
3607 'sscanf',
3608 'std',
3609 'stderr',
3610 'stdin',
3611 'stdout',
3612 'strcat',
3613 'strchr',
3614 'strcmp',
3615 'strcpy',
3616 'strcspn',
3617 'strlen',
3618 'strncat',
3619 'strncmp',
3620 'strncpy',
3621 'strpbrk',
3622 'strrchr',
3623 'strspn',
3624 'strstr',
3625 'swap',
3626 'tan',
3627 'tanh',
3628 'terminate',
3629 'to_underlying',
3630 'tolower',
3631 'toupper',
3632 'vfprintf',
3633 'visit',
3634 'vprintf',
3635 'vsprintf'
3636 ];
3637
3638 const LITERALS = [
3639 'NULL',
3640 'false',
3641 'nullopt',
3642 'nullptr',
3643 'true'
3644 ];
3645
3646 // https://en.cppreference.com/w/cpp/keyword
3647 const BUILT_IN = [ '_Pragma' ];
3648
3649 const CPP_KEYWORDS = {
3650 type: RESERVED_TYPES,
3651 keyword: RESERVED_KEYWORDS,
3652 literal: LITERALS,
3653 built_in: BUILT_IN,
3654 _type_hints: TYPE_HINTS
3655 };
3656
3657 const FUNCTION_DISPATCH = {
3658 className: 'function.dispatch',
3659 relevance: 0,
3660 keywords: {
3661 // Only for relevance, not highlighting.
3662 _hint: FUNCTION_HINTS },
3663 begin: regex.concat(
3664 /\b/,
3665 /(?!decltype)/,
3666 /(?!if)/,
3667 /(?!for)/,
3668 /(?!switch)/,
3669 /(?!while)/,
3670 hljs.IDENT_RE,
3671 regex.lookahead(/(<[^<>]+>|)\s*\(/))
3672 };
3673
3674 const EXPRESSION_CONTAINS = [
3675 FUNCTION_DISPATCH,
3676 PREPROCESSOR,
3677 CPP_PRIMITIVE_TYPES,
3678 C_LINE_COMMENT_MODE,
3679 hljs.C_BLOCK_COMMENT_MODE,
3680 NUMBERS,
3681 STRINGS
3682 ];
3683
3684 const EXPRESSION_CONTEXT = {
3685 // This mode covers expression context where we can't expect a function
3686 // definition and shouldn't highlight anything that looks like one:
3687 // `return some()`, `else if()`, `(x*sum(1, 2))`
3688 variants: [
3689 {
3690 begin: /=/,
3691 end: /;/
3692 },
3693 {
3694 begin: /\(/,
3695 end: /\)/
3696 },
3697 {
3698 beginKeywords: 'new throw return else',
3699 end: /;/
3700 }
3701 ],
3702 keywords: CPP_KEYWORDS,
3703 contains: EXPRESSION_CONTAINS.concat([
3704 {
3705 begin: /\(/,
3706 end: /\)/,
3707 keywords: CPP_KEYWORDS,
3708 contains: EXPRESSION_CONTAINS.concat([ 'self' ]),
3709 relevance: 0
3710 }
3711 ]),
3712 relevance: 0
3713 };
3714
3715 const FUNCTION_DECLARATION = {
3716 className: 'function',
3717 begin: '(' + FUNCTION_TYPE_RE + '[\\*&\\s]+)+' + FUNCTION_TITLE,
3718 returnBegin: true,
3719 end: /[{;=]/,
3720 excludeEnd: true,
3721 keywords: CPP_KEYWORDS,
3722 illegal: /[^\w\s\*&:<>.]/,
3723 contains: [
3724 { // to prevent it from being confused as the function title
3725 begin: DECLTYPE_AUTO_RE,
3726 keywords: CPP_KEYWORDS,
3727 relevance: 0
3728 },
3729 {
3730 begin: FUNCTION_TITLE,
3731 returnBegin: true,
3732 contains: [ TITLE_MODE ],
3733 relevance: 0
3734 },
3735 // needed because we do not have look-behind on the below rule
3736 // to prevent it from grabbing the final : in a :: pair
3737 {
3738 begin: /::/,
3739 relevance: 0
3740 },
3741 // initializers
3742 {
3743 begin: /:/,
3744 endsWithParent: true,
3745 contains: [
3746 STRINGS,
3747 NUMBERS
3748 ]
3749 },
3750 // allow for multiple declarations, e.g.:
3751 // extern void f(int), g(char);
3752 {
3753 relevance: 0,
3754 match: /,/
3755 },
3756 {
3757 className: 'params',
3758 begin: /\(/,
3759 end: /\)/,
3760 keywords: CPP_KEYWORDS,
3761 relevance: 0,
3762 contains: [
3763 C_LINE_COMMENT_MODE,
3764 hljs.C_BLOCK_COMMENT_MODE,
3765 STRINGS,
3766 NUMBERS,
3767 CPP_PRIMITIVE_TYPES,
3768 // Count matching parentheses.
3769 {
3770 begin: /\(/,
3771 end: /\)/,
3772 keywords: CPP_KEYWORDS,
3773 relevance: 0,
3774 contains: [
3775 'self',
3776 C_LINE_COMMENT_MODE,
3777 hljs.C_BLOCK_COMMENT_MODE,
3778 STRINGS,
3779 NUMBERS,
3780 CPP_PRIMITIVE_TYPES
3781 ]
3782 }
3783 ]
3784 },
3785 CPP_PRIMITIVE_TYPES,
3786 C_LINE_COMMENT_MODE,
3787 hljs.C_BLOCK_COMMENT_MODE,
3788 PREPROCESSOR
3789 ]
3790 };
3791
3792 return {
3793 name: 'C++',
3794 aliases: [
3795 'cc',
3796 'c++',
3797 'h++',
3798 'hpp',
3799 'hh',
3800 'hxx',
3801 'cxx'
3802 ],
3803 keywords: CPP_KEYWORDS,
3804 illegal: '</',
3805 classNameAliases: { 'function.dispatch': 'built_in' },
3806 contains: [].concat(
3807 EXPRESSION_CONTEXT,
3808 FUNCTION_DECLARATION,
3809 FUNCTION_DISPATCH,
3810 EXPRESSION_CONTAINS,
3811 [
3812 PREPROCESSOR,
3813 { // containers: ie, `vector <int> rooms (9);`
3814 begin: '\\b(deque|list|queue|priority_queue|pair|stack|vector|map|set|bitset|multiset|multimap|unordered_map|unordered_set|unordered_multiset|unordered_multimap|array|tuple|optional|variant|function)\\s*<(?!<)',
3815 end: '>',
3816 keywords: CPP_KEYWORDS,
3817 contains: [
3818 'self',
3819 CPP_PRIMITIVE_TYPES
3820 ]
3821 },
3822 {
3823 begin: hljs.IDENT_RE + '::',
3824 keywords: CPP_KEYWORDS
3825 },
3826 {
3827 match: [
3828 // extra complexity to deal with `enum class` and `enum struct`
3829 /\b(?:enum(?:\s+(?:class|struct))?|class|struct|union)/,
3830 /\s+/,
3831 /\w+/
3832 ],
3833 className: {
3834 1: 'keyword',
3835 3: 'title.class'
3836 }
3837 }
3838 ])
3839 };
3840 }
3841
3842 /*
3843 Language: C#
3844 Author: Jason Diamond <jason@diamond.name>
3845 Contributor: Nicolas LLOBERA <nllobera@gmail.com>, Pieter Vantorre <pietervantorre@gmail.com>, David Pine <david.pine@microsoft.com>
3846 Website: https://docs.microsoft.com/dotnet/csharp/
3847 Category: common
3848 */
3849
3850 /** @type LanguageFn */
3851 function csharp(hljs) {
3852 const BUILT_IN_KEYWORDS = [
3853 'bool',
3854 'byte',
3855 'char',
3856 'decimal',
3857 'delegate',
3858 'double',
3859 'dynamic',
3860 'enum',
3861 'float',
3862 'int',
3863 'long',
3864 'nint',
3865 'nuint',
3866 'object',
3867 'sbyte',
3868 'short',
3869 'string',
3870 'ulong',
3871 'uint',
3872 'ushort'
3873 ];
3874 const FUNCTION_MODIFIERS = [
3875 'public',
3876 'private',
3877 'protected',
3878 'static',
3879 'internal',
3880 'protected',
3881 'abstract',
3882 'async',
3883 'extern',
3884 'override',
3885 'unsafe',
3886 'virtual',
3887 'new',
3888 'sealed',
3889 'partial'
3890 ];
3891 const LITERAL_KEYWORDS = [
3892 'default',
3893 'false',
3894 'null',
3895 'true'
3896 ];
3897 const NORMAL_KEYWORDS = [
3898 'abstract',
3899 'as',
3900 'base',
3901 'break',
3902 'case',
3903 'catch',
3904 'class',
3905 'const',
3906 'continue',
3907 'do',
3908 'else',
3909 'event',
3910 'explicit',
3911 'extern',
3912 'finally',
3913 'fixed',
3914 'for',
3915 'foreach',
3916 'goto',
3917 'if',
3918 'implicit',
3919 'in',
3920 'interface',
3921 'internal',
3922 'is',
3923 'lock',
3924 'namespace',
3925 'new',
3926 'operator',
3927 'out',
3928 'override',
3929 'params',
3930 'private',
3931 'protected',
3932 'public',
3933 'readonly',
3934 'record',
3935 'ref',
3936 'return',
3937 'scoped',
3938 'sealed',
3939 'sizeof',
3940 'stackalloc',
3941 'static',
3942 'struct',
3943 'switch',
3944 'this',
3945 'throw',
3946 'try',
3947 'typeof',
3948 'unchecked',
3949 'unsafe',
3950 'using',
3951 'virtual',
3952 'void',
3953 'volatile',
3954 'while'
3955 ];
3956 const CONTEXTUAL_KEYWORDS = [
3957 'add',
3958 'alias',
3959 'and',
3960 'ascending',
3961 'async',
3962 'await',
3963 'by',
3964 'descending',
3965 'equals',
3966 'from',
3967 'get',
3968 'global',
3969 'group',
3970 'init',
3971 'into',
3972 'join',
3973 'let',
3974 'nameof',
3975 'not',
3976 'notnull',
3977 'on',
3978 'or',
3979 'orderby',
3980 'partial',
3981 'remove',
3982 'select',
3983 'set',
3984 'unmanaged',
3985 'value|0',
3986 'var',
3987 'when',
3988 'where',
3989 'with',
3990 'yield'
3991 ];
3992
3993 const KEYWORDS = {
3994 keyword: NORMAL_KEYWORDS.concat(CONTEXTUAL_KEYWORDS),
3995 built_in: BUILT_IN_KEYWORDS,
3996 literal: LITERAL_KEYWORDS
3997 };
3998 const TITLE_MODE = hljs.inherit(hljs.TITLE_MODE, { begin: '[a-zA-Z](\\.?\\w)*' });
3999 const NUMBERS = {
4000 className: 'number',
4001 variants: [
4002 { begin: '\\b(0b[01\']+)' },
4003 { begin: '(-?)\\b([\\d\']+(\\.[\\d\']*)?|\\.[\\d\']+)(u|U|l|L|ul|UL|f|F|b|B)' },
4004 { begin: '(-?)(\\b0[xX][a-fA-F0-9\']+|(\\b[\\d\']+(\\.[\\d\']*)?|\\.[\\d\']+)([eE][-+]?[\\d\']+)?)' }
4005 ],
4006 relevance: 0
4007 };
4008 const VERBATIM_STRING = {
4009 className: 'string',
4010 begin: '@"',
4011 end: '"',
4012 contains: [ { begin: '""' } ]
4013 };
4014 const VERBATIM_STRING_NO_LF = hljs.inherit(VERBATIM_STRING, { illegal: /\n/ });
4015 const SUBST = {
4016 className: 'subst',
4017 begin: /\{/,
4018 end: /\}/,
4019 keywords: KEYWORDS
4020 };
4021 const SUBST_NO_LF = hljs.inherit(SUBST, { illegal: /\n/ });
4022 const INTERPOLATED_STRING = {
4023 className: 'string',
4024 begin: /\$"/,
4025 end: '"',
4026 illegal: /\n/,
4027 contains: [
4028 { begin: /\{\{/ },
4029 { begin: /\}\}/ },
4030 hljs.BACKSLASH_ESCAPE,
4031 SUBST_NO_LF
4032 ]
4033 };
4034 const INTERPOLATED_VERBATIM_STRING = {
4035 className: 'string',
4036 begin: /\$@"/,
4037 end: '"',
4038 contains: [
4039 { begin: /\{\{/ },
4040 { begin: /\}\}/ },
4041 { begin: '""' },
4042 SUBST
4043 ]
4044 };
4045 const INTERPOLATED_VERBATIM_STRING_NO_LF = hljs.inherit(INTERPOLATED_VERBATIM_STRING, {
4046 illegal: /\n/,
4047 contains: [
4048 { begin: /\{\{/ },
4049 { begin: /\}\}/ },
4050 { begin: '""' },
4051 SUBST_NO_LF
4052 ]
4053 });
4054 SUBST.contains = [
4055 INTERPOLATED_VERBATIM_STRING,
4056 INTERPOLATED_STRING,
4057 VERBATIM_STRING,
4058 hljs.APOS_STRING_MODE,
4059 hljs.QUOTE_STRING_MODE,
4060 NUMBERS,
4061 hljs.C_BLOCK_COMMENT_MODE
4062 ];
4063 SUBST_NO_LF.contains = [
4064 INTERPOLATED_VERBATIM_STRING_NO_LF,
4065 INTERPOLATED_STRING,
4066 VERBATIM_STRING_NO_LF,
4067 hljs.APOS_STRING_MODE,
4068 hljs.QUOTE_STRING_MODE,
4069 NUMBERS,
4070 hljs.inherit(hljs.C_BLOCK_COMMENT_MODE, { illegal: /\n/ })
4071 ];
4072 const STRING = { variants: [
4073 INTERPOLATED_VERBATIM_STRING,
4074 INTERPOLATED_STRING,
4075 VERBATIM_STRING,
4076 hljs.APOS_STRING_MODE,
4077 hljs.QUOTE_STRING_MODE
4078 ] };
4079
4080 const GENERIC_MODIFIER = {
4081 begin: "<",
4082 end: ">",
4083 contains: [
4084 { beginKeywords: "in out" },
4085 TITLE_MODE
4086 ]
4087 };
4088 const TYPE_IDENT_RE = hljs.IDENT_RE + '(<' + hljs.IDENT_RE + '(\\s*,\\s*' + hljs.IDENT_RE + ')*>)?(\\[\\])?';
4089 const AT_IDENTIFIER = {
4090 // prevents expressions like `@class` from incorrect flagging
4091 // `class` as a keyword
4092 begin: "@" + hljs.IDENT_RE,
4093 relevance: 0
4094 };
4095
4096 return {
4097 name: 'C#',
4098 aliases: [
4099 'cs',
4100 'c#'
4101 ],
4102 keywords: KEYWORDS,
4103 illegal: /::/,
4104 contains: [
4105 hljs.COMMENT(
4106 '///',
4107 '$',
4108 {
4109 returnBegin: true,
4110 contains: [
4111 {
4112 className: 'doctag',
4113 variants: [
4114 {
4115 begin: '///',
4116 relevance: 0
4117 },
4118 { begin: '<!--|-->' },
4119 {
4120 begin: '</?',
4121 end: '>'
4122 }
4123 ]
4124 }
4125 ]
4126 }
4127 ),
4128 hljs.C_LINE_COMMENT_MODE,
4129 hljs.C_BLOCK_COMMENT_MODE,
4130 {
4131 className: 'meta',
4132 begin: '#',
4133 end: '$',
4134 keywords: { keyword: 'if else elif endif define undef warning error line region endregion pragma checksum' }
4135 },
4136 STRING,
4137 NUMBERS,
4138 {
4139 beginKeywords: 'class interface',
4140 relevance: 0,
4141 end: /[{;=]/,
4142 illegal: /[^\s:,]/,
4143 contains: [
4144 { beginKeywords: "where class" },
4145 TITLE_MODE,
4146 GENERIC_MODIFIER,
4147 hljs.C_LINE_COMMENT_MODE,
4148 hljs.C_BLOCK_COMMENT_MODE
4149 ]
4150 },
4151 {
4152 beginKeywords: 'namespace',
4153 relevance: 0,
4154 end: /[{;=]/,
4155 illegal: /[^\s:]/,
4156 contains: [
4157 TITLE_MODE,
4158 hljs.C_LINE_COMMENT_MODE,
4159 hljs.C_BLOCK_COMMENT_MODE
4160 ]
4161 },
4162 {
4163 beginKeywords: 'record',
4164 relevance: 0,
4165 end: /[{;=]/,
4166 illegal: /[^\s:]/,
4167 contains: [
4168 TITLE_MODE,
4169 GENERIC_MODIFIER,
4170 hljs.C_LINE_COMMENT_MODE,
4171 hljs.C_BLOCK_COMMENT_MODE
4172 ]
4173 },
4174 {
4175 // [Attributes("")]
4176 className: 'meta',
4177 begin: '^\\s*\\[(?=[\\w])',
4178 excludeBegin: true,
4179 end: '\\]',
4180 excludeEnd: true,
4181 contains: [
4182 {
4183 className: 'string',
4184 begin: /"/,
4185 end: /"/
4186 }
4187 ]
4188 },
4189 {
4190 // Expression keywords prevent 'keyword Name(...)' from being
4191 // recognized as a function definition
4192 beginKeywords: 'new return throw await else',
4193 relevance: 0
4194 },
4195 {
4196 className: 'function',
4197 begin: '(' + TYPE_IDENT_RE + '\\s+)+' + hljs.IDENT_RE + '\\s*(<[^=]+>\\s*)?\\(',
4198 returnBegin: true,
4199 end: /\s*[{;=]/,
4200 excludeEnd: true,
4201 keywords: KEYWORDS,
4202 contains: [
4203 // prevents these from being highlighted `title`
4204 {
4205 beginKeywords: FUNCTION_MODIFIERS.join(" "),
4206 relevance: 0
4207 },
4208 {
4209 begin: hljs.IDENT_RE + '\\s*(<[^=]+>\\s*)?\\(',
4210 returnBegin: true,
4211 contains: [
4212 hljs.TITLE_MODE,
4213 GENERIC_MODIFIER
4214 ],
4215 relevance: 0
4216 },
4217 { match: /\(\)/ },
4218 {
4219 className: 'params',
4220 begin: /\(/,
4221 end: /\)/,
4222 excludeBegin: true,
4223 excludeEnd: true,
4224 keywords: KEYWORDS,
4225 relevance: 0,
4226 contains: [
4227 STRING,
4228 NUMBERS,
4229 hljs.C_BLOCK_COMMENT_MODE
4230 ]
4231 },
4232 hljs.C_LINE_COMMENT_MODE,
4233 hljs.C_BLOCK_COMMENT_MODE
4234 ]
4235 },
4236 AT_IDENTIFIER
4237 ]
4238 };
4239 }
4240
4241 const MODES = (hljs) => {
4242 return {
4243 IMPORTANT: {
4244 scope: 'meta',
4245 begin: '!important'
4246 },
4247 BLOCK_COMMENT: hljs.C_BLOCK_COMMENT_MODE,
4248 HEXCOLOR: {
4249 scope: 'number',
4250 begin: /#(([0-9a-fA-F]{3,4})|(([0-9a-fA-F]{2}){3,4}))\b/
4251 },
4252 FUNCTION_DISPATCH: {
4253 className: "built_in",
4254 begin: /[\w-]+(?=\()/
4255 },
4256 ATTRIBUTE_SELECTOR_MODE: {
4257 scope: 'selector-attr',
4258 begin: /\[/,
4259 end: /\]/,
4260 illegal: '$',
4261 contains: [
4262 hljs.APOS_STRING_MODE,
4263 hljs.QUOTE_STRING_MODE
4264 ]
4265 },
4266 CSS_NUMBER_MODE: {
4267 scope: 'number',
4268 begin: hljs.NUMBER_RE + '(' +
4269 '%|em|ex|ch|rem' +
4270 '|vw|vh|vmin|vmax' +
4271 '|cm|mm|in|pt|pc|px' +
4272 '|deg|grad|rad|turn' +
4273 '|s|ms' +
4274 '|Hz|kHz' +
4275 '|dpi|dpcm|dppx' +
4276 ')?',
4277 relevance: 0
4278 },
4279 CSS_VARIABLE: {
4280 className: "attr",
4281 begin: /--[A-Za-z][A-Za-z0-9_-]*/
4282 }
4283 };
4284 };
4285
4286 const TAGS = [
4287 'a',
4288 'abbr',
4289 'address',
4290 'article',
4291 'aside',
4292 'audio',
4293 'b',
4294 'blockquote',
4295 'body',
4296 'button',
4297 'canvas',
4298 'caption',
4299 'cite',
4300 'code',
4301 'dd',
4302 'del',
4303 'details',
4304 'dfn',
4305 'div',
4306 'dl',
4307 'dt',
4308 'em',
4309 'fieldset',
4310 'figcaption',
4311 'figure',
4312 'footer',
4313 'form',
4314 'h1',
4315 'h2',
4316 'h3',
4317 'h4',
4318 'h5',
4319 'h6',
4320 'header',
4321 'hgroup',
4322 'html',
4323 'i',
4324 'iframe',
4325 'img',
4326 'input',
4327 'ins',
4328 'kbd',
4329 'label',
4330 'legend',
4331 'li',
4332 'main',
4333 'mark',
4334 'menu',
4335 'nav',
4336 'object',
4337 'ol',
4338 'p',
4339 'q',
4340 'quote',
4341 'samp',
4342 'section',
4343 'span',
4344 'strong',
4345 'summary',
4346 'sup',
4347 'table',
4348 'tbody',
4349 'td',
4350 'textarea',
4351 'tfoot',
4352 'th',
4353 'thead',
4354 'time',
4355 'tr',
4356 'ul',
4357 'var',
4358 'video'
4359 ];
4360
4361 const MEDIA_FEATURES = [
4362 'any-hover',
4363 'any-pointer',
4364 'aspect-ratio',
4365 'color',
4366 'color-gamut',
4367 'color-index',
4368 'device-aspect-ratio',
4369 'device-height',
4370 'device-width',
4371 'display-mode',
4372 'forced-colors',
4373 'grid',
4374 'height',
4375 'hover',
4376 'inverted-colors',
4377 'monochrome',
4378 'orientation',
4379 'overflow-block',
4380 'overflow-inline',
4381 'pointer',
4382 'prefers-color-scheme',
4383 'prefers-contrast',
4384 'prefers-reduced-motion',
4385 'prefers-reduced-transparency',
4386 'resolution',
4387 'scan',
4388 'scripting',
4389 'update',
4390 'width',
4391 // TODO: find a better solution?
4392 'min-width',
4393 'max-width',
4394 'min-height',
4395 'max-height'
4396 ];
4397
4398 // https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-classes
4399 const PSEUDO_CLASSES = [
4400 'active',
4401 'any-link',
4402 'blank',
4403 'checked',
4404 'current',
4405 'default',
4406 'defined',
4407 'dir', // dir()
4408 'disabled',
4409 'drop',
4410 'empty',
4411 'enabled',
4412 'first',
4413 'first-child',
4414 'first-of-type',
4415 'fullscreen',
4416 'future',
4417 'focus',
4418 'focus-visible',
4419 'focus-within',
4420 'has', // has()
4421 'host', // host or host()
4422 'host-context', // host-context()
4423 'hover',
4424 'indeterminate',
4425 'in-range',
4426 'invalid',
4427 'is', // is()
4428 'lang', // lang()
4429 'last-child',
4430 'last-of-type',
4431 'left',
4432 'link',
4433 'local-link',
4434 'not', // not()
4435 'nth-child', // nth-child()
4436 'nth-col', // nth-col()
4437 'nth-last-child', // nth-last-child()
4438 'nth-last-col', // nth-last-col()
4439 'nth-last-of-type', //nth-last-of-type()
4440 'nth-of-type', //nth-of-type()
4441 'only-child',
4442 'only-of-type',
4443 'optional',
4444 'out-of-range',
4445 'past',
4446 'placeholder-shown',
4447 'read-only',
4448 'read-write',
4449 'required',
4450 'right',
4451 'root',
4452 'scope',
4453 'target',
4454 'target-within',
4455 'user-invalid',
4456 'valid',
4457 'visited',
4458 'where' // where()
4459 ];
4460
4461 // https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-elements
4462 const PSEUDO_ELEMENTS = [
4463 'after',
4464 'backdrop',
4465 'before',
4466 'cue',
4467 'cue-region',
4468 'first-letter',
4469 'first-line',
4470 'grammar-error',
4471 'marker',
4472 'part',
4473 'placeholder',
4474 'selection',
4475 'slotted',
4476 'spelling-error'
4477 ];
4478
4479 const ATTRIBUTES = [
4480 'align-content',
4481 'align-items',
4482 'align-self',
4483 'all',
4484 'animation',
4485 'animation-delay',
4486 'animation-direction',
4487 'animation-duration',
4488 'animation-fill-mode',
4489 'animation-iteration-count',
4490 'animation-name',
4491 'animation-play-state',
4492 'animation-timing-function',
4493 'backface-visibility',
4494 'background',
4495 'background-attachment',
4496 'background-blend-mode',
4497 'background-clip',
4498 'background-color',
4499 'background-image',
4500 'background-origin',
4501 'background-position',
4502 'background-repeat',
4503 'background-size',
4504 'block-size',
4505 'border',
4506 'border-block',
4507 'border-block-color',
4508 'border-block-end',
4509 'border-block-end-color',
4510 'border-block-end-style',
4511 'border-block-end-width',
4512 'border-block-start',
4513 'border-block-start-color',
4514 'border-block-start-style',
4515 'border-block-start-width',
4516 'border-block-style',
4517 'border-block-width',
4518 'border-bottom',
4519 'border-bottom-color',
4520 'border-bottom-left-radius',
4521 'border-bottom-right-radius',
4522 'border-bottom-style',
4523 'border-bottom-width',
4524 'border-collapse',
4525 'border-color',
4526 'border-image',
4527 'border-image-outset',
4528 'border-image-repeat',
4529 'border-image-slice',
4530 'border-image-source',
4531 'border-image-width',
4532 'border-inline',
4533 'border-inline-color',
4534 'border-inline-end',
4535 'border-inline-end-color',
4536 'border-inline-end-style',
4537 'border-inline-end-width',
4538 'border-inline-start',
4539 'border-inline-start-color',
4540 'border-inline-start-style',
4541 'border-inline-start-width',
4542 'border-inline-style',
4543 'border-inline-width',
4544 'border-left',
4545 'border-left-color',
4546 'border-left-style',
4547 'border-left-width',
4548 'border-radius',
4549 'border-right',
4550 'border-right-color',
4551 'border-right-style',
4552 'border-right-width',
4553 'border-spacing',
4554 'border-style',
4555 'border-top',
4556 'border-top-color',
4557 'border-top-left-radius',
4558 'border-top-right-radius',
4559 'border-top-style',
4560 'border-top-width',
4561 'border-width',
4562 'bottom',
4563 'box-decoration-break',
4564 'box-shadow',
4565 'box-sizing',
4566 'break-after',
4567 'break-before',
4568 'break-inside',
4569 'caption-side',
4570 'caret-color',
4571 'clear',
4572 'clip',
4573 'clip-path',
4574 'clip-rule',
4575 'color',
4576 'column-count',
4577 'column-fill',
4578 'column-gap',
4579 'column-rule',
4580 'column-rule-color',
4581 'column-rule-style',
4582 'column-rule-width',
4583 'column-span',
4584 'column-width',
4585 'columns',
4586 'contain',
4587 'content',
4588 'content-visibility',
4589 'counter-increment',
4590 'counter-reset',
4591 'cue',
4592 'cue-after',
4593 'cue-before',
4594 'cursor',
4595 'direction',
4596 'display',
4597 'empty-cells',
4598 'filter',
4599 'flex',
4600 'flex-basis',
4601 'flex-direction',
4602 'flex-flow',
4603 'flex-grow',
4604 'flex-shrink',
4605 'flex-wrap',
4606 'float',
4607 'flow',
4608 'font',
4609 'font-display',
4610 'font-family',
4611 'font-feature-settings',
4612 'font-kerning',
4613 'font-language-override',
4614 'font-size',
4615 'font-size-adjust',
4616 'font-smoothing',
4617 'font-stretch',
4618 'font-style',
4619 'font-synthesis',
4620 'font-variant',
4621 'font-variant-caps',
4622 'font-variant-east-asian',
4623 'font-variant-ligatures',
4624 'font-variant-numeric',
4625 'font-variant-position',
4626 'font-variation-settings',
4627 'font-weight',
4628 'gap',
4629 'glyph-orientation-vertical',
4630 'grid',
4631 'grid-area',
4632 'grid-auto-columns',
4633 'grid-auto-flow',
4634 'grid-auto-rows',
4635 'grid-column',
4636 'grid-column-end',
4637 'grid-column-start',
4638 'grid-gap',
4639 'grid-row',
4640 'grid-row-end',
4641 'grid-row-start',
4642 'grid-template',
4643 'grid-template-areas',
4644 'grid-template-columns',
4645 'grid-template-rows',
4646 'hanging-punctuation',
4647 'height',
4648 'hyphens',
4649 'icon',
4650 'image-orientation',
4651 'image-rendering',
4652 'image-resolution',
4653 'ime-mode',
4654 'inline-size',
4655 'isolation',
4656 'justify-content',
4657 'left',
4658 'letter-spacing',
4659 'line-break',
4660 'line-height',
4661 'list-style',
4662 'list-style-image',
4663 'list-style-position',
4664 'list-style-type',
4665 'margin',
4666 'margin-block',
4667 'margin-block-end',
4668 'margin-block-start',
4669 'margin-bottom',
4670 'margin-inline',
4671 'margin-inline-end',
4672 'margin-inline-start',
4673 'margin-left',
4674 'margin-right',
4675 'margin-top',
4676 'marks',
4677 'mask',
4678 'mask-border',
4679 'mask-border-mode',
4680 'mask-border-outset',
4681 'mask-border-repeat',
4682 'mask-border-slice',
4683 'mask-border-source',
4684 'mask-border-width',
4685 'mask-clip',
4686 'mask-composite',
4687 'mask-image',
4688 'mask-mode',
4689 'mask-origin',
4690 'mask-position',
4691 'mask-repeat',
4692 'mask-size',
4693 'mask-type',
4694 'max-block-size',
4695 'max-height',
4696 'max-inline-size',
4697 'max-width',
4698 'min-block-size',
4699 'min-height',
4700 'min-inline-size',
4701 'min-width',
4702 'mix-blend-mode',
4703 'nav-down',
4704 'nav-index',
4705 'nav-left',
4706 'nav-right',
4707 'nav-up',
4708 'none',
4709 'normal',
4710 'object-fit',
4711 'object-position',
4712 'opacity',
4713 'order',
4714 'orphans',
4715 'outline',
4716 'outline-color',
4717 'outline-offset',
4718 'outline-style',
4719 'outline-width',
4720 'overflow',
4721 'overflow-wrap',
4722 'overflow-x',
4723 'overflow-y',
4724 'padding',
4725 'padding-block',
4726 'padding-block-end',
4727 'padding-block-start',
4728 'padding-bottom',
4729 'padding-inline',
4730 'padding-inline-end',
4731 'padding-inline-start',
4732 'padding-left',
4733 'padding-right',
4734 'padding-top',
4735 'page-break-after',
4736 'page-break-before',
4737 'page-break-inside',
4738 'pause',
4739 'pause-after',
4740 'pause-before',
4741 'perspective',
4742 'perspective-origin',
4743 'pointer-events',
4744 'position',
4745 'quotes',
4746 'resize',
4747 'rest',
4748 'rest-after',
4749 'rest-before',
4750 'right',
4751 'row-gap',
4752 'scroll-margin',
4753 'scroll-margin-block',
4754 'scroll-margin-block-end',
4755 'scroll-margin-block-start',
4756 'scroll-margin-bottom',
4757 'scroll-margin-inline',
4758 'scroll-margin-inline-end',
4759 'scroll-margin-inline-start',
4760 'scroll-margin-left',
4761 'scroll-margin-right',
4762 'scroll-margin-top',
4763 'scroll-padding',
4764 'scroll-padding-block',
4765 'scroll-padding-block-end',
4766 'scroll-padding-block-start',
4767 'scroll-padding-bottom',
4768 'scroll-padding-inline',
4769 'scroll-padding-inline-end',
4770 'scroll-padding-inline-start',
4771 'scroll-padding-left',
4772 'scroll-padding-right',
4773 'scroll-padding-top',
4774 'scroll-snap-align',
4775 'scroll-snap-stop',
4776 'scroll-snap-type',
4777 'scrollbar-color',
4778 'scrollbar-gutter',
4779 'scrollbar-width',
4780 'shape-image-threshold',
4781 'shape-margin',
4782 'shape-outside',
4783 'speak',
4784 'speak-as',
4785 'src', // @font-face
4786 'tab-size',
4787 'table-layout',
4788 'text-align',
4789 'text-align-all',
4790 'text-align-last',
4791 'text-combine-upright',
4792 'text-decoration',
4793 'text-decoration-color',
4794 'text-decoration-line',
4795 'text-decoration-style',
4796 'text-emphasis',
4797 'text-emphasis-color',
4798 'text-emphasis-position',
4799 'text-emphasis-style',
4800 'text-indent',
4801 'text-justify',
4802 'text-orientation',
4803 'text-overflow',
4804 'text-rendering',
4805 'text-shadow',
4806 'text-transform',
4807 'text-underline-position',
4808 'top',
4809 'transform',
4810 'transform-box',
4811 'transform-origin',
4812 'transform-style',
4813 'transition',
4814 'transition-delay',
4815 'transition-duration',
4816 'transition-property',
4817 'transition-timing-function',
4818 'unicode-bidi',
4819 'vertical-align',
4820 'visibility',
4821 'voice-balance',
4822 'voice-duration',
4823 'voice-family',
4824 'voice-pitch',
4825 'voice-range',
4826 'voice-rate',
4827 'voice-stress',
4828 'voice-volume',
4829 'white-space',
4830 'widows',
4831 'width',
4832 'will-change',
4833 'word-break',
4834 'word-spacing',
4835 'word-wrap',
4836 'writing-mode',
4837 'z-index'
4838 // reverse makes sure longer attributes `font-weight` are matched fully
4839 // instead of getting false positives on say `font`
4840 ].reverse();
4841
4842 // some grammars use them all as a single group
4843 const PSEUDO_SELECTORS = PSEUDO_CLASSES.concat(PSEUDO_ELEMENTS);
4844
4845 /*
4846 Language: CSS
4847 Category: common, css, web
4848 Website: https://developer.mozilla.org/en-US/docs/Web/CSS
4849 */
4850
4851 /** @type LanguageFn */
4852 function css(hljs) {
4853 const regex = hljs.regex;
4854 const modes = MODES(hljs);
4855 const VENDOR_PREFIX = { begin: /-(webkit|moz|ms|o)-(?=[a-z])/ };
4856 const AT_MODIFIERS = "and or not only";
4857 const AT_PROPERTY_RE = /@-?\w[\w]*(-\w+)*/; // @-webkit-keyframes
4858 const IDENT_RE = '[a-zA-Z-][a-zA-Z0-9_-]*';
4859 const STRINGS = [
4860 hljs.APOS_STRING_MODE,
4861 hljs.QUOTE_STRING_MODE
4862 ];
4863
4864 return {
4865 name: 'CSS',
4866 case_insensitive: true,
4867 illegal: /[=|'\$]/,
4868 keywords: { keyframePosition: "from to" },
4869 classNameAliases: {
4870 // for visual continuity with `tag {}` and because we
4871 // don't have a great class for this?
4872 keyframePosition: "selector-tag" },
4873 contains: [
4874 modes.BLOCK_COMMENT,
4875 VENDOR_PREFIX,
4876 // to recognize keyframe 40% etc which are outside the scope of our
4877 // attribute value mode
4878 modes.CSS_NUMBER_MODE,
4879 {
4880 className: 'selector-id',
4881 begin: /#[A-Za-z0-9_-]+/,
4882 relevance: 0
4883 },
4884 {
4885 className: 'selector-class',
4886 begin: '\\.' + IDENT_RE,
4887 relevance: 0
4888 },
4889 modes.ATTRIBUTE_SELECTOR_MODE,
4890 {
4891 className: 'selector-pseudo',
4892 variants: [
4893 { begin: ':(' + PSEUDO_CLASSES.join('|') + ')' },
4894 { begin: ':(:)?(' + PSEUDO_ELEMENTS.join('|') + ')' }
4895 ]
4896 },
4897 // we may actually need this (12/2020)
4898 // { // pseudo-selector params
4899 // begin: /\(/,
4900 // end: /\)/,
4901 // contains: [ hljs.CSS_NUMBER_MODE ]
4902 // },
4903 modes.CSS_VARIABLE,
4904 {
4905 className: 'attribute',
4906 begin: '\\b(' + ATTRIBUTES.join('|') + ')\\b'
4907 },
4908 // attribute values
4909 {
4910 begin: /:/,
4911 end: /[;}{]/,
4912 contains: [
4913 modes.BLOCK_COMMENT,
4914 modes.HEXCOLOR,
4915 modes.IMPORTANT,
4916 modes.CSS_NUMBER_MODE,
4917 ...STRINGS,
4918 // needed to highlight these as strings and to avoid issues with
4919 // illegal characters that might be inside urls that would tigger the
4920 // languages illegal stack
4921 {
4922 begin: /(url|data-uri)\(/,
4923 end: /\)/,
4924 relevance: 0, // from keywords
4925 keywords: { built_in: "url data-uri" },
4926 contains: [
4927 ...STRINGS,
4928 {
4929 className: "string",
4930 // any character other than `)` as in `url()` will be the start
4931 // of a string, which ends with `)` (from the parent mode)
4932 begin: /[^)]/,
4933 endsWithParent: true,
4934 excludeEnd: true
4935 }
4936 ]
4937 },
4938 modes.FUNCTION_DISPATCH
4939 ]
4940 },
4941 {
4942 begin: regex.lookahead(/@/),
4943 end: '[{;]',
4944 relevance: 0,
4945 illegal: /:/, // break on Less variables @var: ...
4946 contains: [
4947 {
4948 className: 'keyword',
4949 begin: AT_PROPERTY_RE
4950 },
4951 {
4952 begin: /\s/,
4953 endsWithParent: true,
4954 excludeEnd: true,
4955 relevance: 0,
4956 keywords: {
4957 $pattern: /[a-z-]+/,
4958 keyword: AT_MODIFIERS,
4959 attribute: MEDIA_FEATURES.join(" ")
4960 },
4961 contains: [
4962 {
4963 begin: /[a-z-]+(?=:)/,
4964 className: "attribute"
4965 },
4966 ...STRINGS,
4967 modes.CSS_NUMBER_MODE
4968 ]
4969 }
4970 ]
4971 },
4972 {
4973 className: 'selector-tag',
4974 begin: '\\b(' + TAGS.join('|') + ')\\b'
4975 }
4976 ]
4977 };
4978 }
4979
4980 /*
4981 Language: Diff
4982 Description: Unified and context diff
4983 Author: Vasily Polovnyov <vast@whiteants.net>
4984 Website: https://www.gnu.org/software/diffutils/
4985 Category: common
4986 */
4987
4988 /** @type LanguageFn */
4989 function diff(hljs) {
4990 const regex = hljs.regex;
4991 return {
4992 name: 'Diff',
4993 aliases: [ 'patch' ],
4994 contains: [
4995 {
4996 className: 'meta',
4997 relevance: 10,
4998 match: regex.either(
4999 /^@@ +-\d+,\d+ +\+\d+,\d+ +@@/,
5000 /^\*\*\* +\d+,\d+ +\*\*\*\*$/,
5001 /^--- +\d+,\d+ +----$/
5002 )
5003 },
5004 {
5005 className: 'comment',
5006 variants: [
5007 {
5008 begin: regex.either(
5009 /Index: /,
5010 /^index/,
5011 /={3,}/,
5012 /^-{3}/,
5013 /^\*{3} /,
5014 /^\+{3}/,
5015 /^diff --git/
5016 ),
5017 end: /$/
5018 },
5019 { match: /^\*{15}$/ }
5020 ]
5021 },
5022 {
5023 className: 'addition',
5024 begin: /^\+/,
5025 end: /$/
5026 },
5027 {
5028 className: 'deletion',
5029 begin: /^-/,
5030 end: /$/
5031 },
5032 {
5033 className: 'addition',
5034 begin: /^!/,
5035 end: /$/
5036 }
5037 ]
5038 };
5039 }
5040
5041 /*
5042 Language: Go
5043 Author: Stephan Kountso aka StepLg <steplg@gmail.com>
5044 Contributors: Evgeny Stepanischev <imbolk@gmail.com>
5045 Description: Google go language (golang). For info about language
5046 Website: http://golang.org/
5047 Category: common, system
5048 */
5049
5050 function go(hljs) {
5051 const LITERALS = [
5052 "true",
5053 "false",
5054 "iota",
5055 "nil"
5056 ];
5057 const BUILT_INS = [
5058 "append",
5059 "cap",
5060 "close",
5061 "complex",
5062 "copy",
5063 "imag",
5064 "len",
5065 "make",
5066 "new",
5067 "panic",
5068 "print",
5069 "println",
5070 "real",
5071 "recover",
5072 "delete"
5073 ];
5074 const TYPES = [
5075 "bool",
5076 "byte",
5077 "complex64",
5078 "complex128",
5079 "error",
5080 "float32",
5081 "float64",
5082 "int8",
5083 "int16",
5084 "int32",
5085 "int64",
5086 "string",
5087 "uint8",
5088 "uint16",
5089 "uint32",
5090 "uint64",
5091 "int",
5092 "uint",
5093 "uintptr",
5094 "rune"
5095 ];
5096 const KWS = [
5097 "break",
5098 "case",
5099 "chan",
5100 "const",
5101 "continue",
5102 "default",
5103 "defer",
5104 "else",
5105 "fallthrough",
5106 "for",
5107 "func",
5108 "go",
5109 "goto",
5110 "if",
5111 "import",
5112 "interface",
5113 "map",
5114 "package",
5115 "range",
5116 "return",
5117 "select",
5118 "struct",
5119 "switch",
5120 "type",
5121 "var",
5122 ];
5123 const KEYWORDS = {
5124 keyword: KWS,
5125 type: TYPES,
5126 literal: LITERALS,
5127 built_in: BUILT_INS
5128 };
5129 return {
5130 name: 'Go',
5131 aliases: [ 'golang' ],
5132 keywords: KEYWORDS,
5133 illegal: '</',
5134 contains: [
5135 hljs.C_LINE_COMMENT_MODE,
5136 hljs.C_BLOCK_COMMENT_MODE,
5137 {
5138 className: 'string',
5139 variants: [
5140 hljs.QUOTE_STRING_MODE,
5141 hljs.APOS_STRING_MODE,
5142 {
5143 begin: '`',
5144 end: '`'
5145 }
5146 ]
5147 },
5148 {
5149 className: 'number',
5150 variants: [
5151 {
5152 begin: hljs.C_NUMBER_RE + '[i]',
5153 relevance: 1
5154 },
5155 hljs.C_NUMBER_MODE
5156 ]
5157 },
5158 { begin: /:=/ // relevance booster
5159 },
5160 {
5161 className: 'function',
5162 beginKeywords: 'func',
5163 end: '\\s*(\\{|$)',
5164 excludeEnd: true,
5165 contains: [
5166 hljs.TITLE_MODE,
5167 {
5168 className: 'params',
5169 begin: /\(/,
5170 end: /\)/,
5171 endsParent: true,
5172 keywords: KEYWORDS,
5173 illegal: /["']/
5174 }
5175 ]
5176 }
5177 ]
5178 };
5179 }
5180
5181 /*
5182 Language: GraphQL
5183 Author: John Foster (GH jf990), and others
5184 Description: GraphQL is a query language for APIs
5185 Category: web, common
5186 */
5187
5188 /** @type LanguageFn */
5189 function graphql(hljs) {
5190 const regex = hljs.regex;
5191 const GQL_NAME = /[_A-Za-z][_0-9A-Za-z]*/;
5192 return {
5193 name: "GraphQL",
5194 aliases: [ "gql" ],
5195 case_insensitive: true,
5196 disableAutodetect: false,
5197 keywords: {
5198 keyword: [
5199 "query",
5200 "mutation",
5201 "subscription",
5202 "type",
5203 "input",
5204 "schema",
5205 "directive",
5206 "interface",
5207 "union",
5208 "scalar",
5209 "fragment",
5210 "enum",
5211 "on"
5212 ],
5213 literal: [
5214 "true",
5215 "false",
5216 "null"
5217 ]
5218 },
5219 contains: [
5220 hljs.HASH_COMMENT_MODE,
5221 hljs.QUOTE_STRING_MODE,
5222 hljs.NUMBER_MODE,
5223 {
5224 scope: "punctuation",
5225 match: /[.]{3}/,
5226 relevance: 0
5227 },
5228 {
5229 scope: "punctuation",
5230 begin: /[\!\(\)\:\=\[\]\{\|\}]{1}/,
5231 relevance: 0
5232 },
5233 {
5234 scope: "variable",
5235 begin: /\$/,
5236 end: /\W/,
5237 excludeEnd: true,
5238 relevance: 0
5239 },
5240 {
5241 scope: "meta",
5242 match: /@\w+/,
5243 excludeEnd: true
5244 },
5245 {
5246 scope: "symbol",
5247 begin: regex.concat(GQL_NAME, regex.lookahead(/\s*:/)),
5248 relevance: 0
5249 }
5250 ],
5251 illegal: [
5252 /[;<']/,
5253 /BEGIN/
5254 ]
5255 };
5256 }
5257
5258 /*
5259 Language: TOML, also INI
5260 Description: TOML aims to be a minimal configuration file format that's easy to read due to obvious semantics.
5261 Contributors: Guillaume Gomez <guillaume1.gomez@gmail.com>
5262 Category: common, config
5263 Website: https://github.com/toml-lang/toml
5264 */
5265
5266 function ini(hljs) {
5267 const regex = hljs.regex;
5268 const NUMBERS = {
5269 className: 'number',
5270 relevance: 0,
5271 variants: [
5272 { begin: /([+-]+)?[\d]+_[\d_]+/ },
5273 { begin: hljs.NUMBER_RE }
5274 ]
5275 };
5276 const COMMENTS = hljs.COMMENT();
5277 COMMENTS.variants = [
5278 {
5279 begin: /;/,
5280 end: /$/
5281 },
5282 {
5283 begin: /#/,
5284 end: /$/
5285 }
5286 ];
5287 const VARIABLES = {
5288 className: 'variable',
5289 variants: [
5290 { begin: /\$[\w\d"][\w\d_]*/ },
5291 { begin: /\$\{(.*?)\}/ }
5292 ]
5293 };
5294 const LITERALS = {
5295 className: 'literal',
5296 begin: /\bon|off|true|false|yes|no\b/
5297 };
5298 const STRINGS = {
5299 className: "string",
5300 contains: [ hljs.BACKSLASH_ESCAPE ],
5301 variants: [
5302 {
5303 begin: "'''",
5304 end: "'''",
5305 relevance: 10
5306 },
5307 {
5308 begin: '"""',
5309 end: '"""',
5310 relevance: 10
5311 },
5312 {
5313 begin: '"',
5314 end: '"'
5315 },
5316 {
5317 begin: "'",
5318 end: "'"
5319 }
5320 ]
5321 };
5322 const ARRAY = {
5323 begin: /\[/,
5324 end: /\]/,
5325 contains: [
5326 COMMENTS,
5327 LITERALS,
5328 VARIABLES,
5329 STRINGS,
5330 NUMBERS,
5331 'self'
5332 ],
5333 relevance: 0
5334 };
5335
5336 const BARE_KEY = /[A-Za-z0-9_-]+/;
5337 const QUOTED_KEY_DOUBLE_QUOTE = /"(\\"|[^"])*"/;
5338 const QUOTED_KEY_SINGLE_QUOTE = /'[^']*'/;
5339 const ANY_KEY = regex.either(
5340 BARE_KEY, QUOTED_KEY_DOUBLE_QUOTE, QUOTED_KEY_SINGLE_QUOTE
5341 );
5342 const DOTTED_KEY = regex.concat(
5343 ANY_KEY, '(\\s*\\.\\s*', ANY_KEY, ')*',
5344 regex.lookahead(/\s*=\s*[^#\s]/)
5345 );
5346
5347 return {
5348 name: 'TOML, also INI',
5349 aliases: [ 'toml' ],
5350 case_insensitive: true,
5351 illegal: /\S/,
5352 contains: [
5353 COMMENTS,
5354 {
5355 className: 'section',
5356 begin: /\[+/,
5357 end: /\]+/
5358 },
5359 {
5360 begin: DOTTED_KEY,
5361 className: 'attr',
5362 starts: {
5363 end: /$/,
5364 contains: [
5365 COMMENTS,
5366 ARRAY,
5367 LITERALS,
5368 VARIABLES,
5369 STRINGS,
5370 NUMBERS
5371 ]
5372 }
5373 }
5374 ]
5375 };
5376 }
5377
5378 // https://docs.oracle.com/javase/specs/jls/se15/html/jls-3.html#jls-3.10
5379 var decimalDigits = '[0-9](_*[0-9])*';
5380 var frac = `\\.(${decimalDigits})`;
5381 var hexDigits = '[0-9a-fA-F](_*[0-9a-fA-F])*';
5382 var NUMERIC = {
5383 className: 'number',
5384 variants: [
5385 // DecimalFloatingPointLiteral
5386 // including ExponentPart
5387 { begin: `(\\b(${decimalDigits})((${frac})|\\.)?|(${frac}))` +
5388 `[eE][+-]?(${decimalDigits})[fFdD]?\\b` },
5389 // excluding ExponentPart
5390 { begin: `\\b(${decimalDigits})((${frac})[fFdD]?\\b|\\.([fFdD]\\b)?)` },
5391 { begin: `(${frac})[fFdD]?\\b` },
5392 { begin: `\\b(${decimalDigits})[fFdD]\\b` },
5393
5394 // HexadecimalFloatingPointLiteral
5395 { begin: `\\b0[xX]((${hexDigits})\\.?|(${hexDigits})?\\.(${hexDigits}))` +
5396 `[pP][+-]?(${decimalDigits})[fFdD]?\\b` },
5397
5398 // DecimalIntegerLiteral
5399 { begin: '\\b(0|[1-9](_*[0-9])*)[lL]?\\b' },
5400
5401 // HexIntegerLiteral
5402 { begin: `\\b0[xX](${hexDigits})[lL]?\\b` },
5403
5404 // OctalIntegerLiteral
5405 { begin: '\\b0(_*[0-7])*[lL]?\\b' },
5406
5407 // BinaryIntegerLiteral
5408 { begin: '\\b0[bB][01](_*[01])*[lL]?\\b' },
5409 ],
5410 relevance: 0
5411 };
5412
5413 /*
5414 Language: Java
5415 Author: Vsevolod Solovyov <vsevolod.solovyov@gmail.com>
5416 Category: common, enterprise
5417 Website: https://www.java.com/
5418 */
5419
5420 /**
5421 * Allows recursive regex expressions to a given depth
5422 *
5423 * ie: recurRegex("(abc~~~)", /~~~/g, 2) becomes:
5424 * (abc(abc(abc)))
5425 *
5426 * @param {string} re
5427 * @param {RegExp} substitution (should be a g mode regex)
5428 * @param {number} depth
5429 * @returns {string}``
5430 */
5431 function recurRegex(re, substitution, depth) {
5432 if (depth === -1) return "";
5433
5434 return re.replace(substitution, _ => {
5435 return recurRegex(re, substitution, depth - 1);
5436 });
5437 }
5438
5439 /** @type LanguageFn */
5440 function java(hljs) {
5441 const regex = hljs.regex;
5442 const JAVA_IDENT_RE = '[\u00C0-\u02B8a-zA-Z_$][\u00C0-\u02B8a-zA-Z_$0-9]*';
5443 const GENERIC_IDENT_RE = JAVA_IDENT_RE
5444 + recurRegex('(?:<' + JAVA_IDENT_RE + '~~~(?:\\s*,\\s*' + JAVA_IDENT_RE + '~~~)*>)?', /~~~/g, 2);
5445 const MAIN_KEYWORDS = [
5446 'synchronized',
5447 'abstract',
5448 'private',
5449 'var',
5450 'static',
5451 'if',
5452 'const ',
5453 'for',
5454 'while',
5455 'strictfp',
5456 'finally',
5457 'protected',
5458 'import',
5459 'native',
5460 'final',
5461 'void',
5462 'enum',
5463 'else',
5464 'break',
5465 'transient',
5466 'catch',
5467 'instanceof',
5468 'volatile',
5469 'case',
5470 'assert',
5471 'package',
5472 'default',
5473 'public',
5474 'try',
5475 'switch',
5476 'continue',
5477 'throws',
5478 'protected',
5479 'public',
5480 'private',
5481 'module',
5482 'requires',
5483 'exports',
5484 'do',
5485 'sealed',
5486 'yield',
5487 'permits'
5488 ];
5489
5490 const BUILT_INS = [
5491 'super',
5492 'this'
5493 ];
5494
5495 const LITERALS = [
5496 'false',
5497 'true',
5498 'null'
5499 ];
5500
5501 const TYPES = [
5502 'char',
5503 'boolean',
5504 'long',
5505 'float',
5506 'int',
5507 'byte',
5508 'short',
5509 'double'
5510 ];
5511
5512 const KEYWORDS = {
5513 keyword: MAIN_KEYWORDS,
5514 literal: LITERALS,
5515 type: TYPES,
5516 built_in: BUILT_INS
5517 };
5518
5519 const ANNOTATION = {
5520 className: 'meta',
5521 begin: '@' + JAVA_IDENT_RE,
5522 contains: [
5523 {
5524 begin: /\(/,
5525 end: /\)/,
5526 contains: [ "self" ] // allow nested () inside our annotation
5527 }
5528 ]
5529 };
5530 const PARAMS = {
5531 className: 'params',
5532 begin: /\(/,
5533 end: /\)/,
5534 keywords: KEYWORDS,
5535 relevance: 0,
5536 contains: [ hljs.C_BLOCK_COMMENT_MODE ],
5537 endsParent: true
5538 };
5539
5540 return {
5541 name: 'Java',
5542 aliases: [ 'jsp' ],
5543 keywords: KEYWORDS,
5544 illegal: /<\/|#/,
5545 contains: [
5546 hljs.COMMENT(
5547 '/\\*\\*',
5548 '\\*/',
5549 {
5550 relevance: 0,
5551 contains: [
5552 {
5553 // eat up @'s in emails to prevent them to be recognized as doctags
5554 begin: /\w+@/,
5555 relevance: 0
5556 },
5557 {
5558 className: 'doctag',
5559 begin: '@[A-Za-z]+'
5560 }
5561 ]
5562 }
5563 ),
5564 // relevance boost
5565 {
5566 begin: /import java\.[a-z]+\./,
5567 keywords: "import",
5568 relevance: 2
5569 },
5570 hljs.C_LINE_COMMENT_MODE,
5571 hljs.C_BLOCK_COMMENT_MODE,
5572 {
5573 begin: /"""/,
5574 end: /"""/,
5575 className: "string",
5576 contains: [ hljs.BACKSLASH_ESCAPE ]
5577 },
5578 hljs.APOS_STRING_MODE,
5579 hljs.QUOTE_STRING_MODE,
5580 {
5581 match: [
5582 /\b(?:class|interface|enum|extends|implements|new)/,
5583 /\s+/,
5584 JAVA_IDENT_RE
5585 ],
5586 className: {
5587 1: "keyword",
5588 3: "title.class"
5589 }
5590 },
5591 {
5592 // Exceptions for hyphenated keywords
5593 match: /non-sealed/,
5594 scope: "keyword"
5595 },
5596 {
5597 begin: [
5598 regex.concat(/(?!else)/, JAVA_IDENT_RE),
5599 /\s+/,
5600 JAVA_IDENT_RE,
5601 /\s+/,
5602 /=(?!=)/
5603 ],
5604 className: {
5605 1: "type",
5606 3: "variable",
5607 5: "operator"
5608 }
5609 },
5610 {
5611 begin: [
5612 /record/,
5613 /\s+/,
5614 JAVA_IDENT_RE
5615 ],
5616 className: {
5617 1: "keyword",
5618 3: "title.class"
5619 },
5620 contains: [
5621 PARAMS,
5622 hljs.C_LINE_COMMENT_MODE,
5623 hljs.C_BLOCK_COMMENT_MODE
5624 ]
5625 },
5626 {
5627 // Expression keywords prevent 'keyword Name(...)' from being
5628 // recognized as a function definition
5629 beginKeywords: 'new throw return else',
5630 relevance: 0
5631 },
5632 {
5633 begin: [
5634 '(?:' + GENERIC_IDENT_RE + '\\s+)',
5635 hljs.UNDERSCORE_IDENT_RE,
5636 /\s*(?=\()/
5637 ],
5638 className: { 2: "title.function" },
5639 keywords: KEYWORDS,
5640 contains: [
5641 {
5642 className: 'params',
5643 begin: /\(/,
5644 end: /\)/,
5645 keywords: KEYWORDS,
5646 relevance: 0,
5647 contains: [
5648 ANNOTATION,
5649 hljs.APOS_STRING_MODE,
5650 hljs.QUOTE_STRING_MODE,
5651 NUMERIC,
5652 hljs.C_BLOCK_COMMENT_MODE
5653 ]
5654 },
5655 hljs.C_LINE_COMMENT_MODE,
5656 hljs.C_BLOCK_COMMENT_MODE
5657 ]
5658 },
5659 NUMERIC,
5660 ANNOTATION
5661 ]
5662 };
5663 }
5664
5665 const IDENT_RE = '[A-Za-z$_][0-9A-Za-z$_]*';
5666 const KEYWORDS = [
5667 "as", // for exports
5668 "in",
5669 "of",
5670 "if",
5671 "for",
5672 "while",
5673 "finally",
5674 "var",
5675 "new",
5676 "function",
5677 "do",
5678 "return",
5679 "void",
5680 "else",
5681 "break",
5682 "catch",
5683 "instanceof",
5684 "with",
5685 "throw",
5686 "case",
5687 "default",
5688 "try",
5689 "switch",
5690 "continue",
5691 "typeof",
5692 "delete",
5693 "let",
5694 "yield",
5695 "const",
5696 "class",
5697 // JS handles these with a special rule
5698 // "get",
5699 // "set",
5700 "debugger",
5701 "async",
5702 "await",
5703 "static",
5704 "import",
5705 "from",
5706 "export",
5707 "extends"
5708 ];
5709 const LITERALS = [
5710 "true",
5711 "false",
5712 "null",
5713 "undefined",
5714 "NaN",
5715 "Infinity"
5716 ];
5717
5718 // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects
5719 const TYPES = [
5720 // Fundamental objects
5721 "Object",
5722 "Function",
5723 "Boolean",
5724 "Symbol",
5725 // numbers and dates
5726 "Math",
5727 "Date",
5728 "Number",
5729 "BigInt",
5730 // text
5731 "String",
5732 "RegExp",
5733 // Indexed collections
5734 "Array",
5735 "Float32Array",
5736 "Float64Array",
5737 "Int8Array",
5738 "Uint8Array",
5739 "Uint8ClampedArray",
5740 "Int16Array",
5741 "Int32Array",
5742 "Uint16Array",
5743 "Uint32Array",
5744 "BigInt64Array",
5745 "BigUint64Array",
5746 // Keyed collections
5747 "Set",
5748 "Map",
5749 "WeakSet",
5750 "WeakMap",
5751 // Structured data
5752 "ArrayBuffer",
5753 "SharedArrayBuffer",
5754 "Atomics",
5755 "DataView",
5756 "JSON",
5757 // Control abstraction objects
5758 "Promise",
5759 "Generator",
5760 "GeneratorFunction",
5761 "AsyncFunction",
5762 // Reflection
5763 "Reflect",
5764 "Proxy",
5765 // Internationalization
5766 "Intl",
5767 // WebAssembly
5768 "WebAssembly"
5769 ];
5770
5771 const ERROR_TYPES = [
5772 "Error",
5773 "EvalError",
5774 "InternalError",
5775 "RangeError",
5776 "ReferenceError",
5777 "SyntaxError",
5778 "TypeError",
5779 "URIError"
5780 ];
5781
5782 const BUILT_IN_GLOBALS = [
5783 "setInterval",
5784 "setTimeout",
5785 "clearInterval",
5786 "clearTimeout",
5787
5788 "require",
5789 "exports",
5790
5791 "eval",
5792 "isFinite",
5793 "isNaN",
5794 "parseFloat",
5795 "parseInt",
5796 "decodeURI",
5797 "decodeURIComponent",
5798 "encodeURI",
5799 "encodeURIComponent",
5800 "escape",
5801 "unescape"
5802 ];
5803
5804 const BUILT_IN_VARIABLES = [
5805 "arguments",
5806 "this",
5807 "super",
5808 "console",
5809 "window",
5810 "document",
5811 "localStorage",
5812 "module",
5813 "global" // Node.js
5814 ];
5815
5816 const BUILT_INS = [].concat(
5817 BUILT_IN_GLOBALS,
5818 TYPES,
5819 ERROR_TYPES
5820 );
5821
5822 /*
5823 Language: JavaScript
5824 Description: JavaScript (JS) is a lightweight, interpreted, or just-in-time compiled programming language with first-class functions.
5825 Category: common, scripting, web
5826 Website: https://developer.mozilla.org/en-US/docs/Web/JavaScript
5827 */
5828
5829 /** @type LanguageFn */
5830 function javascript(hljs) {
5831 const regex = hljs.regex;
5832 /**
5833 * Takes a string like "<Booger" and checks to see
5834 * if we can find a matching "</Booger" later in the
5835 * content.
5836 * @param {RegExpMatchArray} match
5837 * @param {{after:number}} param1
5838 */
5839 const hasClosingTag = (match, { after }) => {
5840 const tag = "</" + match[0].slice(1);
5841 const pos = match.input.indexOf(tag, after);
5842 return pos !== -1;
5843 };
5844
5845 const IDENT_RE$1 = IDENT_RE;
5846 const FRAGMENT = {
5847 begin: '<>',
5848 end: '</>'
5849 };
5850 // to avoid some special cases inside isTrulyOpeningTag
5851 const XML_SELF_CLOSING = /<[A-Za-z0-9\\._:-]+\s*\/>/;
5852 const XML_TAG = {
5853 begin: /<[A-Za-z0-9\\._:-]+/,
5854 end: /\/[A-Za-z0-9\\._:-]+>|\/>/,
5855 /**
5856 * @param {RegExpMatchArray} match
5857 * @param {CallbackResponse} response
5858 */
5859 isTrulyOpeningTag: (match, response) => {
5860 const afterMatchIndex = match[0].length + match.index;
5861 const nextChar = match.input[afterMatchIndex];
5862 if (
5863 // HTML should not include another raw `<` inside a tag
5864 // nested type?
5865 // `<Array<Array<number>>`, etc.
5866 nextChar === "<" ||
5867 // the , gives away that this is not HTML
5868 // `<T, A extends keyof T, V>`
5869 nextChar === ","
5870 ) {
5871 response.ignoreMatch();
5872 return;
5873 }
5874
5875 // `<something>`
5876 // Quite possibly a tag, lets look for a matching closing tag...
5877 if (nextChar === ">") {
5878 // if we cannot find a matching closing tag, then we
5879 // will ignore it
5880 if (!hasClosingTag(match, { after: afterMatchIndex })) {
5881 response.ignoreMatch();
5882 }
5883 }
5884
5885 // `<blah />` (self-closing)
5886 // handled by simpleSelfClosing rule
5887
5888 let m;
5889 const afterMatch = match.input.substring(afterMatchIndex);
5890
5891 // some more template typing stuff
5892 // <T = any>(key?: string) => Modify<
5893 if ((m = afterMatch.match(/^\s*=/))) {
5894 response.ignoreMatch();
5895 return;
5896 }
5897
5898 // `<From extends string>`
5899 // technically this could be HTML, but it smells like a type
5900 // NOTE: This is ugh, but added specifically for https://github.com/highlightjs/highlight.js/issues/3276
5901 if ((m = afterMatch.match(/^\s+extends\s+/))) {
5902 if (m.index === 0) {
5903 response.ignoreMatch();
5904 // eslint-disable-next-line no-useless-return
5905 return;
5906 }
5907 }
5908 }
5909 };
5910 const KEYWORDS$1 = {
5911 $pattern: IDENT_RE,
5912 keyword: KEYWORDS,
5913 literal: LITERALS,
5914 built_in: BUILT_INS,
5915 "variable.language": BUILT_IN_VARIABLES
5916 };
5917
5918 // https://tc39.es/ecma262/#sec-literals-numeric-literals
5919 const decimalDigits = '[0-9](_?[0-9])*';
5920 const frac = `\\.(${decimalDigits})`;
5921 // DecimalIntegerLiteral, including Annex B NonOctalDecimalIntegerLiteral
5922 // https://tc39.es/ecma262/#sec-additional-syntax-numeric-literals
5923 const decimalInteger = `0|[1-9](_?[0-9])*|0[0-7]*[89][0-9]*`;
5924 const NUMBER = {
5925 className: 'number',
5926 variants: [
5927 // DecimalLiteral
5928 { begin: `(\\b(${decimalInteger})((${frac})|\\.)?|(${frac}))` +
5929 `[eE][+-]?(${decimalDigits})\\b` },
5930 { begin: `\\b(${decimalInteger})\\b((${frac})\\b|\\.)?|(${frac})\\b` },
5931
5932 // DecimalBigIntegerLiteral
5933 { begin: `\\b(0|[1-9](_?[0-9])*)n\\b` },
5934
5935 // NonDecimalIntegerLiteral
5936 { begin: "\\b0[xX][0-9a-fA-F](_?[0-9a-fA-F])*n?\\b" },
5937 { begin: "\\b0[bB][0-1](_?[0-1])*n?\\b" },
5938 { begin: "\\b0[oO][0-7](_?[0-7])*n?\\b" },
5939
5940 // LegacyOctalIntegerLiteral (does not include underscore separators)
5941 // https://tc39.es/ecma262/#sec-additional-syntax-numeric-literals
5942 { begin: "\\b0[0-7]+n?\\b" },
5943 ],
5944 relevance: 0
5945 };
5946
5947 const SUBST = {
5948 className: 'subst',
5949 begin: '\\$\\{',
5950 end: '\\}',
5951 keywords: KEYWORDS$1,
5952 contains: [] // defined later
5953 };
5954 const HTML_TEMPLATE = {
5955 begin: 'html`',
5956 end: '',
5957 starts: {
5958 end: '`',
5959 returnEnd: false,
5960 contains: [
5961 hljs.BACKSLASH_ESCAPE,
5962 SUBST
5963 ],
5964 subLanguage: 'xml'
5965 }
5966 };
5967 const CSS_TEMPLATE = {
5968 begin: 'css`',
5969 end: '',
5970 starts: {
5971 end: '`',
5972 returnEnd: false,
5973 contains: [
5974 hljs.BACKSLASH_ESCAPE,
5975 SUBST
5976 ],
5977 subLanguage: 'css'
5978 }
5979 };
5980 const TEMPLATE_STRING = {
5981 className: 'string',
5982 begin: '`',
5983 end: '`',
5984 contains: [
5985 hljs.BACKSLASH_ESCAPE,
5986 SUBST
5987 ]
5988 };
5989 const JSDOC_COMMENT = hljs.COMMENT(
5990 /\/\*\*(?!\/)/,
5991 '\\*/',
5992 {
5993 relevance: 0,
5994 contains: [
5995 {
5996 begin: '(?=@[A-Za-z]+)',
5997 relevance: 0,
5998 contains: [
5999 {
6000 className: 'doctag',
6001 begin: '@[A-Za-z]+'
6002 },
6003 {
6004 className: 'type',
6005 begin: '\\{',
6006 end: '\\}',
6007 excludeEnd: true,
6008 excludeBegin: true,
6009 relevance: 0
6010 },
6011 {
6012 className: 'variable',
6013 begin: IDENT_RE$1 + '(?=\\s*(-)|$)',
6014 endsParent: true,
6015 relevance: 0
6016 },
6017 // eat spaces (not newlines) so we can find
6018 // types or variables
6019 {
6020 begin: /(?=[^\n])\s/,
6021 relevance: 0
6022 }
6023 ]
6024 }
6025 ]
6026 }
6027 );
6028 const COMMENT = {
6029 className: "comment",
6030 variants: [
6031 JSDOC_COMMENT,
6032 hljs.C_BLOCK_COMMENT_MODE,
6033 hljs.C_LINE_COMMENT_MODE
6034 ]
6035 };
6036 const SUBST_INTERNALS = [
6037 hljs.APOS_STRING_MODE,
6038 hljs.QUOTE_STRING_MODE,
6039 HTML_TEMPLATE,
6040 CSS_TEMPLATE,
6041 TEMPLATE_STRING,
6042 // Skip numbers when they are part of a variable name
6043 { match: /\$\d+/ },
6044 NUMBER,
6045 // This is intentional:
6046 // See https://github.com/highlightjs/highlight.js/issues/3288
6047 // hljs.REGEXP_MODE
6048 ];
6049 SUBST.contains = SUBST_INTERNALS
6050 .concat({
6051 // we need to pair up {} inside our subst to prevent
6052 // it from ending too early by matching another }
6053 begin: /\{/,
6054 end: /\}/,
6055 keywords: KEYWORDS$1,
6056 contains: [
6057 "self"
6058 ].concat(SUBST_INTERNALS)
6059 });
6060 const SUBST_AND_COMMENTS = [].concat(COMMENT, SUBST.contains);
6061 const PARAMS_CONTAINS = SUBST_AND_COMMENTS.concat([
6062 // eat recursive parens in sub expressions
6063 {
6064 begin: /\(/,
6065 end: /\)/,
6066 keywords: KEYWORDS$1,
6067 contains: ["self"].concat(SUBST_AND_COMMENTS)
6068 }
6069 ]);
6070 const PARAMS = {
6071 className: 'params',
6072 begin: /\(/,
6073 end: /\)/,
6074 excludeBegin: true,
6075 excludeEnd: true,
6076 keywords: KEYWORDS$1,
6077 contains: PARAMS_CONTAINS
6078 };
6079
6080 // ES6 classes
6081 const CLASS_OR_EXTENDS = {
6082 variants: [
6083 // class Car extends vehicle
6084 {
6085 match: [
6086 /class/,
6087 /\s+/,
6088 IDENT_RE$1,
6089 /\s+/,
6090 /extends/,
6091 /\s+/,
6092 regex.concat(IDENT_RE$1, "(", regex.concat(/\./, IDENT_RE$1), ")*")
6093 ],
6094 scope: {
6095 1: "keyword",
6096 3: "title.class",
6097 5: "keyword",
6098 7: "title.class.inherited"
6099 }
6100 },
6101 // class Car
6102 {
6103 match: [
6104 /class/,
6105 /\s+/,
6106 IDENT_RE$1
6107 ],
6108 scope: {
6109 1: "keyword",
6110 3: "title.class"
6111 }
6112 },
6113
6114 ]
6115 };
6116
6117 const CLASS_REFERENCE = {
6118 relevance: 0,
6119 match:
6120 regex.either(
6121 // Hard coded exceptions
6122 /\bJSON/,
6123 // Float32Array, OutT
6124 /\b[A-Z][a-z]+([A-Z][a-z]*|\d)*/,
6125 // CSSFactory, CSSFactoryT
6126 /\b[A-Z]{2,}([A-Z][a-z]+|\d)+([A-Z][a-z]*)*/,
6127 // FPs, FPsT
6128 /\b[A-Z]{2,}[a-z]+([A-Z][a-z]+|\d)*([A-Z][a-z]*)*/,
6129 // P
6130 // single letters are not highlighted
6131 // BLAH
6132 // this will be flagged as a UPPER_CASE_CONSTANT instead
6133 ),
6134 className: "title.class",
6135 keywords: {
6136 _: [
6137 // se we still get relevance credit for JS library classes
6138 ...TYPES,
6139 ...ERROR_TYPES
6140 ]
6141 }
6142 };
6143
6144 const USE_STRICT = {
6145 label: "use_strict",
6146 className: 'meta',
6147 relevance: 10,
6148 begin: /^\s*['"]use (strict|asm)['"]/
6149 };
6150
6151 const FUNCTION_DEFINITION = {
6152 variants: [
6153 {
6154 match: [
6155 /function/,
6156 /\s+/,
6157 IDENT_RE$1,
6158 /(?=\s*\()/
6159 ]
6160 },
6161 // anonymous function
6162 {
6163 match: [
6164 /function/,
6165 /\s*(?=\()/
6166 ]
6167 }
6168 ],
6169 className: {
6170 1: "keyword",
6171 3: "title.function"
6172 },
6173 label: "func.def",
6174 contains: [ PARAMS ],
6175 illegal: /%/
6176 };
6177
6178 const UPPER_CASE_CONSTANT = {
6179 relevance: 0,
6180 match: /\b[A-Z][A-Z_0-9]+\b/,
6181 className: "variable.constant"
6182 };
6183
6184 function noneOf(list) {
6185 return regex.concat("(?!", list.join("|"), ")");
6186 }
6187
6188 const FUNCTION_CALL = {
6189 match: regex.concat(
6190 /\b/,
6191 noneOf([
6192 ...BUILT_IN_GLOBALS,
6193 "super",
6194 "import"
6195 ]),
6196 IDENT_RE$1, regex.lookahead(/\(/)),
6197 className: "title.function",
6198 relevance: 0
6199 };
6200
6201 const PROPERTY_ACCESS = {
6202 begin: regex.concat(/\./, regex.lookahead(
6203 regex.concat(IDENT_RE$1, /(?![0-9A-Za-z$_(])/)
6204 )),
6205 end: IDENT_RE$1,
6206 excludeBegin: true,
6207 keywords: "prototype",
6208 className: "property",
6209 relevance: 0
6210 };
6211
6212 const GETTER_OR_SETTER = {
6213 match: [
6214 /get|set/,
6215 /\s+/,
6216 IDENT_RE$1,
6217 /(?=\()/
6218 ],
6219 className: {
6220 1: "keyword",
6221 3: "title.function"
6222 },
6223 contains: [
6224 { // eat to avoid empty params
6225 begin: /\(\)/
6226 },
6227 PARAMS
6228 ]
6229 };
6230
6231 const FUNC_LEAD_IN_RE = '(\\(' +
6232 '[^()]*(\\(' +
6233 '[^()]*(\\(' +
6234 '[^()]*' +
6235 '\\)[^()]*)*' +
6236 '\\)[^()]*)*' +
6237 '\\)|' + hljs.UNDERSCORE_IDENT_RE + ')\\s*=>';
6238
6239 const FUNCTION_VARIABLE = {
6240 match: [
6241 /const|var|let/, /\s+/,
6242 IDENT_RE$1, /\s*/,
6243 /=\s*/,
6244 /(async\s*)?/, // async is optional
6245 regex.lookahead(FUNC_LEAD_IN_RE)
6246 ],
6247 keywords: "async",
6248 className: {
6249 1: "keyword",
6250 3: "title.function"
6251 },
6252 contains: [
6253 PARAMS
6254 ]
6255 };
6256
6257 return {
6258 name: 'Javascript',
6259 aliases: ['js', 'jsx', 'mjs', 'cjs'],
6260 keywords: KEYWORDS$1,
6261 // this will be extended by TypeScript
6262 exports: { PARAMS_CONTAINS, CLASS_REFERENCE },
6263 illegal: /#(?![$_A-z])/,
6264 contains: [
6265 hljs.SHEBANG({
6266 label: "shebang",
6267 binary: "node",
6268 relevance: 5
6269 }),
6270 USE_STRICT,
6271 hljs.APOS_STRING_MODE,
6272 hljs.QUOTE_STRING_MODE,
6273 HTML_TEMPLATE,
6274 CSS_TEMPLATE,
6275 TEMPLATE_STRING,
6276 COMMENT,
6277 // Skip numbers when they are part of a variable name
6278 { match: /\$\d+/ },
6279 NUMBER,
6280 CLASS_REFERENCE,
6281 {
6282 className: 'attr',
6283 begin: IDENT_RE$1 + regex.lookahead(':'),
6284 relevance: 0
6285 },
6286 FUNCTION_VARIABLE,
6287 { // "value" container
6288 begin: '(' + hljs.RE_STARTERS_RE + '|\\b(case|return|throw)\\b)\\s*',
6289 keywords: 'return throw case',
6290 relevance: 0,
6291 contains: [
6292 COMMENT,
6293 hljs.REGEXP_MODE,
6294 {
6295 className: 'function',
6296 // we have to count the parens to make sure we actually have the
6297 // correct bounding ( ) before the =>. There could be any number of
6298 // sub-expressions inside also surrounded by parens.
6299 begin: FUNC_LEAD_IN_RE,
6300 returnBegin: true,
6301 end: '\\s*=>',
6302 contains: [
6303 {
6304 className: 'params',
6305 variants: [
6306 {
6307 begin: hljs.UNDERSCORE_IDENT_RE,
6308 relevance: 0
6309 },
6310 {
6311 className: null,
6312 begin: /\(\s*\)/,
6313 skip: true
6314 },
6315 {
6316 begin: /\(/,
6317 end: /\)/,
6318 excludeBegin: true,
6319 excludeEnd: true,
6320 keywords: KEYWORDS$1,
6321 contains: PARAMS_CONTAINS
6322 }
6323 ]
6324 }
6325 ]
6326 },
6327 { // could be a comma delimited list of params to a function call
6328 begin: /,/,
6329 relevance: 0
6330 },
6331 {
6332 match: /\s+/,
6333 relevance: 0
6334 },
6335 { // JSX
6336 variants: [
6337 { begin: FRAGMENT.begin, end: FRAGMENT.end },
6338 { match: XML_SELF_CLOSING },
6339 {
6340 begin: XML_TAG.begin,
6341 // we carefully check the opening tag to see if it truly
6342 // is a tag and not a false positive
6343 'on:begin': XML_TAG.isTrulyOpeningTag,
6344 end: XML_TAG.end
6345 }
6346 ],
6347 subLanguage: 'xml',
6348 contains: [
6349 {
6350 begin: XML_TAG.begin,
6351 end: XML_TAG.end,
6352 skip: true,
6353 contains: ['self']
6354 }
6355 ]
6356 }
6357 ],
6358 },
6359 FUNCTION_DEFINITION,
6360 {
6361 // prevent this from getting swallowed up by function
6362 // since they appear "function like"
6363 beginKeywords: "while if switch catch for"
6364 },
6365 {
6366 // we have to count the parens to make sure we actually have the correct
6367 // bounding ( ). There could be any number of sub-expressions inside
6368 // also surrounded by parens.
6369 begin: '\\b(?!function)' + hljs.UNDERSCORE_IDENT_RE +
6370 '\\(' + // first parens
6371 '[^()]*(\\(' +
6372 '[^()]*(\\(' +
6373 '[^()]*' +
6374 '\\)[^()]*)*' +
6375 '\\)[^()]*)*' +
6376 '\\)\\s*\\{', // end parens
6377 returnBegin:true,
6378 label: "func.def",
6379 contains: [
6380 PARAMS,
6381 hljs.inherit(hljs.TITLE_MODE, { begin: IDENT_RE$1, className: "title.function" })
6382 ]
6383 },
6384 // catch ... so it won't trigger the property rule below
6385 {
6386 match: /\.\.\./,
6387 relevance: 0
6388 },
6389 PROPERTY_ACCESS,
6390 // hack: prevents detection of keywords in some circumstances
6391 // .keyword()
6392 // $keyword = x
6393 {
6394 match: '\\$' + IDENT_RE$1,
6395 relevance: 0
6396 },
6397 {
6398 match: [ /\bconstructor(?=\s*\()/ ],
6399 className: { 1: "title.function" },
6400 contains: [ PARAMS ]
6401 },
6402 FUNCTION_CALL,
6403 UPPER_CASE_CONSTANT,
6404 CLASS_OR_EXTENDS,
6405 GETTER_OR_SETTER,
6406 {
6407 match: /\$[(.]/ // relevance booster for a pattern common to JS libs: `$(something)` and `$.something`
6408 }
6409 ]
6410 };
6411 }
6412
6413 /*
6414 Language: JSON
6415 Description: JSON (JavaScript Object Notation) is a lightweight data-interchange format.
6416 Author: Ivan Sagalaev <maniac@softwaremaniacs.org>
6417 Website: http://www.json.org
6418 Category: common, protocols, web
6419 */
6420
6421 function json(hljs) {
6422 const ATTRIBUTE = {
6423 className: 'attr',
6424 begin: /"(\\.|[^\\"\r\n])*"(?=\s*:)/,
6425 relevance: 1.01
6426 };
6427 const PUNCTUATION = {
6428 match: /[{}[\],:]/,
6429 className: "punctuation",
6430 relevance: 0
6431 };
6432 const LITERALS = [
6433 "true",
6434 "false",
6435 "null"
6436 ];
6437 // NOTE: normally we would rely on `keywords` for this but using a mode here allows us
6438 // - to use the very tight `illegal: \S` rule later to flag any other character
6439 // - as illegal indicating that despite looking like JSON we do not truly have
6440 // - JSON and thus improve false-positively greatly since JSON will try and claim
6441 // - all sorts of JSON looking stuff
6442 const LITERALS_MODE = {
6443 scope: "literal",
6444 beginKeywords: LITERALS.join(" "),
6445 };
6446
6447 return {
6448 name: 'JSON',
6449 keywords:{
6450 literal: LITERALS,
6451 },
6452 contains: [
6453 ATTRIBUTE,
6454 PUNCTUATION,
6455 hljs.QUOTE_STRING_MODE,
6456 LITERALS_MODE,
6457 hljs.C_NUMBER_MODE,
6458 hljs.C_LINE_COMMENT_MODE,
6459 hljs.C_BLOCK_COMMENT_MODE
6460 ],
6461 illegal: '\\S'
6462 };
6463 }
6464
6465 /*
6466 Language: Kotlin
6467 Description: Kotlin is an OSS statically typed programming language that targets the JVM, Android, JavaScript and Native.
6468 Author: Sergey Mashkov <cy6erGn0m@gmail.com>
6469 Website: https://kotlinlang.org
6470 Category: common
6471 */
6472
6473 function kotlin(hljs) {
6474 const KEYWORDS = {
6475 keyword:
6476 'abstract as val var vararg get set class object open private protected public noinline '
6477 + 'crossinline dynamic final enum if else do while for when throw try catch finally '
6478 + 'import package is in fun override companion reified inline lateinit init '
6479 + 'interface annotation data sealed internal infix operator out by constructor super '
6480 + 'tailrec where const inner suspend typealias external expect actual',
6481 built_in:
6482 'Byte Short Char Int Long Boolean Float Double Void Unit Nothing',
6483 literal:
6484 'true false null'
6485 };
6486 const KEYWORDS_WITH_LABEL = {
6487 className: 'keyword',
6488 begin: /\b(break|continue|return|this)\b/,
6489 starts: { contains: [
6490 {
6491 className: 'symbol',
6492 begin: /@\w+/
6493 }
6494 ] }
6495 };
6496 const LABEL = {
6497 className: 'symbol',
6498 begin: hljs.UNDERSCORE_IDENT_RE + '@'
6499 };
6500
6501 // for string templates
6502 const SUBST = {
6503 className: 'subst',
6504 begin: /\$\{/,
6505 end: /\}/,
6506 contains: [ hljs.C_NUMBER_MODE ]
6507 };
6508 const VARIABLE = {
6509 className: 'variable',
6510 begin: '\\$' + hljs.UNDERSCORE_IDENT_RE
6511 };
6512 const STRING = {
6513 className: 'string',
6514 variants: [
6515 {
6516 begin: '"""',
6517 end: '"""(?=[^"])',
6518 contains: [
6519 VARIABLE,
6520 SUBST
6521 ]
6522 },
6523 // Can't use built-in modes easily, as we want to use STRING in the meta
6524 // context as 'meta-string' and there's no syntax to remove explicitly set
6525 // classNames in built-in modes.
6526 {
6527 begin: '\'',
6528 end: '\'',
6529 illegal: /\n/,
6530 contains: [ hljs.BACKSLASH_ESCAPE ]
6531 },
6532 {
6533 begin: '"',
6534 end: '"',
6535 illegal: /\n/,
6536 contains: [
6537 hljs.BACKSLASH_ESCAPE,
6538 VARIABLE,
6539 SUBST
6540 ]
6541 }
6542 ]
6543 };
6544 SUBST.contains.push(STRING);
6545
6546 const ANNOTATION_USE_SITE = {
6547 className: 'meta',
6548 begin: '@(?:file|property|field|get|set|receiver|param|setparam|delegate)\\s*:(?:\\s*' + hljs.UNDERSCORE_IDENT_RE + ')?'
6549 };
6550 const ANNOTATION = {
6551 className: 'meta',
6552 begin: '@' + hljs.UNDERSCORE_IDENT_RE,
6553 contains: [
6554 {
6555 begin: /\(/,
6556 end: /\)/,
6557 contains: [
6558 hljs.inherit(STRING, { className: 'string' }),
6559 "self"
6560 ]
6561 }
6562 ]
6563 };
6564
6565 // https://kotlinlang.org/docs/reference/whatsnew11.html#underscores-in-numeric-literals
6566 // According to the doc above, the number mode of kotlin is the same as java 8,
6567 // so the code below is copied from java.js
6568 const KOTLIN_NUMBER_MODE = NUMERIC;
6569 const KOTLIN_NESTED_COMMENT = hljs.COMMENT(
6570 '/\\*', '\\*/',
6571 { contains: [ hljs.C_BLOCK_COMMENT_MODE ] }
6572 );
6573 const KOTLIN_PAREN_TYPE = { variants: [
6574 {
6575 className: 'type',
6576 begin: hljs.UNDERSCORE_IDENT_RE
6577 },
6578 {
6579 begin: /\(/,
6580 end: /\)/,
6581 contains: [] // defined later
6582 }
6583 ] };
6584 const KOTLIN_PAREN_TYPE2 = KOTLIN_PAREN_TYPE;
6585 KOTLIN_PAREN_TYPE2.variants[1].contains = [ KOTLIN_PAREN_TYPE ];
6586 KOTLIN_PAREN_TYPE.variants[1].contains = [ KOTLIN_PAREN_TYPE2 ];
6587
6588 return {
6589 name: 'Kotlin',
6590 aliases: [
6591 'kt',
6592 'kts'
6593 ],
6594 keywords: KEYWORDS,
6595 contains: [
6596 hljs.COMMENT(
6597 '/\\*\\*',
6598 '\\*/',
6599 {
6600 relevance: 0,
6601 contains: [
6602 {
6603 className: 'doctag',
6604 begin: '@[A-Za-z]+'
6605 }
6606 ]
6607 }
6608 ),
6609 hljs.C_LINE_COMMENT_MODE,
6610 KOTLIN_NESTED_COMMENT,
6611 KEYWORDS_WITH_LABEL,
6612 LABEL,
6613 ANNOTATION_USE_SITE,
6614 ANNOTATION,
6615 {
6616 className: 'function',
6617 beginKeywords: 'fun',
6618 end: '[(]|$',
6619 returnBegin: true,
6620 excludeEnd: true,
6621 keywords: KEYWORDS,
6622 relevance: 5,
6623 contains: [
6624 {
6625 begin: hljs.UNDERSCORE_IDENT_RE + '\\s*\\(',
6626 returnBegin: true,
6627 relevance: 0,
6628 contains: [ hljs.UNDERSCORE_TITLE_MODE ]
6629 },
6630 {
6631 className: 'type',
6632 begin: /</,
6633 end: />/,
6634 keywords: 'reified',
6635 relevance: 0
6636 },
6637 {
6638 className: 'params',
6639 begin: /\(/,
6640 end: /\)/,
6641 endsParent: true,
6642 keywords: KEYWORDS,
6643 relevance: 0,
6644 contains: [
6645 {
6646 begin: /:/,
6647 end: /[=,\/]/,
6648 endsWithParent: true,
6649 contains: [
6650 KOTLIN_PAREN_TYPE,
6651 hljs.C_LINE_COMMENT_MODE,
6652 KOTLIN_NESTED_COMMENT
6653 ],
6654 relevance: 0
6655 },
6656 hljs.C_LINE_COMMENT_MODE,
6657 KOTLIN_NESTED_COMMENT,
6658 ANNOTATION_USE_SITE,
6659 ANNOTATION,
6660 STRING,
6661 hljs.C_NUMBER_MODE
6662 ]
6663 },
6664 KOTLIN_NESTED_COMMENT
6665 ]
6666 },
6667 {
6668 begin: [
6669 /class|interface|trait/,
6670 /\s+/,
6671 hljs.UNDERSCORE_IDENT_RE
6672 ],
6673 beginScope: {
6674 3: "title.class"
6675 },
6676 keywords: 'class interface trait',
6677 end: /[:\{(]|$/,
6678 excludeEnd: true,
6679 illegal: 'extends implements',
6680 contains: [
6681 { beginKeywords: 'public protected internal private constructor' },
6682 hljs.UNDERSCORE_TITLE_MODE,
6683 {
6684 className: 'type',
6685 begin: /</,
6686 end: />/,
6687 excludeBegin: true,
6688 excludeEnd: true,
6689 relevance: 0
6690 },
6691 {
6692 className: 'type',
6693 begin: /[,:]\s*/,
6694 end: /[<\(,){\s]|$/,
6695 excludeBegin: true,
6696 returnEnd: true
6697 },
6698 ANNOTATION_USE_SITE,
6699 ANNOTATION
6700 ]
6701 },
6702 STRING,
6703 {
6704 className: 'meta',
6705 begin: "^#!/usr/bin/env",
6706 end: '$',
6707 illegal: '\n'
6708 },
6709 KOTLIN_NUMBER_MODE
6710 ]
6711 };
6712 }
6713
6714 /*
6715 Language: Less
6716 Description: It's CSS, with just a little more.
6717 Author: Max Mikhailov <seven.phases.max@gmail.com>
6718 Website: http://lesscss.org
6719 Category: common, css, web
6720 */
6721
6722 /** @type LanguageFn */
6723 function less(hljs) {
6724 const modes = MODES(hljs);
6725 const PSEUDO_SELECTORS$1 = PSEUDO_SELECTORS;
6726
6727 const AT_MODIFIERS = "and or not only";
6728 const IDENT_RE = '[\\w-]+'; // yes, Less identifiers may begin with a digit
6729 const INTERP_IDENT_RE = '(' + IDENT_RE + '|@\\{' + IDENT_RE + '\\})';
6730
6731 /* Generic Modes */
6732
6733 const RULES = []; const VALUE_MODES = []; // forward def. for recursive modes
6734
6735 const STRING_MODE = function(c) {
6736 return {
6737 // Less strings are not multiline (also include '~' for more consistent coloring of "escaped" strings)
6738 className: 'string',
6739 begin: '~?' + c + '.*?' + c
6740 };
6741 };
6742
6743 const IDENT_MODE = function(name, begin, relevance) {
6744 return {
6745 className: name,
6746 begin: begin,
6747 relevance: relevance
6748 };
6749 };
6750
6751 const AT_KEYWORDS = {
6752 $pattern: /[a-z-]+/,
6753 keyword: AT_MODIFIERS,
6754 attribute: MEDIA_FEATURES.join(" ")
6755 };
6756
6757 const PARENS_MODE = {
6758 // used only to properly balance nested parens inside mixin call, def. arg list
6759 begin: '\\(',
6760 end: '\\)',
6761 contains: VALUE_MODES,
6762 keywords: AT_KEYWORDS,
6763 relevance: 0
6764 };
6765
6766 // generic Less highlighter (used almost everywhere except selectors):
6767 VALUE_MODES.push(
6768 hljs.C_LINE_COMMENT_MODE,
6769 hljs.C_BLOCK_COMMENT_MODE,
6770 STRING_MODE("'"),
6771 STRING_MODE('"'),
6772 modes.CSS_NUMBER_MODE, // fixme: it does not include dot for numbers like .5em :(
6773 {
6774 begin: '(url|data-uri)\\(',
6775 starts: {
6776 className: 'string',
6777 end: '[\\)\\n]',
6778 excludeEnd: true
6779 }
6780 },
6781 modes.HEXCOLOR,
6782 PARENS_MODE,
6783 IDENT_MODE('variable', '@@?' + IDENT_RE, 10),
6784 IDENT_MODE('variable', '@\\{' + IDENT_RE + '\\}'),
6785 IDENT_MODE('built_in', '~?`[^`]*?`'), // inline javascript (or whatever host language) *multiline* string
6786 { // @media features (it’s here to not duplicate things in AT_RULE_MODE with extra PARENS_MODE overriding):
6787 className: 'attribute',
6788 begin: IDENT_RE + '\\s*:',
6789 end: ':',
6790 returnBegin: true,
6791 excludeEnd: true
6792 },
6793 modes.IMPORTANT,
6794 { beginKeywords: 'and not' },
6795 modes.FUNCTION_DISPATCH
6796 );
6797
6798 const VALUE_WITH_RULESETS = VALUE_MODES.concat({
6799 begin: /\{/,
6800 end: /\}/,
6801 contains: RULES
6802 });
6803
6804 const MIXIN_GUARD_MODE = {
6805 beginKeywords: 'when',
6806 endsWithParent: true,
6807 contains: [ { beginKeywords: 'and not' } ].concat(VALUE_MODES) // using this form to override VALUE’s 'function' match
6808 };
6809
6810 /* Rule-Level Modes */
6811
6812 const RULE_MODE = {
6813 begin: INTERP_IDENT_RE + '\\s*:',
6814 returnBegin: true,
6815 end: /[;}]/,
6816 relevance: 0,
6817 contains: [
6818 { begin: /-(webkit|moz|ms|o)-/ },
6819 modes.CSS_VARIABLE,
6820 {
6821 className: 'attribute',
6822 begin: '\\b(' + ATTRIBUTES.join('|') + ')\\b',
6823 end: /(?=:)/,
6824 starts: {
6825 endsWithParent: true,
6826 illegal: '[<=$]',
6827 relevance: 0,
6828 contains: VALUE_MODES
6829 }
6830 }
6831 ]
6832 };
6833
6834 const AT_RULE_MODE = {
6835 className: 'keyword',
6836 begin: '@(import|media|charset|font-face|(-[a-z]+-)?keyframes|supports|document|namespace|page|viewport|host)\\b',
6837 starts: {
6838 end: '[;{}]',
6839 keywords: AT_KEYWORDS,
6840 returnEnd: true,
6841 contains: VALUE_MODES,
6842 relevance: 0
6843 }
6844 };
6845
6846 // variable definitions and calls
6847 const VAR_RULE_MODE = {
6848 className: 'variable',
6849 variants: [
6850 // using more strict pattern for higher relevance to increase chances of Less detection.
6851 // this is *the only* Less specific statement used in most of the sources, so...
6852 // (we’ll still often loose to the css-parser unless there's '//' comment,
6853 // simply because 1 variable just can't beat 99 properties :)
6854 {
6855 begin: '@' + IDENT_RE + '\\s*:',
6856 relevance: 15
6857 },
6858 { begin: '@' + IDENT_RE }
6859 ],
6860 starts: {
6861 end: '[;}]',
6862 returnEnd: true,
6863 contains: VALUE_WITH_RULESETS
6864 }
6865 };
6866
6867 const SELECTOR_MODE = {
6868 // first parse unambiguous selectors (i.e. those not starting with tag)
6869 // then fall into the scary lookahead-discriminator variant.
6870 // this mode also handles mixin definitions and calls
6871 variants: [
6872 {
6873 begin: '[\\.#:&\\[>]',
6874 end: '[;{}]' // mixin calls end with ';'
6875 },
6876 {
6877 begin: INTERP_IDENT_RE,
6878 end: /\{/
6879 }
6880 ],
6881 returnBegin: true,
6882 returnEnd: true,
6883 illegal: '[<=\'$"]',
6884 relevance: 0,
6885 contains: [
6886 hljs.C_LINE_COMMENT_MODE,
6887 hljs.C_BLOCK_COMMENT_MODE,
6888 MIXIN_GUARD_MODE,
6889 IDENT_MODE('keyword', 'all\\b'),
6890 IDENT_MODE('variable', '@\\{' + IDENT_RE + '\\}'), // otherwise it’s identified as tag
6891
6892 {
6893 begin: '\\b(' + TAGS.join('|') + ')\\b',
6894 className: 'selector-tag'
6895 },
6896 modes.CSS_NUMBER_MODE,
6897 IDENT_MODE('selector-tag', INTERP_IDENT_RE, 0),
6898 IDENT_MODE('selector-id', '#' + INTERP_IDENT_RE),
6899 IDENT_MODE('selector-class', '\\.' + INTERP_IDENT_RE, 0),
6900 IDENT_MODE('selector-tag', '&', 0),
6901 modes.ATTRIBUTE_SELECTOR_MODE,
6902 {
6903 className: 'selector-pseudo',
6904 begin: ':(' + PSEUDO_CLASSES.join('|') + ')'
6905 },
6906 {
6907 className: 'selector-pseudo',
6908 begin: ':(:)?(' + PSEUDO_ELEMENTS.join('|') + ')'
6909 },
6910 {
6911 begin: /\(/,
6912 end: /\)/,
6913 relevance: 0,
6914 contains: VALUE_WITH_RULESETS
6915 }, // argument list of parametric mixins
6916 { begin: '!important' }, // eat !important after mixin call or it will be colored as tag
6917 modes.FUNCTION_DISPATCH
6918 ]
6919 };
6920
6921 const PSEUDO_SELECTOR_MODE = {
6922 begin: IDENT_RE + ':(:)?' + `(${PSEUDO_SELECTORS$1.join('|')})`,
6923 returnBegin: true,
6924 contains: [ SELECTOR_MODE ]
6925 };
6926
6927 RULES.push(
6928 hljs.C_LINE_COMMENT_MODE,
6929 hljs.C_BLOCK_COMMENT_MODE,
6930 AT_RULE_MODE,
6931 VAR_RULE_MODE,
6932 PSEUDO_SELECTOR_MODE,
6933 RULE_MODE,
6934 SELECTOR_MODE,
6935 MIXIN_GUARD_MODE,
6936 modes.FUNCTION_DISPATCH
6937 );
6938
6939 return {
6940 name: 'Less',
6941 case_insensitive: true,
6942 illegal: '[=>\'/<($"]',
6943 contains: RULES
6944 };
6945 }
6946
6947 /*
6948 Language: Lua
6949 Description: Lua is a powerful, efficient, lightweight, embeddable scripting language.
6950 Author: Andrew Fedorov <dmmdrs@mail.ru>
6951 Category: common, scripting
6952 Website: https://www.lua.org
6953 */
6954
6955 function lua(hljs) {
6956 const OPENING_LONG_BRACKET = '\\[=*\\[';
6957 const CLOSING_LONG_BRACKET = '\\]=*\\]';
6958 const LONG_BRACKETS = {
6959 begin: OPENING_LONG_BRACKET,
6960 end: CLOSING_LONG_BRACKET,
6961 contains: [ 'self' ]
6962 };
6963 const COMMENTS = [
6964 hljs.COMMENT('--(?!' + OPENING_LONG_BRACKET + ')', '$'),
6965 hljs.COMMENT(
6966 '--' + OPENING_LONG_BRACKET,
6967 CLOSING_LONG_BRACKET,
6968 {
6969 contains: [ LONG_BRACKETS ],
6970 relevance: 10
6971 }
6972 )
6973 ];
6974 return {
6975 name: 'Lua',
6976 keywords: {
6977 $pattern: hljs.UNDERSCORE_IDENT_RE,
6978 literal: "true false nil",
6979 keyword: "and break do else elseif end for goto if in local not or repeat return then until while",
6980 built_in:
6981 // Metatags and globals:
6982 '_G _ENV _VERSION __index __newindex __mode __call __metatable __tostring __len '
6983 + '__gc __add __sub __mul __div __mod __pow __concat __unm __eq __lt __le assert '
6984 // Standard methods and properties:
6985 + 'collectgarbage dofile error getfenv getmetatable ipairs load loadfile loadstring '
6986 + 'module next pairs pcall print rawequal rawget rawset require select setfenv '
6987 + 'setmetatable tonumber tostring type unpack xpcall arg self '
6988 // Library methods and properties (one line per library):
6989 + 'coroutine resume yield status wrap create running debug getupvalue '
6990 + 'debug sethook getmetatable gethook setmetatable setlocal traceback setfenv getinfo setupvalue getlocal getregistry getfenv '
6991 + 'io lines write close flush open output type read stderr stdin input stdout popen tmpfile '
6992 + 'math log max acos huge ldexp pi cos tanh pow deg tan cosh sinh random randomseed frexp ceil floor rad abs sqrt modf asin min mod fmod log10 atan2 exp sin atan '
6993 + 'os exit setlocale date getenv difftime remove time clock tmpname rename execute package preload loadlib loaded loaders cpath config path seeall '
6994 + 'string sub upper len gfind rep find match char dump gmatch reverse byte format gsub lower '
6995 + 'table setn insert getn foreachi maxn foreach concat sort remove'
6996 },
6997 contains: COMMENTS.concat([
6998 {
6999 className: 'function',
7000 beginKeywords: 'function',
7001 end: '\\)',
7002 contains: [
7003 hljs.inherit(hljs.TITLE_MODE, { begin: '([_a-zA-Z]\\w*\\.)*([_a-zA-Z]\\w*:)?[_a-zA-Z]\\w*' }),
7004 {
7005 className: 'params',
7006 begin: '\\(',
7007 endsWithParent: true,
7008 contains: COMMENTS
7009 }
7010 ].concat(COMMENTS)
7011 },
7012 hljs.C_NUMBER_MODE,
7013 hljs.APOS_STRING_MODE,
7014 hljs.QUOTE_STRING_MODE,
7015 {
7016 className: 'string',
7017 begin: OPENING_LONG_BRACKET,
7018 end: CLOSING_LONG_BRACKET,
7019 contains: [ LONG_BRACKETS ],
7020 relevance: 5
7021 }
7022 ])
7023 };
7024 }
7025
7026 /*
7027 Language: Makefile
7028 Author: Ivan Sagalaev <maniac@softwaremaniacs.org>
7029 Contributors: Joël Porquet <joel@porquet.org>
7030 Website: https://www.gnu.org/software/make/manual/html_node/Introduction.html
7031 Category: common
7032 */
7033
7034 function makefile(hljs) {
7035 /* Variables: simple (eg $(var)) and special (eg $@) */
7036 const VARIABLE = {
7037 className: 'variable',
7038 variants: [
7039 {
7040 begin: '\\$\\(' + hljs.UNDERSCORE_IDENT_RE + '\\)',
7041 contains: [ hljs.BACKSLASH_ESCAPE ]
7042 },
7043 { begin: /\$[@%<?\^\+\*]/ }
7044 ]
7045 };
7046 /* Quoted string with variables inside */
7047 const QUOTE_STRING = {
7048 className: 'string',
7049 begin: /"/,
7050 end: /"/,
7051 contains: [
7052 hljs.BACKSLASH_ESCAPE,
7053 VARIABLE
7054 ]
7055 };
7056 /* Function: $(func arg,...) */
7057 const FUNC = {
7058 className: 'variable',
7059 begin: /\$\([\w-]+\s/,
7060 end: /\)/,
7061 keywords: { built_in:
7062 'subst patsubst strip findstring filter filter-out sort '
7063 + 'word wordlist firstword lastword dir notdir suffix basename '
7064 + 'addsuffix addprefix join wildcard realpath abspath error warning '
7065 + 'shell origin flavor foreach if or and call eval file value' },
7066 contains: [ VARIABLE ]
7067 };
7068 /* Variable assignment */
7069 const ASSIGNMENT = { begin: '^' + hljs.UNDERSCORE_IDENT_RE + '\\s*(?=[:+?]?=)' };
7070 /* Meta targets (.PHONY) */
7071 const META = {
7072 className: 'meta',
7073 begin: /^\.PHONY:/,
7074 end: /$/,
7075 keywords: {
7076 $pattern: /[\.\w]+/,
7077 keyword: '.PHONY'
7078 }
7079 };
7080 /* Targets */
7081 const TARGET = {
7082 className: 'section',
7083 begin: /^[^\s]+:/,
7084 end: /$/,
7085 contains: [ VARIABLE ]
7086 };
7087 return {
7088 name: 'Makefile',
7089 aliases: [
7090 'mk',
7091 'mak',
7092 'make',
7093 ],
7094 keywords: {
7095 $pattern: /[\w-]+/,
7096 keyword: 'define endef undefine ifdef ifndef ifeq ifneq else endif '
7097 + 'include -include sinclude override export unexport private vpath'
7098 },
7099 contains: [
7100 hljs.HASH_COMMENT_MODE,
7101 VARIABLE,
7102 QUOTE_STRING,
7103 FUNC,
7104 ASSIGNMENT,
7105 META,
7106 TARGET
7107 ]
7108 };
7109 }
7110
7111 /*
7112 Language: HTML, XML
7113 Website: https://www.w3.org/XML/
7114 Category: common, web
7115 Audit: 2020
7116 */
7117
7118 /** @type LanguageFn */
7119 function xml(hljs) {
7120 const regex = hljs.regex;
7121 // XML names can have the following additional letters: https://www.w3.org/TR/xml/#NT-NameChar
7122 // OTHER_NAME_CHARS = /[:\-.0-9\u00B7\u0300-\u036F\u203F-\u2040]/;
7123 // Element names start with NAME_START_CHAR followed by optional other Unicode letters, ASCII digits, hyphens, underscores, and periods
7124 // const TAG_NAME_RE = regex.concat(/[A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD]/, regex.optional(/[A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\-.0-9\u00B7\u0300-\u036F\u203F-\u2040]*:/), /[A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\-.0-9\u00B7\u0300-\u036F\u203F-\u2040]*/);;
7125 // const XML_IDENT_RE = /[A-Z_a-z:\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\-.0-9\u00B7\u0300-\u036F\u203F-\u2040]+/;
7126 // const TAG_NAME_RE = regex.concat(/[A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD]/, regex.optional(/[A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\-.0-9\u00B7\u0300-\u036F\u203F-\u2040]*:/), /[A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\-.0-9\u00B7\u0300-\u036F\u203F-\u2040]*/);
7127 // however, to cater for performance and more Unicode support rely simply on the Unicode letter class
7128 const TAG_NAME_RE = regex.concat(/[\p{L}_]/u, regex.optional(/[\p{L}0-9_.-]*:/u), /[\p{L}0-9_.-]*/u);
7129 const XML_IDENT_RE = /[\p{L}0-9._:-]+/u;
7130 const XML_ENTITIES = {
7131 className: 'symbol',
7132 begin: /&[a-z]+;|&#[0-9]+;|&#x[a-f0-9]+;/
7133 };
7134 const XML_META_KEYWORDS = {
7135 begin: /\s/,
7136 contains: [
7137 {
7138 className: 'keyword',
7139 begin: /#?[a-z_][a-z1-9_-]+/,
7140 illegal: /\n/
7141 }
7142 ]
7143 };
7144 const XML_META_PAR_KEYWORDS = hljs.inherit(XML_META_KEYWORDS, {
7145 begin: /\(/,
7146 end: /\)/
7147 });
7148 const APOS_META_STRING_MODE = hljs.inherit(hljs.APOS_STRING_MODE, { className: 'string' });
7149 const QUOTE_META_STRING_MODE = hljs.inherit(hljs.QUOTE_STRING_MODE, { className: 'string' });
7150 const TAG_INTERNALS = {
7151 endsWithParent: true,
7152 illegal: /</,
7153 relevance: 0,
7154 contains: [
7155 {
7156 className: 'attr',
7157 begin: XML_IDENT_RE,
7158 relevance: 0
7159 },
7160 {
7161 begin: /=\s*/,
7162 relevance: 0,
7163 contains: [
7164 {
7165 className: 'string',
7166 endsParent: true,
7167 variants: [
7168 {
7169 begin: /"/,
7170 end: /"/,
7171 contains: [ XML_ENTITIES ]
7172 },
7173 {
7174 begin: /'/,
7175 end: /'/,
7176 contains: [ XML_ENTITIES ]
7177 },
7178 { begin: /[^\s"'=<>`]+/ }
7179 ]
7180 }
7181 ]
7182 }
7183 ]
7184 };
7185 return {
7186 name: 'HTML, XML',
7187 aliases: [
7188 'html',
7189 'xhtml',
7190 'rss',
7191 'atom',
7192 'xjb',
7193 'xsd',
7194 'xsl',
7195 'plist',
7196 'wsf',
7197 'svg'
7198 ],
7199 case_insensitive: true,
7200 unicodeRegex: true,
7201 contains: [
7202 {
7203 className: 'meta',
7204 begin: /<![a-z]/,
7205 end: />/,
7206 relevance: 10,
7207 contains: [
7208 XML_META_KEYWORDS,
7209 QUOTE_META_STRING_MODE,
7210 APOS_META_STRING_MODE,
7211 XML_META_PAR_KEYWORDS,
7212 {
7213 begin: /\[/,
7214 end: /\]/,
7215 contains: [
7216 {
7217 className: 'meta',
7218 begin: /<![a-z]/,
7219 end: />/,
7220 contains: [
7221 XML_META_KEYWORDS,
7222 XML_META_PAR_KEYWORDS,
7223 QUOTE_META_STRING_MODE,
7224 APOS_META_STRING_MODE
7225 ]
7226 }
7227 ]
7228 }
7229 ]
7230 },
7231 hljs.COMMENT(
7232 /<!--/,
7233 /-->/,
7234 { relevance: 10 }
7235 ),
7236 {
7237 begin: /<!\[CDATA\[/,
7238 end: /\]\]>/,
7239 relevance: 10
7240 },
7241 XML_ENTITIES,
7242 // xml processing instructions
7243 {
7244 className: 'meta',
7245 end: /\?>/,
7246 variants: [
7247 {
7248 begin: /<\?xml/,
7249 relevance: 10,
7250 contains: [
7251 QUOTE_META_STRING_MODE
7252 ]
7253 },
7254 {
7255 begin: /<\?[a-z][a-z0-9]+/,
7256 }
7257 ]
7258
7259 },
7260 {
7261 className: 'tag',
7262 /*
7263 The lookahead pattern (?=...) ensures that 'begin' only matches
7264 '<style' as a single word, followed by a whitespace or an
7265 ending bracket.
7266 */
7267 begin: /<style(?=\s|>)/,
7268 end: />/,
7269 keywords: { name: 'style' },
7270 contains: [ TAG_INTERNALS ],
7271 starts: {
7272 end: /<\/style>/,
7273 returnEnd: true,
7274 subLanguage: [
7275 'css',
7276 'xml'
7277 ]
7278 }
7279 },
7280 {
7281 className: 'tag',
7282 // See the comment in the <style tag about the lookahead pattern
7283 begin: /<script(?=\s|>)/,
7284 end: />/,
7285 keywords: { name: 'script' },
7286 contains: [ TAG_INTERNALS ],
7287 starts: {
7288 end: /<\/script>/,
7289 returnEnd: true,
7290 subLanguage: [
7291 'javascript',
7292 'handlebars',
7293 'xml'
7294 ]
7295 }
7296 },
7297 // we need this for now for jSX
7298 {
7299 className: 'tag',
7300 begin: /<>|<\/>/
7301 },
7302 // open tag
7303 {
7304 className: 'tag',
7305 begin: regex.concat(
7306 /</,
7307 regex.lookahead(regex.concat(
7308 TAG_NAME_RE,
7309 // <tag/>
7310 // <tag>
7311 // <tag ...
7312 regex.either(/\/>/, />/, /\s/)
7313 ))
7314 ),
7315 end: /\/?>/,
7316 contains: [
7317 {
7318 className: 'name',
7319 begin: TAG_NAME_RE,
7320 relevance: 0,
7321 starts: TAG_INTERNALS
7322 }
7323 ]
7324 },
7325 // close tag
7326 {
7327 className: 'tag',
7328 begin: regex.concat(
7329 /<\//,
7330 regex.lookahead(regex.concat(
7331 TAG_NAME_RE, />/
7332 ))
7333 ),
7334 contains: [
7335 {
7336 className: 'name',
7337 begin: TAG_NAME_RE,
7338 relevance: 0
7339 },
7340 {
7341 begin: />/,
7342 relevance: 0,
7343 endsParent: true
7344 }
7345 ]
7346 }
7347 ]
7348 };
7349 }
7350
7351 /*
7352 Language: Markdown
7353 Requires: xml.js
7354 Author: John Crepezzi <john.crepezzi@gmail.com>
7355 Website: https://daringfireball.net/projects/markdown/
7356 Category: common, markup
7357 */
7358
7359 function markdown(hljs) {
7360 const regex = hljs.regex;
7361 const INLINE_HTML = {
7362 begin: /<\/?[A-Za-z_]/,
7363 end: '>',
7364 subLanguage: 'xml',
7365 relevance: 0
7366 };
7367 const HORIZONTAL_RULE = {
7368 begin: '^[-\\*]{3,}',
7369 end: '$'
7370 };
7371 const CODE = {
7372 className: 'code',
7373 variants: [
7374 // TODO: fix to allow these to work with sublanguage also
7375 { begin: '(`{3,})[^`](.|\\n)*?\\1`*[ ]*' },
7376 { begin: '(~{3,})[^~](.|\\n)*?\\1~*[ ]*' },
7377 // needed to allow markdown as a sublanguage to work
7378 {
7379 begin: '```',
7380 end: '```+[ ]*$'
7381 },
7382 {
7383 begin: '~~~',
7384 end: '~~~+[ ]*$'
7385 },
7386 { begin: '`.+?`' },
7387 {
7388 begin: '(?=^( {4}|\\t))',
7389 // use contains to gobble up multiple lines to allow the block to be whatever size
7390 // but only have a single open/close tag vs one per line
7391 contains: [
7392 {
7393 begin: '^( {4}|\\t)',
7394 end: '(\\n)$'
7395 }
7396 ],
7397 relevance: 0
7398 }
7399 ]
7400 };
7401 const LIST = {
7402 className: 'bullet',
7403 begin: '^[ \t]*([*+-]|(\\d+\\.))(?=\\s+)',
7404 end: '\\s+',
7405 excludeEnd: true
7406 };
7407 const LINK_REFERENCE = {
7408 begin: /^\[[^\n]+\]:/,
7409 returnBegin: true,
7410 contains: [
7411 {
7412 className: 'symbol',
7413 begin: /\[/,
7414 end: /\]/,
7415 excludeBegin: true,
7416 excludeEnd: true
7417 },
7418 {
7419 className: 'link',
7420 begin: /:\s*/,
7421 end: /$/,
7422 excludeBegin: true
7423 }
7424 ]
7425 };
7426 const URL_SCHEME = /[A-Za-z][A-Za-z0-9+.-]*/;
7427 const LINK = {
7428 variants: [
7429 // too much like nested array access in so many languages
7430 // to have any real relevance
7431 {
7432 begin: /\[.+?\]\[.*?\]/,
7433 relevance: 0
7434 },
7435 // popular internet URLs
7436 {
7437 begin: /\[.+?\]\(((data|javascript|mailto):|(?:http|ftp)s?:\/\/).*?\)/,
7438 relevance: 2
7439 },
7440 {
7441 begin: regex.concat(/\[.+?\]\(/, URL_SCHEME, /:\/\/.*?\)/),
7442 relevance: 2
7443 },
7444 // relative urls
7445 {
7446 begin: /\[.+?\]\([./?&#].*?\)/,
7447 relevance: 1
7448 },
7449 // whatever else, lower relevance (might not be a link at all)
7450 {
7451 begin: /\[.*?\]\(.*?\)/,
7452 relevance: 0
7453 }
7454 ],
7455 returnBegin: true,
7456 contains: [
7457 {
7458 // empty strings for alt or link text
7459 match: /\[(?=\])/ },
7460 {
7461 className: 'string',
7462 relevance: 0,
7463 begin: '\\[',
7464 end: '\\]',
7465 excludeBegin: true,
7466 returnEnd: true
7467 },
7468 {
7469 className: 'link',
7470 relevance: 0,
7471 begin: '\\]\\(',
7472 end: '\\)',
7473 excludeBegin: true,
7474 excludeEnd: true
7475 },
7476 {
7477 className: 'symbol',
7478 relevance: 0,
7479 begin: '\\]\\[',
7480 end: '\\]',
7481 excludeBegin: true,
7482 excludeEnd: true
7483 }
7484 ]
7485 };
7486 const BOLD = {
7487 className: 'strong',
7488 contains: [], // defined later
7489 variants: [
7490 {
7491 begin: /_{2}(?!\s)/,
7492 end: /_{2}/
7493 },
7494 {
7495 begin: /\*{2}(?!\s)/,
7496 end: /\*{2}/
7497 }
7498 ]
7499 };
7500 const ITALIC = {
7501 className: 'emphasis',
7502 contains: [], // defined later
7503 variants: [
7504 {
7505 begin: /\*(?![*\s])/,
7506 end: /\*/
7507 },
7508 {
7509 begin: /_(?![_\s])/,
7510 end: /_/,
7511 relevance: 0
7512 }
7513 ]
7514 };
7515
7516 // 3 level deep nesting is not allowed because it would create confusion
7517 // in cases like `***testing***` because where we don't know if the last
7518 // `***` is starting a new bold/italic or finishing the last one
7519 const BOLD_WITHOUT_ITALIC = hljs.inherit(BOLD, { contains: [] });
7520 const ITALIC_WITHOUT_BOLD = hljs.inherit(ITALIC, { contains: [] });
7521 BOLD.contains.push(ITALIC_WITHOUT_BOLD);
7522 ITALIC.contains.push(BOLD_WITHOUT_ITALIC);
7523
7524 let CONTAINABLE = [
7525 INLINE_HTML,
7526 LINK
7527 ];
7528
7529 [
7530 BOLD,
7531 ITALIC,
7532 BOLD_WITHOUT_ITALIC,
7533 ITALIC_WITHOUT_BOLD
7534 ].forEach(m => {
7535 m.contains = m.contains.concat(CONTAINABLE);
7536 });
7537
7538 CONTAINABLE = CONTAINABLE.concat(BOLD, ITALIC);
7539
7540 const HEADER = {
7541 className: 'section',
7542 variants: [
7543 {
7544 begin: '^#{1,6}',
7545 end: '$',
7546 contains: CONTAINABLE
7547 },
7548 {
7549 begin: '(?=^.+?\\n[=-]{2,}$)',
7550 contains: [
7551 { begin: '^[=-]*$' },
7552 {
7553 begin: '^',
7554 end: "\\n",
7555 contains: CONTAINABLE
7556 }
7557 ]
7558 }
7559 ]
7560 };
7561
7562 const BLOCKQUOTE = {
7563 className: 'quote',
7564 begin: '^>\\s+',
7565 contains: CONTAINABLE,
7566 end: '$'
7567 };
7568
7569 return {
7570 name: 'Markdown',
7571 aliases: [
7572 'md',
7573 'mkdown',
7574 'mkd'
7575 ],
7576 contains: [
7577 HEADER,
7578 INLINE_HTML,
7579 LIST,
7580 BOLD,
7581 ITALIC,
7582 BLOCKQUOTE,
7583 CODE,
7584 HORIZONTAL_RULE,
7585 LINK,
7586 LINK_REFERENCE
7587 ]
7588 };
7589 }
7590
7591 /*
7592 Language: Objective-C
7593 Author: Valerii Hiora <valerii.hiora@gmail.com>
7594 Contributors: Angel G. Olloqui <angelgarcia.mail@gmail.com>, Matt Diephouse <matt@diephouse.com>, Andrew Farmer <ahfarmer@gmail.com>, Minh Nguyễn <mxn@1ec5.org>
7595 Website: https://developer.apple.com/documentation/objectivec
7596 Category: common
7597 */
7598
7599 function objectivec(hljs) {
7600 const API_CLASS = {
7601 className: 'built_in',
7602 begin: '\\b(AV|CA|CF|CG|CI|CL|CM|CN|CT|MK|MP|MTK|MTL|NS|SCN|SK|UI|WK|XC)\\w+'
7603 };
7604 const IDENTIFIER_RE = /[a-zA-Z@][a-zA-Z0-9_]*/;
7605 const TYPES = [
7606 "int",
7607 "float",
7608 "char",
7609 "unsigned",
7610 "signed",
7611 "short",
7612 "long",
7613 "double",
7614 "wchar_t",
7615 "unichar",
7616 "void",
7617 "bool",
7618 "BOOL",
7619 "id|0",
7620 "_Bool"
7621 ];
7622 const KWS = [
7623 "while",
7624 "export",
7625 "sizeof",
7626 "typedef",
7627 "const",
7628 "struct",
7629 "for",
7630 "union",
7631 "volatile",
7632 "static",
7633 "mutable",
7634 "if",
7635 "do",
7636 "return",
7637 "goto",
7638 "enum",
7639 "else",
7640 "break",
7641 "extern",
7642 "asm",
7643 "case",
7644 "default",
7645 "register",
7646 "explicit",
7647 "typename",
7648 "switch",
7649 "continue",
7650 "inline",
7651 "readonly",
7652 "assign",
7653 "readwrite",
7654 "self",
7655 "@synchronized",
7656 "id",
7657 "typeof",
7658 "nonatomic",
7659 "IBOutlet",
7660 "IBAction",
7661 "strong",
7662 "weak",
7663 "copy",
7664 "in",
7665 "out",
7666 "inout",
7667 "bycopy",
7668 "byref",
7669 "oneway",
7670 "__strong",
7671 "__weak",
7672 "__block",
7673 "__autoreleasing",
7674 "@private",
7675 "@protected",
7676 "@public",
7677 "@try",
7678 "@property",
7679 "@end",
7680 "@throw",
7681 "@catch",
7682 "@finally",
7683 "@autoreleasepool",
7684 "@synthesize",
7685 "@dynamic",
7686 "@selector",
7687 "@optional",
7688 "@required",
7689 "@encode",
7690 "@package",
7691 "@import",
7692 "@defs",
7693 "@compatibility_alias",
7694 "__bridge",
7695 "__bridge_transfer",
7696 "__bridge_retained",
7697 "__bridge_retain",
7698 "__covariant",
7699 "__contravariant",
7700 "__kindof",
7701 "_Nonnull",
7702 "_Nullable",
7703 "_Null_unspecified",
7704 "__FUNCTION__",
7705 "__PRETTY_FUNCTION__",
7706 "__attribute__",
7707 "getter",
7708 "setter",
7709 "retain",
7710 "unsafe_unretained",
7711 "nonnull",
7712 "nullable",
7713 "null_unspecified",
7714 "null_resettable",
7715 "class",
7716 "instancetype",
7717 "NS_DESIGNATED_INITIALIZER",
7718 "NS_UNAVAILABLE",
7719 "NS_REQUIRES_SUPER",
7720 "NS_RETURNS_INNER_POINTER",
7721 "NS_INLINE",
7722 "NS_AVAILABLE",
7723 "NS_DEPRECATED",
7724 "NS_ENUM",
7725 "NS_OPTIONS",
7726 "NS_SWIFT_UNAVAILABLE",
7727 "NS_ASSUME_NONNULL_BEGIN",
7728 "NS_ASSUME_NONNULL_END",
7729 "NS_REFINED_FOR_SWIFT",
7730 "NS_SWIFT_NAME",
7731 "NS_SWIFT_NOTHROW",
7732 "NS_DURING",
7733 "NS_HANDLER",
7734 "NS_ENDHANDLER",
7735 "NS_VALUERETURN",
7736 "NS_VOIDRETURN"
7737 ];
7738 const LITERALS = [
7739 "false",
7740 "true",
7741 "FALSE",
7742 "TRUE",
7743 "nil",
7744 "YES",
7745 "NO",
7746 "NULL"
7747 ];
7748 const BUILT_INS = [
7749 "dispatch_once_t",
7750 "dispatch_queue_t",
7751 "dispatch_sync",
7752 "dispatch_async",
7753 "dispatch_once"
7754 ];
7755 const KEYWORDS = {
7756 "variable.language": [
7757 "this",
7758 "super"
7759 ],
7760 $pattern: IDENTIFIER_RE,
7761 keyword: KWS,
7762 literal: LITERALS,
7763 built_in: BUILT_INS,
7764 type: TYPES
7765 };
7766 const CLASS_KEYWORDS = {
7767 $pattern: IDENTIFIER_RE,
7768 keyword: [
7769 "@interface",
7770 "@class",
7771 "@protocol",
7772 "@implementation"
7773 ]
7774 };
7775 return {
7776 name: 'Objective-C',
7777 aliases: [
7778 'mm',
7779 'objc',
7780 'obj-c',
7781 'obj-c++',
7782 'objective-c++'
7783 ],
7784 keywords: KEYWORDS,
7785 illegal: '</',
7786 contains: [
7787 API_CLASS,
7788 hljs.C_LINE_COMMENT_MODE,
7789 hljs.C_BLOCK_COMMENT_MODE,
7790 hljs.C_NUMBER_MODE,
7791 hljs.QUOTE_STRING_MODE,
7792 hljs.APOS_STRING_MODE,
7793 {
7794 className: 'string',
7795 variants: [
7796 {
7797 begin: '@"',
7798 end: '"',
7799 illegal: '\\n',
7800 contains: [ hljs.BACKSLASH_ESCAPE ]
7801 }
7802 ]
7803 },
7804 {
7805 className: 'meta',
7806 begin: /#\s*[a-z]+\b/,
7807 end: /$/,
7808 keywords: { keyword:
7809 'if else elif endif define undef warning error line '
7810 + 'pragma ifdef ifndef include' },
7811 contains: [
7812 {
7813 begin: /\\\n/,
7814 relevance: 0
7815 },
7816 hljs.inherit(hljs.QUOTE_STRING_MODE, { className: 'string' }),
7817 {
7818 className: 'string',
7819 begin: /<.*?>/,
7820 end: /$/,
7821 illegal: '\\n'
7822 },
7823 hljs.C_LINE_COMMENT_MODE,
7824 hljs.C_BLOCK_COMMENT_MODE
7825 ]
7826 },
7827 {
7828 className: 'class',
7829 begin: '(' + CLASS_KEYWORDS.keyword.join('|') + ')\\b',
7830 end: /(\{|$)/,
7831 excludeEnd: true,
7832 keywords: CLASS_KEYWORDS,
7833 contains: [ hljs.UNDERSCORE_TITLE_MODE ]
7834 },
7835 {
7836 begin: '\\.' + hljs.UNDERSCORE_IDENT_RE,
7837 relevance: 0
7838 }
7839 ]
7840 };
7841 }
7842
7843 /*
7844 Language: Perl
7845 Author: Peter Leonov <gojpeg@yandex.ru>
7846 Website: https://www.perl.org
7847 Category: common
7848 */
7849
7850 /** @type LanguageFn */
7851 function perl(hljs) {
7852 const regex = hljs.regex;
7853 const KEYWORDS = [
7854 'abs',
7855 'accept',
7856 'alarm',
7857 'and',
7858 'atan2',
7859 'bind',
7860 'binmode',
7861 'bless',
7862 'break',
7863 'caller',
7864 'chdir',
7865 'chmod',
7866 'chomp',
7867 'chop',
7868 'chown',
7869 'chr',
7870 'chroot',
7871 'close',
7872 'closedir',
7873 'connect',
7874 'continue',
7875 'cos',
7876 'crypt',
7877 'dbmclose',
7878 'dbmopen',
7879 'defined',
7880 'delete',
7881 'die',
7882 'do',
7883 'dump',
7884 'each',
7885 'else',
7886 'elsif',
7887 'endgrent',
7888 'endhostent',
7889 'endnetent',
7890 'endprotoent',
7891 'endpwent',
7892 'endservent',
7893 'eof',
7894 'eval',
7895 'exec',
7896 'exists',
7897 'exit',
7898 'exp',
7899 'fcntl',
7900 'fileno',
7901 'flock',
7902 'for',
7903 'foreach',
7904 'fork',
7905 'format',
7906 'formline',
7907 'getc',
7908 'getgrent',
7909 'getgrgid',
7910 'getgrnam',
7911 'gethostbyaddr',
7912 'gethostbyname',
7913 'gethostent',
7914 'getlogin',
7915 'getnetbyaddr',
7916 'getnetbyname',
7917 'getnetent',
7918 'getpeername',
7919 'getpgrp',
7920 'getpriority',
7921 'getprotobyname',
7922 'getprotobynumber',
7923 'getprotoent',
7924 'getpwent',
7925 'getpwnam',
7926 'getpwuid',
7927 'getservbyname',
7928 'getservbyport',
7929 'getservent',
7930 'getsockname',
7931 'getsockopt',
7932 'given',
7933 'glob',
7934 'gmtime',
7935 'goto',
7936 'grep',
7937 'gt',
7938 'hex',
7939 'if',
7940 'index',
7941 'int',
7942 'ioctl',
7943 'join',
7944 'keys',
7945 'kill',
7946 'last',
7947 'lc',
7948 'lcfirst',
7949 'length',
7950 'link',
7951 'listen',
7952 'local',
7953 'localtime',
7954 'log',
7955 'lstat',
7956 'lt',
7957 'ma',
7958 'map',
7959 'mkdir',
7960 'msgctl',
7961 'msgget',
7962 'msgrcv',
7963 'msgsnd',
7964 'my',
7965 'ne',
7966 'next',
7967 'no',
7968 'not',
7969 'oct',
7970 'open',
7971 'opendir',
7972 'or',
7973 'ord',
7974 'our',
7975 'pack',
7976 'package',
7977 'pipe',
7978 'pop',
7979 'pos',
7980 'print',
7981 'printf',
7982 'prototype',
7983 'push',
7984 'q|0',
7985 'qq',
7986 'quotemeta',
7987 'qw',
7988 'qx',
7989 'rand',
7990 'read',
7991 'readdir',
7992 'readline',
7993 'readlink',
7994 'readpipe',
7995 'recv',
7996 'redo',
7997 'ref',
7998 'rename',
7999 'require',
8000 'reset',
8001 'return',
8002 'reverse',
8003 'rewinddir',
8004 'rindex',
8005 'rmdir',
8006 'say',
8007 'scalar',
8008 'seek',
8009 'seekdir',
8010 'select',
8011 'semctl',
8012 'semget',
8013 'semop',
8014 'send',
8015 'setgrent',
8016 'sethostent',
8017 'setnetent',
8018 'setpgrp',
8019 'setpriority',
8020 'setprotoent',
8021 'setpwent',
8022 'setservent',
8023 'setsockopt',
8024 'shift',
8025 'shmctl',
8026 'shmget',
8027 'shmread',
8028 'shmwrite',
8029 'shutdown',
8030 'sin',
8031 'sleep',
8032 'socket',
8033 'socketpair',
8034 'sort',
8035 'splice',
8036 'split',
8037 'sprintf',
8038 'sqrt',
8039 'srand',
8040 'stat',
8041 'state',
8042 'study',
8043 'sub',
8044 'substr',
8045 'symlink',
8046 'syscall',
8047 'sysopen',
8048 'sysread',
8049 'sysseek',
8050 'system',
8051 'syswrite',
8052 'tell',
8053 'telldir',
8054 'tie',
8055 'tied',
8056 'time',
8057 'times',
8058 'tr',
8059 'truncate',
8060 'uc',
8061 'ucfirst',
8062 'umask',
8063 'undef',
8064 'unless',
8065 'unlink',
8066 'unpack',
8067 'unshift',
8068 'untie',
8069 'until',
8070 'use',
8071 'utime',
8072 'values',
8073 'vec',
8074 'wait',
8075 'waitpid',
8076 'wantarray',
8077 'warn',
8078 'when',
8079 'while',
8080 'write',
8081 'x|0',
8082 'xor',
8083 'y|0'
8084 ];
8085
8086 // https://perldoc.perl.org/perlre#Modifiers
8087 const REGEX_MODIFIERS = /[dualxmsipngr]{0,12}/; // aa and xx are valid, making max length 12
8088 const PERL_KEYWORDS = {
8089 $pattern: /[\w.]+/,
8090 keyword: KEYWORDS.join(" ")
8091 };
8092 const SUBST = {
8093 className: 'subst',
8094 begin: '[$@]\\{',
8095 end: '\\}',
8096 keywords: PERL_KEYWORDS
8097 };
8098 const METHOD = {
8099 begin: /->\{/,
8100 end: /\}/
8101 // contains defined later
8102 };
8103 const VAR = { variants: [
8104 { begin: /\$\d/ },
8105 { begin: regex.concat(
8106 /[$%@](\^\w\b|#\w+(::\w+)*|\{\w+\}|\w+(::\w*)*)/,
8107 // negative look-ahead tries to avoid matching patterns that are not
8108 // Perl at all like $ident$, @ident@, etc.
8109 `(?![A-Za-z])(?![@$%])`
8110 ) },
8111 {
8112 begin: /[$%@][^\s\w{]/,
8113 relevance: 0
8114 }
8115 ] };
8116 const STRING_CONTAINS = [
8117 hljs.BACKSLASH_ESCAPE,
8118 SUBST,
8119 VAR
8120 ];
8121 const REGEX_DELIMS = [
8122 /!/,
8123 /\//,
8124 /\|/,
8125 /\?/,
8126 /'/,
8127 /"/, // valid but infrequent and weird
8128 /#/ // valid but infrequent and weird
8129 ];
8130 /**
8131 * @param {string|RegExp} prefix
8132 * @param {string|RegExp} open
8133 * @param {string|RegExp} close
8134 */
8135 const PAIRED_DOUBLE_RE = (prefix, open, close = '\\1') => {
8136 const middle = (close === '\\1')
8137 ? close
8138 : regex.concat(close, open);
8139 return regex.concat(
8140 regex.concat("(?:", prefix, ")"),
8141 open,
8142 /(?:\\.|[^\\\/])*?/,
8143 middle,
8144 /(?:\\.|[^\\\/])*?/,
8145 close,
8146 REGEX_MODIFIERS
8147 );
8148 };
8149 /**
8150 * @param {string|RegExp} prefix
8151 * @param {string|RegExp} open
8152 * @param {string|RegExp} close
8153 */
8154 const PAIRED_RE = (prefix, open, close) => {
8155 return regex.concat(
8156 regex.concat("(?:", prefix, ")"),
8157 open,
8158 /(?:\\.|[^\\\/])*?/,
8159 close,
8160 REGEX_MODIFIERS
8161 );
8162 };
8163 const PERL_DEFAULT_CONTAINS = [
8164 VAR,
8165 hljs.HASH_COMMENT_MODE,
8166 hljs.COMMENT(
8167 /^=\w/,
8168 /=cut/,
8169 { endsWithParent: true }
8170 ),
8171 METHOD,
8172 {
8173 className: 'string',
8174 contains: STRING_CONTAINS,
8175 variants: [
8176 {
8177 begin: 'q[qwxr]?\\s*\\(',
8178 end: '\\)',
8179 relevance: 5
8180 },
8181 {
8182 begin: 'q[qwxr]?\\s*\\[',
8183 end: '\\]',
8184 relevance: 5
8185 },
8186 {
8187 begin: 'q[qwxr]?\\s*\\{',
8188 end: '\\}',
8189 relevance: 5
8190 },
8191 {
8192 begin: 'q[qwxr]?\\s*\\|',
8193 end: '\\|',
8194 relevance: 5
8195 },
8196 {
8197 begin: 'q[qwxr]?\\s*<',
8198 end: '>',
8199 relevance: 5
8200 },
8201 {
8202 begin: 'qw\\s+q',
8203 end: 'q',
8204 relevance: 5
8205 },
8206 {
8207 begin: '\'',
8208 end: '\'',
8209 contains: [ hljs.BACKSLASH_ESCAPE ]
8210 },
8211 {
8212 begin: '"',
8213 end: '"'
8214 },
8215 {
8216 begin: '`',
8217 end: '`',
8218 contains: [ hljs.BACKSLASH_ESCAPE ]
8219 },
8220 {
8221 begin: /\{\w+\}/,
8222 relevance: 0
8223 },
8224 {
8225 begin: '-?\\w+\\s*=>',
8226 relevance: 0
8227 }
8228 ]
8229 },
8230 {
8231 className: 'number',
8232 begin: '(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b',
8233 relevance: 0
8234 },
8235 { // regexp container
8236 begin: '(\\/\\/|' + hljs.RE_STARTERS_RE + '|\\b(split|return|print|reverse|grep)\\b)\\s*',
8237 keywords: 'split return print reverse grep',
8238 relevance: 0,
8239 contains: [
8240 hljs.HASH_COMMENT_MODE,
8241 {
8242 className: 'regexp',
8243 variants: [
8244 // allow matching common delimiters
8245 { begin: PAIRED_DOUBLE_RE("s|tr|y", regex.either(...REGEX_DELIMS, { capture: true })) },
8246 // and then paired delmis
8247 { begin: PAIRED_DOUBLE_RE("s|tr|y", "\\(", "\\)") },
8248 { begin: PAIRED_DOUBLE_RE("s|tr|y", "\\[", "\\]") },
8249 { begin: PAIRED_DOUBLE_RE("s|tr|y", "\\{", "\\}") }
8250 ],
8251 relevance: 2
8252 },
8253 {
8254 className: 'regexp',
8255 variants: [
8256 {
8257 // could be a comment in many languages so do not count
8258 // as relevant
8259 begin: /(m|qr)\/\//,
8260 relevance: 0
8261 },
8262 // prefix is optional with /regex/
8263 { begin: PAIRED_RE("(?:m|qr)?", /\//, /\//) },
8264 // allow matching common delimiters
8265 { begin: PAIRED_RE("m|qr", regex.either(...REGEX_DELIMS, { capture: true }), /\1/) },
8266 // allow common paired delmins
8267 { begin: PAIRED_RE("m|qr", /\(/, /\)/) },
8268 { begin: PAIRED_RE("m|qr", /\[/, /\]/) },
8269 { begin: PAIRED_RE("m|qr", /\{/, /\}/) }
8270 ]
8271 }
8272 ]
8273 },
8274 {
8275 className: 'function',
8276 beginKeywords: 'sub',
8277 end: '(\\s*\\(.*?\\))?[;{]',
8278 excludeEnd: true,
8279 relevance: 5,
8280 contains: [ hljs.TITLE_MODE ]
8281 },
8282 {
8283 begin: '-\\w\\b',
8284 relevance: 0
8285 },
8286 {
8287 begin: "^__DATA__$",
8288 end: "^__END__$",
8289 subLanguage: 'mojolicious',
8290 contains: [
8291 {
8292 begin: "^@@.*",
8293 end: "$",
8294 className: "comment"
8295 }
8296 ]
8297 }
8298 ];
8299 SUBST.contains = PERL_DEFAULT_CONTAINS;
8300 METHOD.contains = PERL_DEFAULT_CONTAINS;
8301
8302 return {
8303 name: 'Perl',
8304 aliases: [
8305 'pl',
8306 'pm'
8307 ],
8308 keywords: PERL_KEYWORDS,
8309 contains: PERL_DEFAULT_CONTAINS
8310 };
8311 }
8312
8313 /*
8314 Language: PHP
8315 Author: Victor Karamzin <Victor.Karamzin@enterra-inc.com>
8316 Contributors: Evgeny Stepanischev <imbolk@gmail.com>, Ivan Sagalaev <maniac@softwaremaniacs.org>
8317 Website: https://www.php.net
8318 Category: common
8319 */
8320
8321 /**
8322 * @param {HLJSApi} hljs
8323 * @returns {LanguageDetail}
8324 * */
8325 function php(hljs) {
8326 const regex = hljs.regex;
8327 // negative look-ahead tries to avoid matching patterns that are not
8328 // Perl at all like $ident$, @ident@, etc.
8329 const NOT_PERL_ETC = /(?![A-Za-z0-9])(?![$])/;
8330 const IDENT_RE = regex.concat(
8331 /[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/,
8332 NOT_PERL_ETC);
8333 // Will not detect camelCase classes
8334 const PASCAL_CASE_CLASS_NAME_RE = regex.concat(
8335 /(\\?[A-Z][a-z0-9_\x7f-\xff]+|\\?[A-Z]+(?=[A-Z][a-z0-9_\x7f-\xff])){1,}/,
8336 NOT_PERL_ETC);
8337 const VARIABLE = {
8338 scope: 'variable',
8339 match: '\\$+' + IDENT_RE,
8340 };
8341 const PREPROCESSOR = {
8342 scope: 'meta',
8343 variants: [
8344 { begin: /<\?php/, relevance: 10 }, // boost for obvious PHP
8345 { begin: /<\?=/ },
8346 // less relevant per PSR-1 which says not to use short-tags
8347 { begin: /<\?/, relevance: 0.1 },
8348 { begin: /\?>/ } // end php tag
8349 ]
8350 };
8351 const SUBST = {
8352 scope: 'subst',
8353 variants: [
8354 { begin: /\$\w+/ },
8355 {
8356 begin: /\{\$/,
8357 end: /\}/
8358 }
8359 ]
8360 };
8361 const SINGLE_QUOTED = hljs.inherit(hljs.APOS_STRING_MODE, { illegal: null, });
8362 const DOUBLE_QUOTED = hljs.inherit(hljs.QUOTE_STRING_MODE, {
8363 illegal: null,
8364 contains: hljs.QUOTE_STRING_MODE.contains.concat(SUBST),
8365 });
8366 const HEREDOC = hljs.END_SAME_AS_BEGIN({
8367 begin: /<<<[ \t]*(\w+)\n/,
8368 end: /[ \t]*(\w+)\b/,
8369 contains: hljs.QUOTE_STRING_MODE.contains.concat(SUBST),
8370 });
8371 // list of valid whitespaces because non-breaking space might be part of a IDENT_RE
8372 const WHITESPACE = '[ \t\n]';
8373 const STRING = {
8374 scope: 'string',
8375 variants: [
8376 DOUBLE_QUOTED,
8377 SINGLE_QUOTED,
8378 HEREDOC
8379 ]
8380 };
8381 const NUMBER = {
8382 scope: 'number',
8383 variants: [
8384 { begin: `\\b0[bB][01]+(?:_[01]+)*\\b` }, // Binary w/ underscore support
8385 { begin: `\\b0[oO][0-7]+(?:_[0-7]+)*\\b` }, // Octals w/ underscore support
8386 { begin: `\\b0[xX][\\da-fA-F]+(?:_[\\da-fA-F]+)*\\b` }, // Hex w/ underscore support
8387 // Decimals w/ underscore support, with optional fragments and scientific exponent (e) suffix.
8388 { begin: `(?:\\b\\d+(?:_\\d+)*(\\.(?:\\d+(?:_\\d+)*))?|\\B\\.\\d+)(?:[eE][+-]?\\d+)?` }
8389 ],
8390 relevance: 0
8391 };
8392 const LITERALS = [
8393 "false",
8394 "null",
8395 "true"
8396 ];
8397 const KWS = [
8398 // Magic constants:
8399 // <https://www.php.net/manual/en/language.constants.predefined.php>
8400 "__CLASS__",
8401 "__DIR__",
8402 "__FILE__",
8403 "__FUNCTION__",
8404 "__COMPILER_HALT_OFFSET__",
8405 "__LINE__",
8406 "__METHOD__",
8407 "__NAMESPACE__",
8408 "__TRAIT__",
8409 // Function that look like language construct or language construct that look like function:
8410 // List of keywords that may not require parenthesis
8411 "die",
8412 "echo",
8413 "exit",
8414 "include",
8415 "include_once",
8416 "print",
8417 "require",
8418 "require_once",
8419 // These are not language construct (function) but operate on the currently-executing function and can access the current symbol table
8420 // 'compact extract func_get_arg func_get_args func_num_args get_called_class get_parent_class ' +
8421 // Other keywords:
8422 // <https://www.php.net/manual/en/reserved.php>
8423 // <https://www.php.net/manual/en/language.types.type-juggling.php>
8424 "array",
8425 "abstract",
8426 "and",
8427 "as",
8428 "binary",
8429 "bool",
8430 "boolean",
8431 "break",
8432 "callable",
8433 "case",
8434 "catch",
8435 "class",
8436 "clone",
8437 "const",
8438 "continue",
8439 "declare",
8440 "default",
8441 "do",
8442 "double",
8443 "else",
8444 "elseif",
8445 "empty",
8446 "enddeclare",
8447 "endfor",
8448 "endforeach",
8449 "endif",
8450 "endswitch",
8451 "endwhile",
8452 "enum",
8453 "eval",
8454 "extends",
8455 "final",
8456 "finally",
8457 "float",
8458 "for",
8459 "foreach",
8460 "from",
8461 "global",
8462 "goto",
8463 "if",
8464 "implements",
8465 "instanceof",
8466 "insteadof",
8467 "int",
8468 "integer",
8469 "interface",
8470 "isset",
8471 "iterable",
8472 "list",
8473 "match|0",
8474 "mixed",
8475 "new",
8476 "never",
8477 "object",
8478 "or",
8479 "private",
8480 "protected",
8481 "public",
8482 "readonly",
8483 "real",
8484 "return",
8485 "string",
8486 "switch",
8487 "throw",
8488 "trait",
8489 "try",
8490 "unset",
8491 "use",
8492 "var",
8493 "void",
8494 "while",
8495 "xor",
8496 "yield"
8497 ];
8498
8499 const BUILT_INS = [
8500 // Standard PHP library:
8501 // <https://www.php.net/manual/en/book.spl.php>
8502 "Error|0",
8503 "AppendIterator",
8504 "ArgumentCountError",
8505 "ArithmeticError",
8506 "ArrayIterator",
8507 "ArrayObject",
8508 "AssertionError",
8509 "BadFunctionCallException",
8510 "BadMethodCallException",
8511 "CachingIterator",
8512 "CallbackFilterIterator",
8513 "CompileError",
8514 "Countable",
8515 "DirectoryIterator",
8516 "DivisionByZeroError",
8517 "DomainException",
8518 "EmptyIterator",
8519 "ErrorException",
8520 "Exception",
8521 "FilesystemIterator",
8522 "FilterIterator",
8523 "GlobIterator",
8524 "InfiniteIterator",
8525 "InvalidArgumentException",
8526 "IteratorIterator",
8527 "LengthException",
8528 "LimitIterator",
8529 "LogicException",
8530 "MultipleIterator",
8531 "NoRewindIterator",
8532 "OutOfBoundsException",
8533 "OutOfRangeException",
8534 "OuterIterator",
8535 "OverflowException",
8536 "ParentIterator",
8537 "ParseError",
8538 "RangeException",
8539 "RecursiveArrayIterator",
8540 "RecursiveCachingIterator",
8541 "RecursiveCallbackFilterIterator",
8542 "RecursiveDirectoryIterator",
8543 "RecursiveFilterIterator",
8544 "RecursiveIterator",
8545 "RecursiveIteratorIterator",
8546 "RecursiveRegexIterator",
8547 "RecursiveTreeIterator",
8548 "RegexIterator",
8549 "RuntimeException",
8550 "SeekableIterator",
8551 "SplDoublyLinkedList",
8552 "SplFileInfo",
8553 "SplFileObject",
8554 "SplFixedArray",
8555 "SplHeap",
8556 "SplMaxHeap",
8557 "SplMinHeap",
8558 "SplObjectStorage",
8559 "SplObserver",
8560 "SplPriorityQueue",
8561 "SplQueue",
8562 "SplStack",
8563 "SplSubject",
8564 "SplTempFileObject",
8565 "TypeError",
8566 "UnderflowException",
8567 "UnexpectedValueException",
8568 "UnhandledMatchError",
8569 // Reserved interfaces:
8570 // <https://www.php.net/manual/en/reserved.interfaces.php>
8571 "ArrayAccess",
8572 "BackedEnum",
8573 "Closure",
8574 "Fiber",
8575 "Generator",
8576 "Iterator",
8577 "IteratorAggregate",
8578 "Serializable",
8579 "Stringable",
8580 "Throwable",
8581 "Traversable",
8582 "UnitEnum",
8583 "WeakReference",
8584 "WeakMap",
8585 // Reserved classes:
8586 // <https://www.php.net/manual/en/reserved.classes.php>
8587 "Directory",
8588 "__PHP_Incomplete_Class",
8589 "parent",
8590 "php_user_filter",
8591 "self",
8592 "static",
8593 "stdClass"
8594 ];
8595
8596 /** Dual-case keywords
8597 *
8598 * ["then","FILE"] =>
8599 * ["then", "THEN", "FILE", "file"]
8600 *
8601 * @param {string[]} items */
8602 const dualCase = (items) => {
8603 /** @type string[] */
8604 const result = [];
8605 items.forEach(item => {
8606 result.push(item);
8607 if (item.toLowerCase() === item) {
8608 result.push(item.toUpperCase());
8609 } else {
8610 result.push(item.toLowerCase());
8611 }
8612 });
8613 return result;
8614 };
8615
8616 const KEYWORDS = {
8617 keyword: KWS,
8618 literal: dualCase(LITERALS),
8619 built_in: BUILT_INS,
8620 };
8621
8622 /**
8623 * @param {string[]} items */
8624 const normalizeKeywords = (items) => {
8625 return items.map(item => {
8626 return item.replace(/\|\d+$/, "");
8627 });
8628 };
8629
8630 const CONSTRUCTOR_CALL = { variants: [
8631 {
8632 match: [
8633 /new/,
8634 regex.concat(WHITESPACE, "+"),
8635 // to prevent built ins from being confused as the class constructor call
8636 regex.concat("(?!", normalizeKeywords(BUILT_INS).join("\\b|"), "\\b)"),
8637 PASCAL_CASE_CLASS_NAME_RE,
8638 ],
8639 scope: {
8640 1: "keyword",
8641 4: "title.class",
8642 },
8643 }
8644 ] };
8645
8646 const CONSTANT_REFERENCE = regex.concat(IDENT_RE, "\\b(?!\\()");
8647
8648 const LEFT_AND_RIGHT_SIDE_OF_DOUBLE_COLON = { variants: [
8649 {
8650 match: [
8651 regex.concat(
8652 /::/,
8653 regex.lookahead(/(?!class\b)/)
8654 ),
8655 CONSTANT_REFERENCE,
8656 ],
8657 scope: { 2: "variable.constant", },
8658 },
8659 {
8660 match: [
8661 /::/,
8662 /class/,
8663 ],
8664 scope: { 2: "variable.language", },
8665 },
8666 {
8667 match: [
8668 PASCAL_CASE_CLASS_NAME_RE,
8669 regex.concat(
8670 /::/,
8671 regex.lookahead(/(?!class\b)/)
8672 ),
8673 CONSTANT_REFERENCE,
8674 ],
8675 scope: {
8676 1: "title.class",
8677 3: "variable.constant",
8678 },
8679 },
8680 {
8681 match: [
8682 PASCAL_CASE_CLASS_NAME_RE,
8683 regex.concat(
8684 "::",
8685 regex.lookahead(/(?!class\b)/)
8686 ),
8687 ],
8688 scope: { 1: "title.class", },
8689 },
8690 {
8691 match: [
8692 PASCAL_CASE_CLASS_NAME_RE,
8693 /::/,
8694 /class/,
8695 ],
8696 scope: {
8697 1: "title.class",
8698 3: "variable.language",
8699 },
8700 }
8701 ] };
8702
8703 const NAMED_ARGUMENT = {
8704 scope: 'attr',
8705 match: regex.concat(IDENT_RE, regex.lookahead(':'), regex.lookahead(/(?!::)/)),
8706 };
8707 const PARAMS_MODE = {
8708 relevance: 0,
8709 begin: /\(/,
8710 end: /\)/,
8711 keywords: KEYWORDS,
8712 contains: [
8713 NAMED_ARGUMENT,
8714 VARIABLE,
8715 LEFT_AND_RIGHT_SIDE_OF_DOUBLE_COLON,
8716 hljs.C_BLOCK_COMMENT_MODE,
8717 STRING,
8718 NUMBER,
8719 CONSTRUCTOR_CALL,
8720 ],
8721 };
8722 const FUNCTION_INVOKE = {
8723 relevance: 0,
8724 match: [
8725 /\b/,
8726 // to prevent keywords from being confused as the function title
8727 regex.concat("(?!fn\\b|function\\b|", normalizeKeywords(KWS).join("\\b|"), "|", normalizeKeywords(BUILT_INS).join("\\b|"), "\\b)"),
8728 IDENT_RE,
8729 regex.concat(WHITESPACE, "*"),
8730 regex.lookahead(/(?=\()/)
8731 ],
8732 scope: { 3: "title.function.invoke", },
8733 contains: [ PARAMS_MODE ]
8734 };
8735 PARAMS_MODE.contains.push(FUNCTION_INVOKE);
8736
8737 const ATTRIBUTE_CONTAINS = [
8738 NAMED_ARGUMENT,
8739 LEFT_AND_RIGHT_SIDE_OF_DOUBLE_COLON,
8740 hljs.C_BLOCK_COMMENT_MODE,
8741 STRING,
8742 NUMBER,
8743 CONSTRUCTOR_CALL,
8744 ];
8745
8746 const ATTRIBUTES = {
8747 begin: regex.concat(/#\[\s*/, PASCAL_CASE_CLASS_NAME_RE),
8748 beginScope: "meta",
8749 end: /]/,
8750 endScope: "meta",
8751 keywords: {
8752 literal: LITERALS,
8753 keyword: [
8754 'new',
8755 'array',
8756 ]
8757 },
8758 contains: [
8759 {
8760 begin: /\[/,
8761 end: /]/,
8762 keywords: {
8763 literal: LITERALS,
8764 keyword: [
8765 'new',
8766 'array',
8767 ]
8768 },
8769 contains: [
8770 'self',
8771 ...ATTRIBUTE_CONTAINS,
8772 ]
8773 },
8774 ...ATTRIBUTE_CONTAINS,
8775 {
8776 scope: 'meta',
8777 match: PASCAL_CASE_CLASS_NAME_RE
8778 }
8779 ]
8780 };
8781
8782 return {
8783 case_insensitive: false,
8784 keywords: KEYWORDS,
8785 contains: [
8786 ATTRIBUTES,
8787 hljs.HASH_COMMENT_MODE,
8788 hljs.COMMENT('//', '$'),
8789 hljs.COMMENT(
8790 '/\\*',
8791 '\\*/',
8792 { contains: [
8793 {
8794 scope: 'doctag',
8795 match: '@[A-Za-z]+'
8796 }
8797 ] }
8798 ),
8799 {
8800 match: /__halt_compiler\(\);/,
8801 keywords: '__halt_compiler',
8802 starts: {
8803 scope: "comment",
8804 end: hljs.MATCH_NOTHING_RE,
8805 contains: [
8806 {
8807 match: /\?>/,
8808 scope: "meta",
8809 endsParent: true
8810 }
8811 ]
8812 }
8813 },
8814 PREPROCESSOR,
8815 {
8816 scope: 'variable.language',
8817 match: /\$this\b/
8818 },
8819 VARIABLE,
8820 FUNCTION_INVOKE,
8821 LEFT_AND_RIGHT_SIDE_OF_DOUBLE_COLON,
8822 {
8823 match: [
8824 /const/,
8825 /\s/,
8826 IDENT_RE,
8827 ],
8828 scope: {
8829 1: "keyword",
8830 3: "variable.constant",
8831 },
8832 },
8833 CONSTRUCTOR_CALL,
8834 {
8835 scope: 'function',
8836 relevance: 0,
8837 beginKeywords: 'fn function',
8838 end: /[;{]/,
8839 excludeEnd: true,
8840 illegal: '[$%\\[]',
8841 contains: [
8842 { beginKeywords: 'use', },
8843 hljs.UNDERSCORE_TITLE_MODE,
8844 {
8845 begin: '=>', // No markup, just a relevance booster
8846 endsParent: true
8847 },
8848 {
8849 scope: 'params',
8850 begin: '\\(',
8851 end: '\\)',
8852 excludeBegin: true,
8853 excludeEnd: true,
8854 keywords: KEYWORDS,
8855 contains: [
8856 'self',
8857 VARIABLE,
8858 LEFT_AND_RIGHT_SIDE_OF_DOUBLE_COLON,
8859 hljs.C_BLOCK_COMMENT_MODE,
8860 STRING,
8861 NUMBER
8862 ]
8863 },
8864 ]
8865 },
8866 {
8867 scope: 'class',
8868 variants: [
8869 {
8870 beginKeywords: "enum",
8871 illegal: /[($"]/
8872 },
8873 {
8874 beginKeywords: "class interface trait",
8875 illegal: /[:($"]/
8876 }
8877 ],
8878 relevance: 0,
8879 end: /\{/,
8880 excludeEnd: true,
8881 contains: [
8882 { beginKeywords: 'extends implements' },
8883 hljs.UNDERSCORE_TITLE_MODE
8884 ]
8885 },
8886 // both use and namespace still use "old style" rules (vs multi-match)
8887 // because the namespace name can include `\` and we still want each
8888 // element to be treated as its own *individual* title
8889 {
8890 beginKeywords: 'namespace',
8891 relevance: 0,
8892 end: ';',
8893 illegal: /[.']/,
8894 contains: [ hljs.inherit(hljs.UNDERSCORE_TITLE_MODE, { scope: "title.class" }) ]
8895 },
8896 {
8897 beginKeywords: 'use',
8898 relevance: 0,
8899 end: ';',
8900 contains: [
8901 // TODO: title.function vs title.class
8902 {
8903 match: /\b(as|const|function)\b/,
8904 scope: "keyword"
8905 },
8906 // TODO: could be title.class or title.function
8907 hljs.UNDERSCORE_TITLE_MODE
8908 ]
8909 },
8910 STRING,
8911 NUMBER,
8912 ]
8913 };
8914 }
8915
8916 /*
8917 Language: PHP Template
8918 Requires: xml.js, php.js
8919 Author: Josh Goebel <hello@joshgoebel.com>
8920 Website: https://www.php.net
8921 Category: common
8922 */
8923
8924 function phpTemplate(hljs) {
8925 return {
8926 name: "PHP template",
8927 subLanguage: 'xml',
8928 contains: [
8929 {
8930 begin: /<\?(php|=)?/,
8931 end: /\?>/,
8932 subLanguage: 'php',
8933 contains: [
8934 // We don't want the php closing tag ?> to close the PHP block when
8935 // inside any of the following blocks:
8936 {
8937 begin: '/\\*',
8938 end: '\\*/',
8939 skip: true
8940 },
8941 {
8942 begin: 'b"',
8943 end: '"',
8944 skip: true
8945 },
8946 {
8947 begin: 'b\'',
8948 end: '\'',
8949 skip: true
8950 },
8951 hljs.inherit(hljs.APOS_STRING_MODE, {
8952 illegal: null,
8953 className: null,
8954 contains: null,
8955 skip: true
8956 }),
8957 hljs.inherit(hljs.QUOTE_STRING_MODE, {
8958 illegal: null,
8959 className: null,
8960 contains: null,
8961 skip: true
8962 })
8963 ]
8964 }
8965 ]
8966 };
8967 }
8968
8969 /*
8970 Language: Plain text
8971 Author: Egor Rogov (e.rogov@postgrespro.ru)
8972 Description: Plain text without any highlighting.
8973 Category: common
8974 */
8975
8976 function plaintext(hljs) {
8977 return {
8978 name: 'Plain text',
8979 aliases: [
8980 'text',
8981 'txt'
8982 ],
8983 disableAutodetect: true
8984 };
8985 }
8986
8987 /*
8988 Language: Python
8989 Description: Python is an interpreted, object-oriented, high-level programming language with dynamic semantics.
8990 Website: https://www.python.org
8991 Category: common
8992 */
8993
8994 function python(hljs) {
8995 const regex = hljs.regex;
8996 const IDENT_RE = /[\p{XID_Start}_]\p{XID_Continue}*/u;
8997 const RESERVED_WORDS = [
8998 'and',
8999 'as',
9000 'assert',
9001 'async',
9002 'await',
9003 'break',
9004 'case',
9005 'class',
9006 'continue',
9007 'def',
9008 'del',
9009 'elif',
9010 'else',
9011 'except',
9012 'finally',
9013 'for',
9014 'from',
9015 'global',
9016 'if',
9017 'import',
9018 'in',
9019 'is',
9020 'lambda',
9021 'match',
9022 'nonlocal|10',
9023 'not',
9024 'or',
9025 'pass',
9026 'raise',
9027 'return',
9028 'try',
9029 'while',
9030 'with',
9031 'yield'
9032 ];
9033
9034 const BUILT_INS = [
9035 '__import__',
9036 'abs',
9037 'all',
9038 'any',
9039 'ascii',
9040 'bin',
9041 'bool',
9042 'breakpoint',
9043 'bytearray',
9044 'bytes',
9045 'callable',
9046 'chr',
9047 'classmethod',
9048 'compile',
9049 'complex',
9050 'delattr',
9051 'dict',
9052 'dir',
9053 'divmod',
9054 'enumerate',
9055 'eval',
9056 'exec',
9057 'filter',
9058 'float',
9059 'format',
9060 'frozenset',
9061 'getattr',
9062 'globals',
9063 'hasattr',
9064 'hash',
9065 'help',
9066 'hex',
9067 'id',
9068 'input',
9069 'int',
9070 'isinstance',
9071 'issubclass',
9072 'iter',
9073 'len',
9074 'list',
9075 'locals',
9076 'map',
9077 'max',
9078 'memoryview',
9079 'min',
9080 'next',
9081 'object',
9082 'oct',
9083 'open',
9084 'ord',
9085 'pow',
9086 'print',
9087 'property',
9088 'range',
9089 'repr',
9090 'reversed',
9091 'round',
9092 'set',
9093 'setattr',
9094 'slice',
9095 'sorted',
9096 'staticmethod',
9097 'str',
9098 'sum',
9099 'super',
9100 'tuple',
9101 'type',
9102 'vars',
9103 'zip'
9104 ];
9105
9106 const LITERALS = [
9107 '__debug__',
9108 'Ellipsis',
9109 'False',
9110 'None',
9111 'NotImplemented',
9112 'True'
9113 ];
9114
9115 // https://docs.python.org/3/library/typing.html
9116 // TODO: Could these be supplemented by a CamelCase matcher in certain
9117 // contexts, leaving these remaining only for relevance hinting?
9118 const TYPES = [
9119 "Any",
9120 "Callable",
9121 "Coroutine",
9122 "Dict",
9123 "List",
9124 "Literal",
9125 "Generic",
9126 "Optional",
9127 "Sequence",
9128 "Set",
9129 "Tuple",
9130 "Type",
9131 "Union"
9132 ];
9133
9134 const KEYWORDS = {
9135 $pattern: /[A-Za-z]\w+|__\w+__/,
9136 keyword: RESERVED_WORDS,
9137 built_in: BUILT_INS,
9138 literal: LITERALS,
9139 type: TYPES
9140 };
9141
9142 const PROMPT = {
9143 className: 'meta',
9144 begin: /^(>>>|\.\.\.) /
9145 };
9146
9147 const SUBST = {
9148 className: 'subst',
9149 begin: /\{/,
9150 end: /\}/,
9151 keywords: KEYWORDS,
9152 illegal: /#/
9153 };
9154
9155 const LITERAL_BRACKET = {
9156 begin: /\{\{/,
9157 relevance: 0
9158 };
9159
9160 const STRING = {
9161 className: 'string',
9162 contains: [ hljs.BACKSLASH_ESCAPE ],
9163 variants: [
9164 {
9165 begin: /([uU]|[bB]|[rR]|[bB][rR]|[rR][bB])?'''/,
9166 end: /'''/,
9167 contains: [
9168 hljs.BACKSLASH_ESCAPE,
9169 PROMPT
9170 ],
9171 relevance: 10
9172 },
9173 {
9174 begin: /([uU]|[bB]|[rR]|[bB][rR]|[rR][bB])?"""/,
9175 end: /"""/,
9176 contains: [
9177 hljs.BACKSLASH_ESCAPE,
9178 PROMPT
9179 ],
9180 relevance: 10
9181 },
9182 {
9183 begin: /([fF][rR]|[rR][fF]|[fF])'''/,
9184 end: /'''/,
9185 contains: [
9186 hljs.BACKSLASH_ESCAPE,
9187 PROMPT,
9188 LITERAL_BRACKET,
9189 SUBST
9190 ]
9191 },
9192 {
9193 begin: /([fF][rR]|[rR][fF]|[fF])"""/,
9194 end: /"""/,
9195 contains: [
9196 hljs.BACKSLASH_ESCAPE,
9197 PROMPT,
9198 LITERAL_BRACKET,
9199 SUBST
9200 ]
9201 },
9202 {
9203 begin: /([uU]|[rR])'/,
9204 end: /'/,
9205 relevance: 10
9206 },
9207 {
9208 begin: /([uU]|[rR])"/,
9209 end: /"/,
9210 relevance: 10
9211 },
9212 {
9213 begin: /([bB]|[bB][rR]|[rR][bB])'/,
9214 end: /'/
9215 },
9216 {
9217 begin: /([bB]|[bB][rR]|[rR][bB])"/,
9218 end: /"/
9219 },
9220 {
9221 begin: /([fF][rR]|[rR][fF]|[fF])'/,
9222 end: /'/,
9223 contains: [
9224 hljs.BACKSLASH_ESCAPE,
9225 LITERAL_BRACKET,
9226 SUBST
9227 ]
9228 },
9229 {
9230 begin: /([fF][rR]|[rR][fF]|[fF])"/,
9231 end: /"/,
9232 contains: [
9233 hljs.BACKSLASH_ESCAPE,
9234 LITERAL_BRACKET,
9235 SUBST
9236 ]
9237 },
9238 hljs.APOS_STRING_MODE,
9239 hljs.QUOTE_STRING_MODE
9240 ]
9241 };
9242
9243 // https://docs.python.org/3.9/reference/lexical_analysis.html#numeric-literals
9244 const digitpart = '[0-9](_?[0-9])*';
9245 const pointfloat = `(\\b(${digitpart}))?\\.(${digitpart})|\\b(${digitpart})\\.`;
9246 // Whitespace after a number (or any lexical token) is needed only if its absence
9247 // would change the tokenization
9248 // https://docs.python.org/3.9/reference/lexical_analysis.html#whitespace-between-tokens
9249 // We deviate slightly, requiring a word boundary or a keyword
9250 // to avoid accidentally recognizing *prefixes* (e.g., `0` in `0x41` or `08` or `0__1`)
9251 const lookahead = `\\b|${RESERVED_WORDS.join('|')}`;
9252 const NUMBER = {
9253 className: 'number',
9254 relevance: 0,
9255 variants: [
9256 // exponentfloat, pointfloat
9257 // https://docs.python.org/3.9/reference/lexical_analysis.html#floating-point-literals
9258 // optionally imaginary
9259 // https://docs.python.org/3.9/reference/lexical_analysis.html#imaginary-literals
9260 // Note: no leading \b because floats can start with a decimal point
9261 // and we don't want to mishandle e.g. `fn(.5)`,
9262 // no trailing \b for pointfloat because it can end with a decimal point
9263 // and we don't want to mishandle e.g. `0..hex()`; this should be safe
9264 // because both MUST contain a decimal point and so cannot be confused with
9265 // the interior part of an identifier
9266 {
9267 begin: `(\\b(${digitpart})|(${pointfloat}))[eE][+-]?(${digitpart})[jJ]?(?=${lookahead})`
9268 },
9269 {
9270 begin: `(${pointfloat})[jJ]?`
9271 },
9272
9273 // decinteger, bininteger, octinteger, hexinteger
9274 // https://docs.python.org/3.9/reference/lexical_analysis.html#integer-literals
9275 // optionally "long" in Python 2
9276 // https://docs.python.org/2.7/reference/lexical_analysis.html#integer-and-long-integer-literals
9277 // decinteger is optionally imaginary
9278 // https://docs.python.org/3.9/reference/lexical_analysis.html#imaginary-literals
9279 {
9280 begin: `\\b([1-9](_?[0-9])*|0+(_?0)*)[lLjJ]?(?=${lookahead})`
9281 },
9282 {
9283 begin: `\\b0[bB](_?[01])+[lL]?(?=${lookahead})`
9284 },
9285 {
9286 begin: `\\b0[oO](_?[0-7])+[lL]?(?=${lookahead})`
9287 },
9288 {
9289 begin: `\\b0[xX](_?[0-9a-fA-F])+[lL]?(?=${lookahead})`
9290 },
9291
9292 // imagnumber (digitpart-based)
9293 // https://docs.python.org/3.9/reference/lexical_analysis.html#imaginary-literals
9294 {
9295 begin: `\\b(${digitpart})[jJ](?=${lookahead})`
9296 }
9297 ]
9298 };
9299 const COMMENT_TYPE = {
9300 className: "comment",
9301 begin: regex.lookahead(/# type:/),
9302 end: /$/,
9303 keywords: KEYWORDS,
9304 contains: [
9305 { // prevent keywords from coloring `type`
9306 begin: /# type:/
9307 },
9308 // comment within a datatype comment includes no keywords
9309 {
9310 begin: /#/,
9311 end: /\b\B/,
9312 endsWithParent: true
9313 }
9314 ]
9315 };
9316 const PARAMS = {
9317 className: 'params',
9318 variants: [
9319 // Exclude params in functions without params
9320 {
9321 className: "",
9322 begin: /\(\s*\)/,
9323 skip: true
9324 },
9325 {
9326 begin: /\(/,
9327 end: /\)/,
9328 excludeBegin: true,
9329 excludeEnd: true,
9330 keywords: KEYWORDS,
9331 contains: [
9332 'self',
9333 PROMPT,
9334 NUMBER,
9335 STRING,
9336 hljs.HASH_COMMENT_MODE
9337 ]
9338 }
9339 ]
9340 };
9341 SUBST.contains = [
9342 STRING,
9343 NUMBER,
9344 PROMPT
9345 ];
9346
9347 return {
9348 name: 'Python',
9349 aliases: [
9350 'py',
9351 'gyp',
9352 'ipython'
9353 ],
9354 unicodeRegex: true,
9355 keywords: KEYWORDS,
9356 illegal: /(<\/|->|\?)|=>/,
9357 contains: [
9358 PROMPT,
9359 NUMBER,
9360 {
9361 // very common convention
9362 begin: /\bself\b/
9363 },
9364 {
9365 // eat "if" prior to string so that it won't accidentally be
9366 // labeled as an f-string
9367 beginKeywords: "if",
9368 relevance: 0
9369 },
9370 STRING,
9371 COMMENT_TYPE,
9372 hljs.HASH_COMMENT_MODE,
9373 {
9374 match: [
9375 /\bdef/, /\s+/,
9376 IDENT_RE,
9377 ],
9378 scope: {
9379 1: "keyword",
9380 3: "title.function"
9381 },
9382 contains: [ PARAMS ]
9383 },
9384 {
9385 variants: [
9386 {
9387 match: [
9388 /\bclass/, /\s+/,
9389 IDENT_RE, /\s*/,
9390 /\(\s*/, IDENT_RE,/\s*\)/
9391 ],
9392 },
9393 {
9394 match: [
9395 /\bclass/, /\s+/,
9396 IDENT_RE
9397 ],
9398 }
9399 ],
9400 scope: {
9401 1: "keyword",
9402 3: "title.class",
9403 6: "title.class.inherited",
9404 }
9405 },
9406 {
9407 className: 'meta',
9408 begin: /^[\t ]*@/,
9409 end: /(?=#)|$/,
9410 contains: [
9411 NUMBER,
9412 PARAMS,
9413 STRING
9414 ]
9415 }
9416 ]
9417 };
9418 }
9419
9420 /*
9421 Language: Python REPL
9422 Requires: python.js
9423 Author: Josh Goebel <hello@joshgoebel.com>
9424 Category: common
9425 */
9426
9427 function pythonRepl(hljs) {
9428 return {
9429 aliases: [ 'pycon' ],
9430 contains: [
9431 {
9432 className: 'meta.prompt',
9433 starts: {
9434 // a space separates the REPL prefix from the actual code
9435 // this is purely for cleaner HTML output
9436 end: / |$/,
9437 starts: {
9438 end: '$',
9439 subLanguage: 'python'
9440 }
9441 },
9442 variants: [
9443 { begin: /^>>>(?=[ ]|$)/ },
9444 { begin: /^\.\.\.(?=[ ]|$)/ }
9445 ]
9446 }
9447 ]
9448 };
9449 }
9450
9451 /*
9452 Language: R
9453 Description: R is a free software environment for statistical computing and graphics.
9454 Author: Joe Cheng <joe@rstudio.org>
9455 Contributors: Konrad Rudolph <konrad.rudolph@gmail.com>
9456 Website: https://www.r-project.org
9457 Category: common,scientific
9458 */
9459
9460 /** @type LanguageFn */
9461 function r(hljs) {
9462 const regex = hljs.regex;
9463 // Identifiers in R cannot start with `_`, but they can start with `.` if it
9464 // is not immediately followed by a digit.
9465 // R also supports quoted identifiers, which are near-arbitrary sequences
9466 // delimited by backticks (`…`), which may contain escape sequences. These are
9467 // handled in a separate mode. See `test/markup/r/names.txt` for examples.
9468 // FIXME: Support Unicode identifiers.
9469 const IDENT_RE = /(?:(?:[a-zA-Z]|\.[._a-zA-Z])[._a-zA-Z0-9]*)|\.(?!\d)/;
9470 const NUMBER_TYPES_RE = regex.either(
9471 // Special case: only hexadecimal binary powers can contain fractions
9472 /0[xX][0-9a-fA-F]+\.[0-9a-fA-F]*[pP][+-]?\d+i?/,
9473 // Hexadecimal numbers without fraction and optional binary power
9474 /0[xX][0-9a-fA-F]+(?:[pP][+-]?\d+)?[Li]?/,
9475 // Decimal numbers
9476 /(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+)?[Li]?/
9477 );
9478 const OPERATORS_RE = /[=!<>:]=|\|\||&&|:::?|<-|<<-|->>|->|\|>|[-+*\/?!$&|:<=>@^~]|\*\*/;
9479 const PUNCTUATION_RE = regex.either(
9480 /[()]/,
9481 /[{}]/,
9482 /\[\[/,
9483 /[[\]]/,
9484 /\\/,
9485 /,/
9486 );
9487
9488 return {
9489 name: 'R',
9490
9491 keywords: {
9492 $pattern: IDENT_RE,
9493 keyword:
9494 'function if in break next repeat else for while',
9495 literal:
9496 'NULL NA TRUE FALSE Inf NaN NA_integer_|10 NA_real_|10 '
9497 + 'NA_character_|10 NA_complex_|10',
9498 built_in:
9499 // Builtin constants
9500 'LETTERS letters month.abb month.name pi T F '
9501 // Primitive functions
9502 // These are all the functions in `base` that are implemented as a
9503 // `.Primitive`, minus those functions that are also keywords.
9504 + 'abs acos acosh all any anyNA Arg as.call as.character '
9505 + 'as.complex as.double as.environment as.integer as.logical '
9506 + 'as.null.default as.numeric as.raw asin asinh atan atanh attr '
9507 + 'attributes baseenv browser c call ceiling class Conj cos cosh '
9508 + 'cospi cummax cummin cumprod cumsum digamma dim dimnames '
9509 + 'emptyenv exp expression floor forceAndCall gamma gc.time '
9510 + 'globalenv Im interactive invisible is.array is.atomic is.call '
9511 + 'is.character is.complex is.double is.environment is.expression '
9512 + 'is.finite is.function is.infinite is.integer is.language '
9513 + 'is.list is.logical is.matrix is.na is.name is.nan is.null '
9514 + 'is.numeric is.object is.pairlist is.raw is.recursive is.single '
9515 + 'is.symbol lazyLoadDBfetch length lgamma list log max min '
9516 + 'missing Mod names nargs nzchar oldClass on.exit pos.to.env '
9517 + 'proc.time prod quote range Re rep retracemem return round '
9518 + 'seq_along seq_len seq.int sign signif sin sinh sinpi sqrt '
9519 + 'standardGeneric substitute sum switch tan tanh tanpi tracemem '
9520 + 'trigamma trunc unclass untracemem UseMethod xtfrm',
9521 },
9522
9523 contains: [
9524 // Roxygen comments
9525 hljs.COMMENT(
9526 /#'/,
9527 /$/,
9528 { contains: [
9529 {
9530 // Handle `@examples` separately to cause all subsequent code
9531 // until the next `@`-tag on its own line to be kept as-is,
9532 // preventing highlighting. This code is example R code, so nested
9533 // doctags shouldn’t be treated as such. See
9534 // `test/markup/r/roxygen.txt` for an example.
9535 scope: 'doctag',
9536 match: /@examples/,
9537 starts: {
9538 end: regex.lookahead(regex.either(
9539 // end if another doc comment
9540 /\n^#'\s*(?=@[a-zA-Z]+)/,
9541 // or a line with no comment
9542 /\n^(?!#')/
9543 )),
9544 endsParent: true
9545 }
9546 },
9547 {
9548 // Handle `@param` to highlight the parameter name following
9549 // after.
9550 scope: 'doctag',
9551 begin: '@param',
9552 end: /$/,
9553 contains: [
9554 {
9555 scope: 'variable',
9556 variants: [
9557 { match: IDENT_RE },
9558 { match: /`(?:\\.|[^`\\])+`/ }
9559 ],
9560 endsParent: true
9561 }
9562 ]
9563 },
9564 {
9565 scope: 'doctag',
9566 match: /@[a-zA-Z]+/
9567 },
9568 {
9569 scope: 'keyword',
9570 match: /\\[a-zA-Z]+/
9571 }
9572 ] }
9573 ),
9574
9575 hljs.HASH_COMMENT_MODE,
9576
9577 {
9578 scope: 'string',
9579 contains: [ hljs.BACKSLASH_ESCAPE ],
9580 variants: [
9581 hljs.END_SAME_AS_BEGIN({
9582 begin: /[rR]"(-*)\(/,
9583 end: /\)(-*)"/
9584 }),
9585 hljs.END_SAME_AS_BEGIN({
9586 begin: /[rR]"(-*)\{/,
9587 end: /\}(-*)"/
9588 }),
9589 hljs.END_SAME_AS_BEGIN({
9590 begin: /[rR]"(-*)\[/,
9591 end: /\](-*)"/
9592 }),
9593 hljs.END_SAME_AS_BEGIN({
9594 begin: /[rR]'(-*)\(/,
9595 end: /\)(-*)'/
9596 }),
9597 hljs.END_SAME_AS_BEGIN({
9598 begin: /[rR]'(-*)\{/,
9599 end: /\}(-*)'/
9600 }),
9601 hljs.END_SAME_AS_BEGIN({
9602 begin: /[rR]'(-*)\[/,
9603 end: /\](-*)'/
9604 }),
9605 {
9606 begin: '"',
9607 end: '"',
9608 relevance: 0
9609 },
9610 {
9611 begin: "'",
9612 end: "'",
9613 relevance: 0
9614 }
9615 ],
9616 },
9617
9618 // Matching numbers immediately following punctuation and operators is
9619 // tricky since we need to look at the character ahead of a number to
9620 // ensure the number is not part of an identifier, and we cannot use
9621 // negative look-behind assertions. So instead we explicitly handle all
9622 // possible combinations of (operator|punctuation), number.
9623 // TODO: replace with negative look-behind when available
9624 // { begin: /(?<![a-zA-Z0-9._])0[xX][0-9a-fA-F]+\.[0-9a-fA-F]*[pP][+-]?\d+i?/ },
9625 // { begin: /(?<![a-zA-Z0-9._])0[xX][0-9a-fA-F]+([pP][+-]?\d+)?[Li]?/ },
9626 // { begin: /(?<![a-zA-Z0-9._])(\d+(\.\d*)?|\.\d+)([eE][+-]?\d+)?[Li]?/ }
9627 {
9628 relevance: 0,
9629 variants: [
9630 {
9631 scope: {
9632 1: 'operator',
9633 2: 'number'
9634 },
9635 match: [
9636 OPERATORS_RE,
9637 NUMBER_TYPES_RE
9638 ]
9639 },
9640 {
9641 scope: {
9642 1: 'operator',
9643 2: 'number'
9644 },
9645 match: [
9646 /%[^%]*%/,
9647 NUMBER_TYPES_RE
9648 ]
9649 },
9650 {
9651 scope: {
9652 1: 'punctuation',
9653 2: 'number'
9654 },
9655 match: [
9656 PUNCTUATION_RE,
9657 NUMBER_TYPES_RE
9658 ]
9659 },
9660 {
9661 scope: { 2: 'number' },
9662 match: [
9663 /[^a-zA-Z0-9._]|^/, // not part of an identifier, or start of document
9664 NUMBER_TYPES_RE
9665 ]
9666 }
9667 ]
9668 },
9669
9670 // Operators/punctuation when they're not directly followed by numbers
9671 {
9672 // Relevance boost for the most common assignment form.
9673 scope: { 3: 'operator' },
9674 match: [
9675 IDENT_RE,
9676 /\s+/,
9677 /<-/,
9678 /\s+/
9679 ]
9680 },
9681
9682 {
9683 scope: 'operator',
9684 relevance: 0,
9685 variants: [
9686 { match: OPERATORS_RE },
9687 { match: /%[^%]*%/ }
9688 ]
9689 },
9690
9691 {
9692 scope: 'punctuation',
9693 relevance: 0,
9694 match: PUNCTUATION_RE
9695 },
9696
9697 {
9698 // Escaped identifier
9699 begin: '`',
9700 end: '`',
9701 contains: [ { begin: /\\./ } ]
9702 }
9703 ]
9704 };
9705 }
9706
9707 /*
9708 Language: Ruby
9709 Description: Ruby is a dynamic, open source programming language with a focus on simplicity and productivity.
9710 Website: https://www.ruby-lang.org/
9711 Author: Anton Kovalyov <anton@kovalyov.net>
9712 Contributors: Peter Leonov <gojpeg@yandex.ru>, Vasily Polovnyov <vast@whiteants.net>, Loren Segal <lsegal@soen.ca>, Pascal Hurni <phi@ruby-reactive.org>, Cedric Sohrauer <sohrauer@googlemail.com>
9713 Category: common
9714 */
9715
9716 function ruby(hljs) {
9717 const regex = hljs.regex;
9718 const RUBY_METHOD_RE = '([a-zA-Z_]\\w*[!?=]?|[-+~]@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?)';
9719 // TODO: move concepts like CAMEL_CASE into `modes.js`
9720 const CLASS_NAME_RE = regex.either(
9721 /\b([A-Z]+[a-z0-9]+)+/,
9722 // ends in caps
9723 /\b([A-Z]+[a-z0-9]+)+[A-Z]+/,
9724 )
9725 ;
9726 const CLASS_NAME_WITH_NAMESPACE_RE = regex.concat(CLASS_NAME_RE, /(::\w+)*/);
9727 // very popular ruby built-ins that one might even assume
9728 // are actual keywords (despite that not being the case)
9729 const PSEUDO_KWS = [
9730 "include",
9731 "extend",
9732 "prepend",
9733 "public",
9734 "private",
9735 "protected",
9736 "raise",
9737 "throw"
9738 ];
9739 const RUBY_KEYWORDS = {
9740 "variable.constant": [
9741 "__FILE__",
9742 "__LINE__",
9743 "__ENCODING__"
9744 ],
9745 "variable.language": [
9746 "self",
9747 "super",
9748 ],
9749 keyword: [
9750 "alias",
9751 "and",
9752 "begin",
9753 "BEGIN",
9754 "break",
9755 "case",
9756 "class",
9757 "defined",
9758 "do",
9759 "else",
9760 "elsif",
9761 "end",
9762 "END",
9763 "ensure",
9764 "for",
9765 "if",
9766 "in",
9767 "module",
9768 "next",
9769 "not",
9770 "or",
9771 "redo",
9772 "require",
9773 "rescue",
9774 "retry",
9775 "return",
9776 "then",
9777 "undef",
9778 "unless",
9779 "until",
9780 "when",
9781 "while",
9782 "yield",
9783 ...PSEUDO_KWS
9784 ],
9785 built_in: [
9786 "proc",
9787 "lambda",
9788 "attr_accessor",
9789 "attr_reader",
9790 "attr_writer",
9791 "define_method",
9792 "private_constant",
9793 "module_function"
9794 ],
9795 literal: [
9796 "true",
9797 "false",
9798 "nil"
9799 ]
9800 };
9801 const YARDOCTAG = {
9802 className: 'doctag',
9803 begin: '@[A-Za-z]+'
9804 };
9805 const IRB_OBJECT = {
9806 begin: '#<',
9807 end: '>'
9808 };
9809 const COMMENT_MODES = [
9810 hljs.COMMENT(
9811 '#',
9812 '$',
9813 { contains: [ YARDOCTAG ] }
9814 ),
9815 hljs.COMMENT(
9816 '^=begin',
9817 '^=end',
9818 {
9819 contains: [ YARDOCTAG ],
9820 relevance: 10
9821 }
9822 ),
9823 hljs.COMMENT('^__END__', hljs.MATCH_NOTHING_RE)
9824 ];
9825 const SUBST = {
9826 className: 'subst',
9827 begin: /#\{/,
9828 end: /\}/,
9829 keywords: RUBY_KEYWORDS
9830 };
9831 const STRING = {
9832 className: 'string',
9833 contains: [
9834 hljs.BACKSLASH_ESCAPE,
9835 SUBST
9836 ],
9837 variants: [
9838 {
9839 begin: /'/,
9840 end: /'/
9841 },
9842 {
9843 begin: /"/,
9844 end: /"/
9845 },
9846 {
9847 begin: /`/,
9848 end: /`/
9849 },
9850 {
9851 begin: /%[qQwWx]?\(/,
9852 end: /\)/
9853 },
9854 {
9855 begin: /%[qQwWx]?\[/,
9856 end: /\]/
9857 },
9858 {
9859 begin: /%[qQwWx]?\{/,
9860 end: /\}/
9861 },
9862 {
9863 begin: /%[qQwWx]?</,
9864 end: />/
9865 },
9866 {
9867 begin: /%[qQwWx]?\//,
9868 end: /\//
9869 },
9870 {
9871 begin: /%[qQwWx]?%/,
9872 end: /%/
9873 },
9874 {
9875 begin: /%[qQwWx]?-/,
9876 end: /-/
9877 },
9878 {
9879 begin: /%[qQwWx]?\|/,
9880 end: /\|/
9881 },
9882 // in the following expressions, \B in the beginning suppresses recognition of ?-sequences
9883 // where ? is the last character of a preceding identifier, as in: `func?4`
9884 { begin: /\B\?(\\\d{1,3})/ },
9885 { begin: /\B\?(\\x[A-Fa-f0-9]{1,2})/ },
9886 { begin: /\B\?(\\u\{?[A-Fa-f0-9]{1,6}\}?)/ },
9887 { begin: /\B\?(\\M-\\C-|\\M-\\c|\\c\\M-|\\M-|\\C-\\M-)[\x20-\x7e]/ },
9888 { begin: /\B\?\\(c|C-)[\x20-\x7e]/ },
9889 { begin: /\B\?\\?\S/ },
9890 // heredocs
9891 {
9892 // this guard makes sure that we have an entire heredoc and not a false
9893 // positive (auto-detect, etc.)
9894 begin: regex.concat(
9895 /<<[-~]?'?/,
9896 regex.lookahead(/(\w+)(?=\W)[^\n]*\n(?:[^\n]*\n)*?\s*\1\b/)
9897 ),
9898 contains: [
9899 hljs.END_SAME_AS_BEGIN({
9900 begin: /(\w+)/,
9901 end: /(\w+)/,
9902 contains: [
9903 hljs.BACKSLASH_ESCAPE,
9904 SUBST
9905 ]
9906 })
9907 ]
9908 }
9909 ]
9910 };
9911
9912 // Ruby syntax is underdocumented, but this grammar seems to be accurate
9913 // as of version 2.7.2 (confirmed with (irb and `Ripper.sexp(...)`)
9914 // https://docs.ruby-lang.org/en/2.7.0/doc/syntax/literals_rdoc.html#label-Numbers
9915 const decimal = '[1-9](_?[0-9])*|0';
9916 const digits = '[0-9](_?[0-9])*';
9917 const NUMBER = {
9918 className: 'number',
9919 relevance: 0,
9920 variants: [
9921 // decimal integer/float, optionally exponential or rational, optionally imaginary
9922 { begin: `\\b(${decimal})(\\.(${digits}))?([eE][+-]?(${digits})|r)?i?\\b` },
9923
9924 // explicit decimal/binary/octal/hexadecimal integer,
9925 // optionally rational and/or imaginary
9926 { begin: "\\b0[dD][0-9](_?[0-9])*r?i?\\b" },
9927 { begin: "\\b0[bB][0-1](_?[0-1])*r?i?\\b" },
9928 { begin: "\\b0[oO][0-7](_?[0-7])*r?i?\\b" },
9929 { begin: "\\b0[xX][0-9a-fA-F](_?[0-9a-fA-F])*r?i?\\b" },
9930
9931 // 0-prefixed implicit octal integer, optionally rational and/or imaginary
9932 { begin: "\\b0(_?[0-7])+r?i?\\b" }
9933 ]
9934 };
9935
9936 const PARAMS = {
9937 variants: [
9938 {
9939 match: /\(\)/,
9940 },
9941 {
9942 className: 'params',
9943 begin: /\(/,
9944 end: /(?=\))/,
9945 excludeBegin: true,
9946 endsParent: true,
9947 keywords: RUBY_KEYWORDS,
9948 }
9949 ]
9950 };
9951
9952 const INCLUDE_EXTEND = {
9953 match: [
9954 /(include|extend)\s+/,
9955 CLASS_NAME_WITH_NAMESPACE_RE
9956 ],
9957 scope: {
9958 2: "title.class"
9959 },
9960 keywords: RUBY_KEYWORDS
9961 };
9962
9963 const CLASS_DEFINITION = {
9964 variants: [
9965 {
9966 match: [
9967 /class\s+/,
9968 CLASS_NAME_WITH_NAMESPACE_RE,
9969 /\s+<\s+/,
9970 CLASS_NAME_WITH_NAMESPACE_RE
9971 ]
9972 },
9973 {
9974 match: [
9975 /\b(class|module)\s+/,
9976 CLASS_NAME_WITH_NAMESPACE_RE
9977 ]
9978 }
9979 ],
9980 scope: {
9981 2: "title.class",
9982 4: "title.class.inherited"
9983 },
9984 keywords: RUBY_KEYWORDS
9985 };
9986
9987 const UPPER_CASE_CONSTANT = {
9988 relevance: 0,
9989 match: /\b[A-Z][A-Z_0-9]+\b/,
9990 className: "variable.constant"
9991 };
9992
9993 const METHOD_DEFINITION = {
9994 match: [
9995 /def/, /\s+/,
9996 RUBY_METHOD_RE
9997 ],
9998 scope: {
9999 1: "keyword",
10000 3: "title.function"
10001 },
10002 contains: [
10003 PARAMS
10004 ]
10005 };
10006
10007 const OBJECT_CREATION = {
10008 relevance: 0,
10009 match: [
10010 CLASS_NAME_WITH_NAMESPACE_RE,
10011 /\.new[. (]/
10012 ],
10013 scope: {
10014 1: "title.class"
10015 }
10016 };
10017
10018 // CamelCase
10019 const CLASS_REFERENCE = {
10020 relevance: 0,
10021 match: CLASS_NAME_RE,
10022 scope: "title.class"
10023 };
10024
10025 const RUBY_DEFAULT_CONTAINS = [
10026 STRING,
10027 CLASS_DEFINITION,
10028 INCLUDE_EXTEND,
10029 OBJECT_CREATION,
10030 UPPER_CASE_CONSTANT,
10031 CLASS_REFERENCE,
10032 METHOD_DEFINITION,
10033 {
10034 // swallow namespace qualifiers before symbols
10035 begin: hljs.IDENT_RE + '::' },
10036 {
10037 className: 'symbol',
10038 begin: hljs.UNDERSCORE_IDENT_RE + '(!|\\?)?:',
10039 relevance: 0
10040 },
10041 {
10042 className: 'symbol',
10043 begin: ':(?!\\s)',
10044 contains: [
10045 STRING,
10046 { begin: RUBY_METHOD_RE }
10047 ],
10048 relevance: 0
10049 },
10050 NUMBER,
10051 {
10052 // negative-look forward attempts to prevent false matches like:
10053 // @ident@ or $ident$ that might indicate this is not ruby at all
10054 className: "variable",
10055 begin: '(\\$\\W)|((\\$|@@?)(\\w+))(?=[^@$?])' + `(?![A-Za-z])(?![@$?'])`
10056 },
10057 {
10058 className: 'params',
10059 begin: /\|/,
10060 end: /\|/,
10061 excludeBegin: true,
10062 excludeEnd: true,
10063 relevance: 0, // this could be a lot of things (in other languages) other than params
10064 keywords: RUBY_KEYWORDS
10065 },
10066 { // regexp container
10067 begin: '(' + hljs.RE_STARTERS_RE + '|unless)\\s*',
10068 keywords: 'unless',
10069 contains: [
10070 {
10071 className: 'regexp',
10072 contains: [
10073 hljs.BACKSLASH_ESCAPE,
10074 SUBST
10075 ],
10076 illegal: /\n/,
10077 variants: [
10078 {
10079 begin: '/',
10080 end: '/[a-z]*'
10081 },
10082 {
10083 begin: /%r\{/,
10084 end: /\}[a-z]*/
10085 },
10086 {
10087 begin: '%r\\(',
10088 end: '\\)[a-z]*'
10089 },
10090 {
10091 begin: '%r!',
10092 end: '![a-z]*'
10093 },
10094 {
10095 begin: '%r\\[',
10096 end: '\\][a-z]*'
10097 }
10098 ]
10099 }
10100 ].concat(IRB_OBJECT, COMMENT_MODES),
10101 relevance: 0
10102 }
10103 ].concat(IRB_OBJECT, COMMENT_MODES);
10104
10105 SUBST.contains = RUBY_DEFAULT_CONTAINS;
10106 PARAMS.contains = RUBY_DEFAULT_CONTAINS;
10107
10108 // >>
10109 // ?>
10110 const SIMPLE_PROMPT = "[>?]>";
10111 // irb(main):001:0>
10112 const DEFAULT_PROMPT = "[\\w#]+\\(\\w+\\):\\d+:\\d+[>*]";
10113 const RVM_PROMPT = "(\\w+-)?\\d+\\.\\d+\\.\\d+(p\\d+)?[^\\d][^>]+>";
10114
10115 const IRB_DEFAULT = [
10116 {
10117 begin: /^\s*=>/,
10118 starts: {
10119 end: '$',
10120 contains: RUBY_DEFAULT_CONTAINS
10121 }
10122 },
10123 {
10124 className: 'meta.prompt',
10125 begin: '^(' + SIMPLE_PROMPT + "|" + DEFAULT_PROMPT + '|' + RVM_PROMPT + ')(?=[ ])',
10126 starts: {
10127 end: '$',
10128 keywords: RUBY_KEYWORDS,
10129 contains: RUBY_DEFAULT_CONTAINS
10130 }
10131 }
10132 ];
10133
10134 COMMENT_MODES.unshift(IRB_OBJECT);
10135
10136 return {
10137 name: 'Ruby',
10138 aliases: [
10139 'rb',
10140 'gemspec',
10141 'podspec',
10142 'thor',
10143 'irb'
10144 ],
10145 keywords: RUBY_KEYWORDS,
10146 illegal: /\/\*/,
10147 contains: [ hljs.SHEBANG({ binary: "ruby" }) ]
10148 .concat(IRB_DEFAULT)
10149 .concat(COMMENT_MODES)
10150 .concat(RUBY_DEFAULT_CONTAINS)
10151 };
10152 }
10153
10154 /*
10155 Language: Rust
10156 Author: Andrey Vlasovskikh <andrey.vlasovskikh@gmail.com>
10157 Contributors: Roman Shmatov <romanshmatov@gmail.com>, Kasper Andersen <kma_untrusted@protonmail.com>
10158 Website: https://www.rust-lang.org
10159 Category: common, system
10160 */
10161
10162 /** @type LanguageFn */
10163 function rust(hljs) {
10164 const regex = hljs.regex;
10165 const FUNCTION_INVOKE = {
10166 className: "title.function.invoke",
10167 relevance: 0,
10168 begin: regex.concat(
10169 /\b/,
10170 /(?!let\b)/,
10171 hljs.IDENT_RE,
10172 regex.lookahead(/\s*\(/))
10173 };
10174 const NUMBER_SUFFIX = '([ui](8|16|32|64|128|size)|f(32|64))\?';
10175 const KEYWORDS = [
10176 "abstract",
10177 "as",
10178 "async",
10179 "await",
10180 "become",
10181 "box",
10182 "break",
10183 "const",
10184 "continue",
10185 "crate",
10186 "do",
10187 "dyn",
10188 "else",
10189 "enum",
10190 "extern",
10191 "false",
10192 "final",
10193 "fn",
10194 "for",
10195 "if",
10196 "impl",
10197 "in",
10198 "let",
10199 "loop",
10200 "macro",
10201 "match",
10202 "mod",
10203 "move",
10204 "mut",
10205 "override",
10206 "priv",
10207 "pub",
10208 "ref",
10209 "return",
10210 "self",
10211 "Self",
10212 "static",
10213 "struct",
10214 "super",
10215 "trait",
10216 "true",
10217 "try",
10218 "type",
10219 "typeof",
10220 "unsafe",
10221 "unsized",
10222 "use",
10223 "virtual",
10224 "where",
10225 "while",
10226 "yield"
10227 ];
10228 const LITERALS = [
10229 "true",
10230 "false",
10231 "Some",
10232 "None",
10233 "Ok",
10234 "Err"
10235 ];
10236 const BUILTINS = [
10237 // functions
10238 'drop ',
10239 // traits
10240 "Copy",
10241 "Send",
10242 "Sized",
10243 "Sync",
10244 "Drop",
10245 "Fn",
10246 "FnMut",
10247 "FnOnce",
10248 "ToOwned",
10249 "Clone",
10250 "Debug",
10251 "PartialEq",
10252 "PartialOrd",
10253 "Eq",
10254 "Ord",
10255 "AsRef",
10256 "AsMut",
10257 "Into",
10258 "From",
10259 "Default",
10260 "Iterator",
10261 "Extend",
10262 "IntoIterator",
10263 "DoubleEndedIterator",
10264 "ExactSizeIterator",
10265 "SliceConcatExt",
10266 "ToString",
10267 // macros
10268 "assert!",
10269 "assert_eq!",
10270 "bitflags!",
10271 "bytes!",
10272 "cfg!",
10273 "col!",
10274 "concat!",
10275 "concat_idents!",
10276 "debug_assert!",
10277 "debug_assert_eq!",
10278 "env!",
10279 "panic!",
10280 "file!",
10281 "format!",
10282 "format_args!",
10283 "include_bytes!",
10284 "include_str!",
10285 "line!",
10286 "local_data_key!",
10287 "module_path!",
10288 "option_env!",
10289 "print!",
10290 "println!",
10291 "select!",
10292 "stringify!",
10293 "try!",
10294 "unimplemented!",
10295 "unreachable!",
10296 "vec!",
10297 "write!",
10298 "writeln!",
10299 "macro_rules!",
10300 "assert_ne!",
10301 "debug_assert_ne!"
10302 ];
10303 const TYPES = [
10304 "i8",
10305 "i16",
10306 "i32",
10307 "i64",
10308 "i128",
10309 "isize",
10310 "u8",
10311 "u16",
10312 "u32",
10313 "u64",
10314 "u128",
10315 "usize",
10316 "f32",
10317 "f64",
10318 "str",
10319 "char",
10320 "bool",
10321 "Box",
10322 "Option",
10323 "Result",
10324 "String",
10325 "Vec"
10326 ];
10327 return {
10328 name: 'Rust',
10329 aliases: [ 'rs' ],
10330 keywords: {
10331 $pattern: hljs.IDENT_RE + '!?',
10332 type: TYPES,
10333 keyword: KEYWORDS,
10334 literal: LITERALS,
10335 built_in: BUILTINS
10336 },
10337 illegal: '</',
10338 contains: [
10339 hljs.C_LINE_COMMENT_MODE,
10340 hljs.COMMENT('/\\*', '\\*/', { contains: [ 'self' ] }),
10341 hljs.inherit(hljs.QUOTE_STRING_MODE, {
10342 begin: /b?"/,
10343 illegal: null
10344 }),
10345 {
10346 className: 'string',
10347 variants: [
10348 { begin: /b?r(#*)"(.|\n)*?"\1(?!#)/ },
10349 { begin: /b?'\\?(x\w{2}|u\w{4}|U\w{8}|.)'/ }
10350 ]
10351 },
10352 {
10353 className: 'symbol',
10354 begin: /'[a-zA-Z_][a-zA-Z0-9_]*/
10355 },
10356 {
10357 className: 'number',
10358 variants: [
10359 { begin: '\\b0b([01_]+)' + NUMBER_SUFFIX },
10360 { begin: '\\b0o([0-7_]+)' + NUMBER_SUFFIX },
10361 { begin: '\\b0x([A-Fa-f0-9_]+)' + NUMBER_SUFFIX },
10362 { begin: '\\b(\\d[\\d_]*(\\.[0-9_]+)?([eE][+-]?[0-9_]+)?)'
10363 + NUMBER_SUFFIX }
10364 ],
10365 relevance: 0
10366 },
10367 {
10368 begin: [
10369 /fn/,
10370 /\s+/,
10371 hljs.UNDERSCORE_IDENT_RE
10372 ],
10373 className: {
10374 1: "keyword",
10375 3: "title.function"
10376 }
10377 },
10378 {
10379 className: 'meta',
10380 begin: '#!?\\[',
10381 end: '\\]',
10382 contains: [
10383 {
10384 className: 'string',
10385 begin: /"/,
10386 end: /"/
10387 }
10388 ]
10389 },
10390 {
10391 begin: [
10392 /let/,
10393 /\s+/,
10394 /(?:mut\s+)?/,
10395 hljs.UNDERSCORE_IDENT_RE
10396 ],
10397 className: {
10398 1: "keyword",
10399 3: "keyword",
10400 4: "variable"
10401 }
10402 },
10403 // must come before impl/for rule later
10404 {
10405 begin: [
10406 /for/,
10407 /\s+/,
10408 hljs.UNDERSCORE_IDENT_RE,
10409 /\s+/,
10410 /in/
10411 ],
10412 className: {
10413 1: "keyword",
10414 3: "variable",
10415 5: "keyword"
10416 }
10417 },
10418 {
10419 begin: [
10420 /type/,
10421 /\s+/,
10422 hljs.UNDERSCORE_IDENT_RE
10423 ],
10424 className: {
10425 1: "keyword",
10426 3: "title.class"
10427 }
10428 },
10429 {
10430 begin: [
10431 /(?:trait|enum|struct|union|impl|for)/,
10432 /\s+/,
10433 hljs.UNDERSCORE_IDENT_RE
10434 ],
10435 className: {
10436 1: "keyword",
10437 3: "title.class"
10438 }
10439 },
10440 {
10441 begin: hljs.IDENT_RE + '::',
10442 keywords: {
10443 keyword: "Self",
10444 built_in: BUILTINS,
10445 type: TYPES
10446 }
10447 },
10448 {
10449 className: "punctuation",
10450 begin: '->'
10451 },
10452 FUNCTION_INVOKE
10453 ]
10454 };
10455 }
10456
10457 /*
10458 Language: SCSS
10459 Description: Scss is an extension of the syntax of CSS.
10460 Author: Kurt Emch <kurt@kurtemch.com>
10461 Website: https://sass-lang.com
10462 Category: common, css, web
10463 */
10464
10465 /** @type LanguageFn */
10466 function scss(hljs) {
10467 const modes = MODES(hljs);
10468 const PSEUDO_ELEMENTS$1 = PSEUDO_ELEMENTS;
10469 const PSEUDO_CLASSES$1 = PSEUDO_CLASSES;
10470
10471 const AT_IDENTIFIER = '@[a-z-]+'; // @font-face
10472 const AT_MODIFIERS = "and or not only";
10473 const IDENT_RE = '[a-zA-Z-][a-zA-Z0-9_-]*';
10474 const VARIABLE = {
10475 className: 'variable',
10476 begin: '(\\$' + IDENT_RE + ')\\b',
10477 relevance: 0
10478 };
10479
10480 return {
10481 name: 'SCSS',
10482 case_insensitive: true,
10483 illegal: '[=/|\']',
10484 contains: [
10485 hljs.C_LINE_COMMENT_MODE,
10486 hljs.C_BLOCK_COMMENT_MODE,
10487 // to recognize keyframe 40% etc which are outside the scope of our
10488 // attribute value mode
10489 modes.CSS_NUMBER_MODE,
10490 {
10491 className: 'selector-id',
10492 begin: '#[A-Za-z0-9_-]+',
10493 relevance: 0
10494 },
10495 {
10496 className: 'selector-class',
10497 begin: '\\.[A-Za-z0-9_-]+',
10498 relevance: 0
10499 },
10500 modes.ATTRIBUTE_SELECTOR_MODE,
10501 {
10502 className: 'selector-tag',
10503 begin: '\\b(' + TAGS.join('|') + ')\\b',
10504 // was there, before, but why?
10505 relevance: 0
10506 },
10507 {
10508 className: 'selector-pseudo',
10509 begin: ':(' + PSEUDO_CLASSES$1.join('|') + ')'
10510 },
10511 {
10512 className: 'selector-pseudo',
10513 begin: ':(:)?(' + PSEUDO_ELEMENTS$1.join('|') + ')'
10514 },
10515 VARIABLE,
10516 { // pseudo-selector params
10517 begin: /\(/,
10518 end: /\)/,
10519 contains: [ modes.CSS_NUMBER_MODE ]
10520 },
10521 modes.CSS_VARIABLE,
10522 {
10523 className: 'attribute',
10524 begin: '\\b(' + ATTRIBUTES.join('|') + ')\\b'
10525 },
10526 { begin: '\\b(whitespace|wait|w-resize|visible|vertical-text|vertical-ideographic|uppercase|upper-roman|upper-alpha|underline|transparent|top|thin|thick|text|text-top|text-bottom|tb-rl|table-header-group|table-footer-group|sw-resize|super|strict|static|square|solid|small-caps|separate|se-resize|scroll|s-resize|rtl|row-resize|ridge|right|repeat|repeat-y|repeat-x|relative|progress|pointer|overline|outside|outset|oblique|nowrap|not-allowed|normal|none|nw-resize|no-repeat|no-drop|newspaper|ne-resize|n-resize|move|middle|medium|ltr|lr-tb|lowercase|lower-roman|lower-alpha|loose|list-item|line|line-through|line-edge|lighter|left|keep-all|justify|italic|inter-word|inter-ideograph|inside|inset|inline|inline-block|inherit|inactive|ideograph-space|ideograph-parenthesis|ideograph-numeric|ideograph-alpha|horizontal|hidden|help|hand|groove|fixed|ellipsis|e-resize|double|dotted|distribute|distribute-space|distribute-letter|distribute-all-lines|disc|disabled|default|decimal|dashed|crosshair|collapse|col-resize|circle|char|center|capitalize|break-word|break-all|bottom|both|bolder|bold|block|bidi-override|below|baseline|auto|always|all-scroll|absolute|table|table-cell)\\b' },
10527 {
10528 begin: /:/,
10529 end: /[;}{]/,
10530 relevance: 0,
10531 contains: [
10532 modes.BLOCK_COMMENT,
10533 VARIABLE,
10534 modes.HEXCOLOR,
10535 modes.CSS_NUMBER_MODE,
10536 hljs.QUOTE_STRING_MODE,
10537 hljs.APOS_STRING_MODE,
10538 modes.IMPORTANT,
10539 modes.FUNCTION_DISPATCH
10540 ]
10541 },
10542 // matching these here allows us to treat them more like regular CSS
10543 // rules so everything between the {} gets regular rule highlighting,
10544 // which is what we want for page and font-face
10545 {
10546 begin: '@(page|font-face)',
10547 keywords: {
10548 $pattern: AT_IDENTIFIER,
10549 keyword: '@page @font-face'
10550 }
10551 },
10552 {
10553 begin: '@',
10554 end: '[{;]',
10555 returnBegin: true,
10556 keywords: {
10557 $pattern: /[a-z-]+/,
10558 keyword: AT_MODIFIERS,
10559 attribute: MEDIA_FEATURES.join(" ")
10560 },
10561 contains: [
10562 {
10563 begin: AT_IDENTIFIER,
10564 className: "keyword"
10565 },
10566 {
10567 begin: /[a-z-]+(?=:)/,
10568 className: "attribute"
10569 },
10570 VARIABLE,
10571 hljs.QUOTE_STRING_MODE,
10572 hljs.APOS_STRING_MODE,
10573 modes.HEXCOLOR,
10574 modes.CSS_NUMBER_MODE
10575 ]
10576 },
10577 modes.FUNCTION_DISPATCH
10578 ]
10579 };
10580 }
10581
10582 /*
10583 Language: Shell Session
10584 Requires: bash.js
10585 Author: TSUYUSATO Kitsune <make.just.on@gmail.com>
10586 Category: common
10587 Audit: 2020
10588 */
10589
10590 /** @type LanguageFn */
10591 function shell(hljs) {
10592 return {
10593 name: 'Shell Session',
10594 aliases: [
10595 'console',
10596 'shellsession'
10597 ],
10598 contains: [
10599 {
10600 className: 'meta.prompt',
10601 // We cannot add \s (spaces) in the regular expression otherwise it will be too broad and produce unexpected result.
10602 // For instance, in the following example, it would match "echo /path/to/home >" as a prompt:
10603 // echo /path/to/home > t.exe
10604 begin: /^\s{0,3}[/~\w\d[\]()@-]*[>%$#][ ]?/,
10605 starts: {
10606 end: /[^\\](?=\s*$)/,
10607 subLanguage: 'bash'
10608 }
10609 }
10610 ]
10611 };
10612 }
10613
10614 /*
10615 Language: SQL
10616 Website: https://en.wikipedia.org/wiki/SQL
10617 Category: common, database
10618 */
10619
10620 /*
10621
10622 Goals:
10623
10624 SQL is intended to highlight basic/common SQL keywords and expressions
10625
10626 - If pretty much every single SQL server includes supports, then it's a canidate.
10627 - It is NOT intended to include tons of vendor specific keywords (Oracle, MySQL,
10628 PostgreSQL) although the list of data types is purposely a bit more expansive.
10629 - For more specific SQL grammars please see:
10630 - PostgreSQL and PL/pgSQL - core
10631 - T-SQL - https://github.com/highlightjs/highlightjs-tsql
10632 - sql_more (core)
10633
10634 */
10635
10636 function sql(hljs) {
10637 const regex = hljs.regex;
10638 const COMMENT_MODE = hljs.COMMENT('--', '$');
10639 const STRING = {
10640 className: 'string',
10641 variants: [
10642 {
10643 begin: /'/,
10644 end: /'/,
10645 contains: [ { begin: /''/ } ]
10646 }
10647 ]
10648 };
10649 const QUOTED_IDENTIFIER = {
10650 begin: /"/,
10651 end: /"/,
10652 contains: [ { begin: /""/ } ]
10653 };
10654
10655 const LITERALS = [
10656 "true",
10657 "false",
10658 // Not sure it's correct to call NULL literal, and clauses like IS [NOT] NULL look strange that way.
10659 // "null",
10660 "unknown"
10661 ];
10662
10663 const MULTI_WORD_TYPES = [
10664 "double precision",
10665 "large object",
10666 "with timezone",
10667 "without timezone"
10668 ];
10669
10670 const TYPES = [
10671 'bigint',
10672 'binary',
10673 'blob',
10674 'boolean',
10675 'char',
10676 'character',
10677 'clob',
10678 'date',
10679 'dec',
10680 'decfloat',
10681 'decimal',
10682 'float',
10683 'int',
10684 'integer',
10685 'interval',
10686 'nchar',
10687 'nclob',
10688 'national',
10689 'numeric',
10690 'real',
10691 'row',
10692 'smallint',
10693 'time',
10694 'timestamp',
10695 'varchar',
10696 'varying', // modifier (character varying)
10697 'varbinary'
10698 ];
10699
10700 const NON_RESERVED_WORDS = [
10701 "add",
10702 "asc",
10703 "collation",
10704 "desc",
10705 "final",
10706 "first",
10707 "last",
10708 "view"
10709 ];
10710
10711 // https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#reserved-word
10712 const RESERVED_WORDS = [
10713 "abs",
10714 "acos",
10715 "all",
10716 "allocate",
10717 "alter",
10718 "and",
10719 "any",
10720 "are",
10721 "array",
10722 "array_agg",
10723 "array_max_cardinality",
10724 "as",
10725 "asensitive",
10726 "asin",
10727 "asymmetric",
10728 "at",
10729 "atan",
10730 "atomic",
10731 "authorization",
10732 "avg",
10733 "begin",
10734 "begin_frame",
10735 "begin_partition",
10736 "between",
10737 "bigint",
10738 "binary",
10739 "blob",
10740 "boolean",
10741 "both",
10742 "by",
10743 "call",
10744 "called",
10745 "cardinality",
10746 "cascaded",
10747 "case",
10748 "cast",
10749 "ceil",
10750 "ceiling",
10751 "char",
10752 "char_length",
10753 "character",
10754 "character_length",
10755 "check",
10756 "classifier",
10757 "clob",
10758 "close",
10759 "coalesce",
10760 "collate",
10761 "collect",
10762 "column",
10763 "commit",
10764 "condition",
10765 "connect",
10766 "constraint",
10767 "contains",
10768 "convert",
10769 "copy",
10770 "corr",
10771 "corresponding",
10772 "cos",
10773 "cosh",
10774 "count",
10775 "covar_pop",
10776 "covar_samp",
10777 "create",
10778 "cross",
10779 "cube",
10780 "cume_dist",
10781 "current",
10782 "current_catalog",
10783 "current_date",
10784 "current_default_transform_group",
10785 "current_path",
10786 "current_role",
10787 "current_row",
10788 "current_schema",
10789 "current_time",
10790 "current_timestamp",
10791 "current_path",
10792 "current_role",
10793 "current_transform_group_for_type",
10794 "current_user",
10795 "cursor",
10796 "cycle",
10797 "date",
10798 "day",
10799 "deallocate",
10800 "dec",
10801 "decimal",
10802 "decfloat",
10803 "declare",
10804 "default",
10805 "define",
10806 "delete",
10807 "dense_rank",
10808 "deref",
10809 "describe",
10810 "deterministic",
10811 "disconnect",
10812 "distinct",
10813 "double",
10814 "drop",
10815 "dynamic",
10816 "each",
10817 "element",
10818 "else",
10819 "empty",
10820 "end",
10821 "end_frame",
10822 "end_partition",
10823 "end-exec",
10824 "equals",
10825 "escape",
10826 "every",
10827 "except",
10828 "exec",
10829 "execute",
10830 "exists",
10831 "exp",
10832 "external",
10833 "extract",
10834 "false",
10835 "fetch",
10836 "filter",
10837 "first_value",
10838 "float",
10839 "floor",
10840 "for",
10841 "foreign",
10842 "frame_row",
10843 "free",
10844 "from",
10845 "full",
10846 "function",
10847 "fusion",
10848 "get",
10849 "global",
10850 "grant",
10851 "group",
10852 "grouping",
10853 "groups",
10854 "having",
10855 "hold",
10856 "hour",
10857 "identity",
10858 "in",
10859 "indicator",
10860 "initial",
10861 "inner",
10862 "inout",
10863 "insensitive",
10864 "insert",
10865 "int",
10866 "integer",
10867 "intersect",
10868 "intersection",
10869 "interval",
10870 "into",
10871 "is",
10872 "join",
10873 "json_array",
10874 "json_arrayagg",
10875 "json_exists",
10876 "json_object",
10877 "json_objectagg",
10878 "json_query",
10879 "json_table",
10880 "json_table_primitive",
10881 "json_value",
10882 "lag",
10883 "language",
10884 "large",
10885 "last_value",
10886 "lateral",
10887 "lead",
10888 "leading",
10889 "left",
10890 "like",
10891 "like_regex",
10892 "listagg",
10893 "ln",
10894 "local",
10895 "localtime",
10896 "localtimestamp",
10897 "log",
10898 "log10",
10899 "lower",
10900 "match",
10901 "match_number",
10902 "match_recognize",
10903 "matches",
10904 "max",
10905 "member",
10906 "merge",
10907 "method",
10908 "min",
10909 "minute",
10910 "mod",
10911 "modifies",
10912 "module",
10913 "month",
10914 "multiset",
10915 "national",
10916 "natural",
10917 "nchar",
10918 "nclob",
10919 "new",
10920 "no",
10921 "none",
10922 "normalize",
10923 "not",
10924 "nth_value",
10925 "ntile",
10926 "null",
10927 "nullif",
10928 "numeric",
10929 "octet_length",
10930 "occurrences_regex",
10931 "of",
10932 "offset",
10933 "old",
10934 "omit",
10935 "on",
10936 "one",
10937 "only",
10938 "open",
10939 "or",
10940 "order",
10941 "out",
10942 "outer",
10943 "over",
10944 "overlaps",
10945 "overlay",
10946 "parameter",
10947 "partition",
10948 "pattern",
10949 "per",
10950 "percent",
10951 "percent_rank",
10952 "percentile_cont",
10953 "percentile_disc",
10954 "period",
10955 "portion",
10956 "position",
10957 "position_regex",
10958 "power",
10959 "precedes",
10960 "precision",
10961 "prepare",
10962 "primary",
10963 "procedure",
10964 "ptf",
10965 "range",
10966 "rank",
10967 "reads",
10968 "real",
10969 "recursive",
10970 "ref",
10971 "references",
10972 "referencing",
10973 "regr_avgx",
10974 "regr_avgy",
10975 "regr_count",
10976 "regr_intercept",
10977 "regr_r2",
10978 "regr_slope",
10979 "regr_sxx",
10980 "regr_sxy",
10981 "regr_syy",
10982 "release",
10983 "result",
10984 "return",
10985 "returns",
10986 "revoke",
10987 "right",
10988 "rollback",
10989 "rollup",
10990 "row",
10991 "row_number",
10992 "rows",
10993 "running",
10994 "savepoint",
10995 "scope",
10996 "scroll",
10997 "search",
10998 "second",
10999 "seek",
11000 "select",
11001 "sensitive",
11002 "session_user",
11003 "set",
11004 "show",
11005 "similar",
11006 "sin",
11007 "sinh",
11008 "skip",
11009 "smallint",
11010 "some",
11011 "specific",
11012 "specifictype",
11013 "sql",
11014 "sqlexception",
11015 "sqlstate",
11016 "sqlwarning",
11017 "sqrt",
11018 "start",
11019 "static",
11020 "stddev_pop",
11021 "stddev_samp",
11022 "submultiset",
11023 "subset",
11024 "substring",
11025 "substring_regex",
11026 "succeeds",
11027 "sum",
11028 "symmetric",
11029 "system",
11030 "system_time",
11031 "system_user",
11032 "table",
11033 "tablesample",
11034 "tan",
11035 "tanh",
11036 "then",
11037 "time",
11038 "timestamp",
11039 "timezone_hour",
11040 "timezone_minute",
11041 "to",
11042 "trailing",
11043 "translate",
11044 "translate_regex",
11045 "translation",
11046 "treat",
11047 "trigger",
11048 "trim",
11049 "trim_array",
11050 "true",
11051 "truncate",
11052 "uescape",
11053 "union",
11054 "unique",
11055 "unknown",
11056 "unnest",
11057 "update",
11058 "upper",
11059 "user",
11060 "using",
11061 "value",
11062 "values",
11063 "value_of",
11064 "var_pop",
11065 "var_samp",
11066 "varbinary",
11067 "varchar",
11068 "varying",
11069 "versioning",
11070 "when",
11071 "whenever",
11072 "where",
11073 "width_bucket",
11074 "window",
11075 "with",
11076 "within",
11077 "without",
11078 "year",
11079 ];
11080
11081 // these are reserved words we have identified to be functions
11082 // and should only be highlighted in a dispatch-like context
11083 // ie, array_agg(...), etc.
11084 const RESERVED_FUNCTIONS = [
11085 "abs",
11086 "acos",
11087 "array_agg",
11088 "asin",
11089 "atan",
11090 "avg",
11091 "cast",
11092 "ceil",
11093 "ceiling",
11094 "coalesce",
11095 "corr",
11096 "cos",
11097 "cosh",
11098 "count",
11099 "covar_pop",
11100 "covar_samp",
11101 "cume_dist",
11102 "dense_rank",
11103 "deref",
11104 "element",
11105 "exp",
11106 "extract",
11107 "first_value",
11108 "floor",
11109 "json_array",
11110 "json_arrayagg",
11111 "json_exists",
11112 "json_object",
11113 "json_objectagg",
11114 "json_query",
11115 "json_table",
11116 "json_table_primitive",
11117 "json_value",
11118 "lag",
11119 "last_value",
11120 "lead",
11121 "listagg",
11122 "ln",
11123 "log",
11124 "log10",
11125 "lower",
11126 "max",
11127 "min",
11128 "mod",
11129 "nth_value",
11130 "ntile",
11131 "nullif",
11132 "percent_rank",
11133 "percentile_cont",
11134 "percentile_disc",
11135 "position",
11136 "position_regex",
11137 "power",
11138 "rank",
11139 "regr_avgx",
11140 "regr_avgy",
11141 "regr_count",
11142 "regr_intercept",
11143 "regr_r2",
11144 "regr_slope",
11145 "regr_sxx",
11146 "regr_sxy",
11147 "regr_syy",
11148 "row_number",
11149 "sin",
11150 "sinh",
11151 "sqrt",
11152 "stddev_pop",
11153 "stddev_samp",
11154 "substring",
11155 "substring_regex",
11156 "sum",
11157 "tan",
11158 "tanh",
11159 "translate",
11160 "translate_regex",
11161 "treat",
11162 "trim",
11163 "trim_array",
11164 "unnest",
11165 "upper",
11166 "value_of",
11167 "var_pop",
11168 "var_samp",
11169 "width_bucket",
11170 ];
11171
11172 // these functions can
11173 const POSSIBLE_WITHOUT_PARENS = [
11174 "current_catalog",
11175 "current_date",
11176 "current_default_transform_group",
11177 "current_path",
11178 "current_role",
11179 "current_schema",
11180 "current_transform_group_for_type",
11181 "current_user",
11182 "session_user",
11183 "system_time",
11184 "system_user",
11185 "current_time",
11186 "localtime",
11187 "current_timestamp",
11188 "localtimestamp"
11189 ];
11190
11191 // those exist to boost relevance making these very
11192 // "SQL like" keyword combos worth +1 extra relevance
11193 const COMBOS = [
11194 "create table",
11195 "insert into",
11196 "primary key",
11197 "foreign key",
11198 "not null",
11199 "alter table",
11200 "add constraint",
11201 "grouping sets",
11202 "on overflow",
11203 "character set",
11204 "respect nulls",
11205 "ignore nulls",
11206 "nulls first",
11207 "nulls last",
11208 "depth first",
11209 "breadth first"
11210 ];
11211
11212 const FUNCTIONS = RESERVED_FUNCTIONS;
11213
11214 const KEYWORDS = [
11215 ...RESERVED_WORDS,
11216 ...NON_RESERVED_WORDS
11217 ].filter((keyword) => {
11218 return !RESERVED_FUNCTIONS.includes(keyword);
11219 });
11220
11221 const VARIABLE = {
11222 className: "variable",
11223 begin: /@[a-z0-9]+/,
11224 };
11225
11226 const OPERATOR = {
11227 className: "operator",
11228 begin: /[-+*/=%^~]|&&?|\|\|?|!=?|<(?:=>?|<|>)?|>[>=]?/,
11229 relevance: 0,
11230 };
11231
11232 const FUNCTION_CALL = {
11233 begin: regex.concat(/\b/, regex.either(...FUNCTIONS), /\s*\(/),
11234 relevance: 0,
11235 keywords: { built_in: FUNCTIONS }
11236 };
11237
11238 // keywords with less than 3 letters are reduced in relevancy
11239 function reduceRelevancy(list, {
11240 exceptions, when
11241 } = {}) {
11242 const qualifyFn = when;
11243 exceptions = exceptions || [];
11244 return list.map((item) => {
11245 if (item.match(/\|\d+$/) || exceptions.includes(item)) {
11246 return item;
11247 } else if (qualifyFn(item)) {
11248 return `${item}|0`;
11249 } else {
11250 return item;
11251 }
11252 });
11253 }
11254
11255 return {
11256 name: 'SQL',
11257 case_insensitive: true,
11258 // does not include {} or HTML tags `</`
11259 illegal: /[{}]|<\//,
11260 keywords: {
11261 $pattern: /\b[\w\.]+/,
11262 keyword:
11263 reduceRelevancy(KEYWORDS, { when: (x) => x.length < 3 }),
11264 literal: LITERALS,
11265 type: TYPES,
11266 built_in: POSSIBLE_WITHOUT_PARENS
11267 },
11268 contains: [
11269 {
11270 begin: regex.either(...COMBOS),
11271 relevance: 0,
11272 keywords: {
11273 $pattern: /[\w\.]+/,
11274 keyword: KEYWORDS.concat(COMBOS),
11275 literal: LITERALS,
11276 type: TYPES
11277 },
11278 },
11279 {
11280 className: "type",
11281 begin: regex.either(...MULTI_WORD_TYPES)
11282 },
11283 FUNCTION_CALL,
11284 VARIABLE,
11285 STRING,
11286 QUOTED_IDENTIFIER,
11287 hljs.C_NUMBER_MODE,
11288 hljs.C_BLOCK_COMMENT_MODE,
11289 COMMENT_MODE,
11290 OPERATOR
11291 ]
11292 };
11293 }
11294
11295 const keywordWrapper = keyword => concat(
11296 /\b/,
11297 keyword,
11298 /\w$/.test(keyword) ? /\b/ : /\B/
11299 );
11300
11301 // Keywords that require a leading dot.
11302 const dotKeywords = [
11303 'Protocol', // contextual
11304 'Type' // contextual
11305 ].map(keywordWrapper);
11306
11307 // Keywords that may have a leading dot.
11308 const optionalDotKeywords = [
11309 'init',
11310 'self'
11311 ].map(keywordWrapper);
11312
11313 // should register as keyword, not type
11314 const keywordTypes = [
11315 'Any',
11316 'Self'
11317 ];
11318
11319 // Regular keywords and literals.
11320 const keywords = [
11321 // strings below will be fed into the regular `keywords` engine while regex
11322 // will result in additional modes being created to scan for those keywords to
11323 // avoid conflicts with other rules
11324 'actor',
11325 'any', // contextual
11326 'associatedtype',
11327 'async',
11328 'await',
11329 /as\?/, // operator
11330 /as!/, // operator
11331 'as', // operator
11332 'break',
11333 'case',
11334 'catch',
11335 'class',
11336 'continue',
11337 'convenience', // contextual
11338 'default',
11339 'defer',
11340 'deinit',
11341 'didSet', // contextual
11342 'distributed',
11343 'do',
11344 'dynamic', // contextual
11345 'else',
11346 'enum',
11347 'extension',
11348 'fallthrough',
11349 /fileprivate\(set\)/,
11350 'fileprivate',
11351 'final', // contextual
11352 'for',
11353 'func',
11354 'get', // contextual
11355 'guard',
11356 'if',
11357 'import',
11358 'indirect', // contextual
11359 'infix', // contextual
11360 /init\?/,
11361 /init!/,
11362 'inout',
11363 /internal\(set\)/,
11364 'internal',
11365 'in',
11366 'is', // operator
11367 'isolated', // contextual
11368 'nonisolated', // contextual
11369 'lazy', // contextual
11370 'let',
11371 'mutating', // contextual
11372 'nonmutating', // contextual
11373 /open\(set\)/, // contextual
11374 'open', // contextual
11375 'operator',
11376 'optional', // contextual
11377 'override', // contextual
11378 'postfix', // contextual
11379 'precedencegroup',
11380 'prefix', // contextual
11381 /private\(set\)/,
11382 'private',
11383 'protocol',
11384 /public\(set\)/,
11385 'public',
11386 'repeat',
11387 'required', // contextual
11388 'rethrows',
11389 'return',
11390 'set', // contextual
11391 'some', // contextual
11392 'static',
11393 'struct',
11394 'subscript',
11395 'super',
11396 'switch',
11397 'throws',
11398 'throw',
11399 /try\?/, // operator
11400 /try!/, // operator
11401 'try', // operator
11402 'typealias',
11403 /unowned\(safe\)/, // contextual
11404 /unowned\(unsafe\)/, // contextual
11405 'unowned', // contextual
11406 'var',
11407 'weak', // contextual
11408 'where',
11409 'while',
11410 'willSet' // contextual
11411 ];
11412
11413 // NOTE: Contextual keywords are reserved only in specific contexts.
11414 // Ideally, these should be matched using modes to avoid false positives.
11415
11416 // Literals.
11417 const literals = [
11418 'false',
11419 'nil',
11420 'true'
11421 ];
11422
11423 // Keywords used in precedence groups.
11424 const precedencegroupKeywords = [
11425 'assignment',
11426 'associativity',
11427 'higherThan',
11428 'left',
11429 'lowerThan',
11430 'none',
11431 'right'
11432 ];
11433
11434 // Keywords that start with a number sign (#).
11435 // #(un)available is handled separately.
11436 const numberSignKeywords = [
11437 '#colorLiteral',
11438 '#column',
11439 '#dsohandle',
11440 '#else',
11441 '#elseif',
11442 '#endif',
11443 '#error',
11444 '#file',
11445 '#fileID',
11446 '#fileLiteral',
11447 '#filePath',
11448 '#function',
11449 '#if',
11450 '#imageLiteral',
11451 '#keyPath',
11452 '#line',
11453 '#selector',
11454 '#sourceLocation',
11455 '#warn_unqualified_access',
11456 '#warning'
11457 ];
11458
11459 // Global functions in the Standard Library.
11460 const builtIns$1 = [
11461 'abs',
11462 'all',
11463 'any',
11464 'assert',
11465 'assertionFailure',
11466 'debugPrint',
11467 'dump',
11468 'fatalError',
11469 'getVaList',
11470 'isKnownUniquelyReferenced',
11471 'max',
11472 'min',
11473 'numericCast',
11474 'pointwiseMax',
11475 'pointwiseMin',
11476 'precondition',
11477 'preconditionFailure',
11478 'print',
11479 'readLine',
11480 'repeatElement',
11481 'sequence',
11482 'stride',
11483 'swap',
11484 'swift_unboxFromSwiftValueWithType',
11485 'transcode',
11486 'type',
11487 'unsafeBitCast',
11488 'unsafeDowncast',
11489 'withExtendedLifetime',
11490 'withUnsafeMutablePointer',
11491 'withUnsafePointer',
11492 'withVaList',
11493 'withoutActuallyEscaping',
11494 'zip'
11495 ];
11496
11497 // Valid first characters for operators.
11498 const operatorHead = either(
11499 /[/=\-+!*%<>&|^~?]/,
11500 /[\u00A1-\u00A7]/,
11501 /[\u00A9\u00AB]/,
11502 /[\u00AC\u00AE]/,
11503 /[\u00B0\u00B1]/,
11504 /[\u00B6\u00BB\u00BF\u00D7\u00F7]/,
11505 /[\u2016-\u2017]/,
11506 /[\u2020-\u2027]/,
11507 /[\u2030-\u203E]/,
11508 /[\u2041-\u2053]/,
11509 /[\u2055-\u205E]/,
11510 /[\u2190-\u23FF]/,
11511 /[\u2500-\u2775]/,
11512 /[\u2794-\u2BFF]/,
11513 /[\u2E00-\u2E7F]/,
11514 /[\u3001-\u3003]/,
11515 /[\u3008-\u3020]/,
11516 /[\u3030]/
11517 );
11518
11519 // Valid characters for operators.
11520 const operatorCharacter = either(
11521 operatorHead,
11522 /[\u0300-\u036F]/,
11523 /[\u1DC0-\u1DFF]/,
11524 /[\u20D0-\u20FF]/,
11525 /[\uFE00-\uFE0F]/,
11526 /[\uFE20-\uFE2F]/
11527 // TODO: The following characters are also allowed, but the regex isn't supported yet.
11528 // /[\u{E0100}-\u{E01EF}]/u
11529 );
11530
11531 // Valid operator.
11532 const operator = concat(operatorHead, operatorCharacter, '*');
11533
11534 // Valid first characters for identifiers.
11535 const identifierHead = either(
11536 /[a-zA-Z_]/,
11537 /[\u00A8\u00AA\u00AD\u00AF\u00B2-\u00B5\u00B7-\u00BA]/,
11538 /[\u00BC-\u00BE\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u00FF]/,
11539 /[\u0100-\u02FF\u0370-\u167F\u1681-\u180D\u180F-\u1DBF]/,
11540 /[\u1E00-\u1FFF]/,
11541 /[\u200B-\u200D\u202A-\u202E\u203F-\u2040\u2054\u2060-\u206F]/,
11542 /[\u2070-\u20CF\u2100-\u218F\u2460-\u24FF\u2776-\u2793]/,
11543 /[\u2C00-\u2DFF\u2E80-\u2FFF]/,
11544 /[\u3004-\u3007\u3021-\u302F\u3031-\u303F\u3040-\uD7FF]/,
11545 /[\uF900-\uFD3D\uFD40-\uFDCF\uFDF0-\uFE1F\uFE30-\uFE44]/,
11546 /[\uFE47-\uFEFE\uFF00-\uFFFD]/ // Should be /[\uFE47-\uFFFD]/, but we have to exclude FEFF.
11547 // The following characters are also allowed, but the regexes aren't supported yet.
11548 // /[\u{10000}-\u{1FFFD}\u{20000-\u{2FFFD}\u{30000}-\u{3FFFD}\u{40000}-\u{4FFFD}]/u,
11549 // /[\u{50000}-\u{5FFFD}\u{60000-\u{6FFFD}\u{70000}-\u{7FFFD}\u{80000}-\u{8FFFD}]/u,
11550 // /[\u{90000}-\u{9FFFD}\u{A0000-\u{AFFFD}\u{B0000}-\u{BFFFD}\u{C0000}-\u{CFFFD}]/u,
11551 // /[\u{D0000}-\u{DFFFD}\u{E0000-\u{EFFFD}]/u
11552 );
11553
11554 // Valid characters for identifiers.
11555 const identifierCharacter = either(
11556 identifierHead,
11557 /\d/,
11558 /[\u0300-\u036F\u1DC0-\u1DFF\u20D0-\u20FF\uFE20-\uFE2F]/
11559 );
11560
11561 // Valid identifier.
11562 const identifier = concat(identifierHead, identifierCharacter, '*');
11563
11564 // Valid type identifier.
11565 const typeIdentifier = concat(/[A-Z]/, identifierCharacter, '*');
11566
11567 // Built-in attributes, which are highlighted as keywords.
11568 // @available is handled separately.
11569 const keywordAttributes = [
11570 'autoclosure',
11571 concat(/convention\(/, either('swift', 'block', 'c'), /\)/),
11572 'discardableResult',
11573 'dynamicCallable',
11574 'dynamicMemberLookup',
11575 'escaping',
11576 'frozen',
11577 'GKInspectable',
11578 'IBAction',
11579 'IBDesignable',
11580 'IBInspectable',
11581 'IBOutlet',
11582 'IBSegueAction',
11583 'inlinable',
11584 'main',
11585 'nonobjc',
11586 'NSApplicationMain',
11587 'NSCopying',
11588 'NSManaged',
11589 concat(/objc\(/, identifier, /\)/),
11590 'objc',
11591 'objcMembers',
11592 'propertyWrapper',
11593 'requires_stored_property_inits',
11594 'resultBuilder',
11595 'testable',
11596 'UIApplicationMain',
11597 'unknown',
11598 'usableFromInline'
11599 ];
11600
11601 // Contextual keywords used in @available and #(un)available.
11602 const availabilityKeywords = [
11603 'iOS',
11604 'iOSApplicationExtension',
11605 'macOS',
11606 'macOSApplicationExtension',
11607 'macCatalyst',
11608 'macCatalystApplicationExtension',
11609 'watchOS',
11610 'watchOSApplicationExtension',
11611 'tvOS',
11612 'tvOSApplicationExtension',
11613 'swift'
11614 ];
11615
11616 /*
11617 Language: Swift
11618 Description: Swift is a general-purpose programming language built using a modern approach to safety, performance, and software design patterns.
11619 Author: Steven Van Impe <steven.vanimpe@icloud.com>
11620 Contributors: Chris Eidhof <chris@eidhof.nl>, Nate Cook <natecook@gmail.com>, Alexander Lichter <manniL@gmx.net>, Richard Gibson <gibson042@github>
11621 Website: https://swift.org
11622 Category: common, system
11623 */
11624
11625 /** @type LanguageFn */
11626 function swift(hljs) {
11627 const WHITESPACE = {
11628 match: /\s+/,
11629 relevance: 0
11630 };
11631 // https://docs.swift.org/swift-book/ReferenceManual/LexicalStructure.html#ID411
11632 const BLOCK_COMMENT = hljs.COMMENT(
11633 '/\\*',
11634 '\\*/',
11635 { contains: [ 'self' ] }
11636 );
11637 const COMMENTS = [
11638 hljs.C_LINE_COMMENT_MODE,
11639 BLOCK_COMMENT
11640 ];
11641
11642 // https://docs.swift.org/swift-book/ReferenceManual/LexicalStructure.html#ID413
11643 // https://docs.swift.org/swift-book/ReferenceManual/zzSummaryOfTheGrammar.html
11644 const DOT_KEYWORD = {
11645 match: [
11646 /\./,
11647 either(...dotKeywords, ...optionalDotKeywords)
11648 ],
11649 className: { 2: "keyword" }
11650 };
11651 const KEYWORD_GUARD = {
11652 // Consume .keyword to prevent highlighting properties and methods as keywords.
11653 match: concat(/\./, either(...keywords)),
11654 relevance: 0
11655 };
11656 const PLAIN_KEYWORDS = keywords
11657 .filter(kw => typeof kw === 'string')
11658 .concat([ "_|0" ]); // seems common, so 0 relevance
11659 const REGEX_KEYWORDS = keywords
11660 .filter(kw => typeof kw !== 'string') // find regex
11661 .concat(keywordTypes)
11662 .map(keywordWrapper);
11663 const KEYWORD = { variants: [
11664 {
11665 className: 'keyword',
11666 match: either(...REGEX_KEYWORDS, ...optionalDotKeywords)
11667 }
11668 ] };
11669 // find all the regular keywords
11670 const KEYWORDS = {
11671 $pattern: either(
11672 /\b\w+/, // regular keywords
11673 /#\w+/ // number keywords
11674 ),
11675 keyword: PLAIN_KEYWORDS
11676 .concat(numberSignKeywords),
11677 literal: literals
11678 };
11679 const KEYWORD_MODES = [
11680 DOT_KEYWORD,
11681 KEYWORD_GUARD,
11682 KEYWORD
11683 ];
11684
11685 // https://github.com/apple/swift/tree/main/stdlib/public/core
11686 const BUILT_IN_GUARD = {
11687 // Consume .built_in to prevent highlighting properties and methods.
11688 match: concat(/\./, either(...builtIns$1)),
11689 relevance: 0
11690 };
11691 const BUILT_IN = {
11692 className: 'built_in',
11693 match: concat(/\b/, either(...builtIns$1), /(?=\()/)
11694 };
11695 const BUILT_INS = [
11696 BUILT_IN_GUARD,
11697 BUILT_IN
11698 ];
11699
11700 // https://docs.swift.org/swift-book/ReferenceManual/LexicalStructure.html#ID418
11701 const OPERATOR_GUARD = {
11702 // Prevent -> from being highlighting as an operator.
11703 match: /->/,
11704 relevance: 0
11705 };
11706 const OPERATOR = {
11707 className: 'operator',
11708 relevance: 0,
11709 variants: [
11710 { match: operator },
11711 {
11712 // dot-operator: only operators that start with a dot are allowed to use dots as
11713 // characters (..., ...<, .*, etc). So there rule here is: a dot followed by one or more
11714 // characters that may also include dots.
11715 match: `\\.(\\.|${operatorCharacter})+` }
11716 ]
11717 };
11718 const OPERATORS = [
11719 OPERATOR_GUARD,
11720 OPERATOR
11721 ];
11722
11723 // https://docs.swift.org/swift-book/ReferenceManual/LexicalStructure.html#grammar_numeric-literal
11724 // TODO: Update for leading `-` after lookbehind is supported everywhere
11725 const decimalDigits = '([0-9]_*)+';
11726 const hexDigits = '([0-9a-fA-F]_*)+';
11727 const NUMBER = {
11728 className: 'number',
11729 relevance: 0,
11730 variants: [
11731 // decimal floating-point-literal (subsumes decimal-literal)
11732 { match: `\\b(${decimalDigits})(\\.(${decimalDigits}))?` + `([eE][+-]?(${decimalDigits}))?\\b` },
11733 // hexadecimal floating-point-literal (subsumes hexadecimal-literal)
11734 { match: `\\b0x(${hexDigits})(\\.(${hexDigits}))?` + `([pP][+-]?(${decimalDigits}))?\\b` },
11735 // octal-literal
11736 { match: /\b0o([0-7]_*)+\b/ },
11737 // binary-literal
11738 { match: /\b0b([01]_*)+\b/ }
11739 ]
11740 };
11741
11742 // https://docs.swift.org/swift-book/ReferenceManual/LexicalStructure.html#grammar_string-literal
11743 const ESCAPED_CHARACTER = (rawDelimiter = "") => ({
11744 className: 'subst',
11745 variants: [
11746 { match: concat(/\\/, rawDelimiter, /[0\\tnr"']/) },
11747 { match: concat(/\\/, rawDelimiter, /u\{[0-9a-fA-F]{1,8}\}/) }
11748 ]
11749 });
11750 const ESCAPED_NEWLINE = (rawDelimiter = "") => ({
11751 className: 'subst',
11752 match: concat(/\\/, rawDelimiter, /[\t ]*(?:[\r\n]|\r\n)/)
11753 });
11754 const INTERPOLATION = (rawDelimiter = "") => ({
11755 className: 'subst',
11756 label: "interpol",
11757 begin: concat(/\\/, rawDelimiter, /\(/),
11758 end: /\)/
11759 });
11760 const MULTILINE_STRING = (rawDelimiter = "") => ({
11761 begin: concat(rawDelimiter, /"""/),
11762 end: concat(/"""/, rawDelimiter),
11763 contains: [
11764 ESCAPED_CHARACTER(rawDelimiter),
11765 ESCAPED_NEWLINE(rawDelimiter),
11766 INTERPOLATION(rawDelimiter)
11767 ]
11768 });
11769 const SINGLE_LINE_STRING = (rawDelimiter = "") => ({
11770 begin: concat(rawDelimiter, /"/),
11771 end: concat(/"/, rawDelimiter),
11772 contains: [
11773 ESCAPED_CHARACTER(rawDelimiter),
11774 INTERPOLATION(rawDelimiter)
11775 ]
11776 });
11777 const STRING = {
11778 className: 'string',
11779 variants: [
11780 MULTILINE_STRING(),
11781 MULTILINE_STRING("#"),
11782 MULTILINE_STRING("##"),
11783 MULTILINE_STRING("###"),
11784 SINGLE_LINE_STRING(),
11785 SINGLE_LINE_STRING("#"),
11786 SINGLE_LINE_STRING("##"),
11787 SINGLE_LINE_STRING("###")
11788 ]
11789 };
11790
11791 // https://docs.swift.org/swift-book/ReferenceManual/LexicalStructure.html#ID412
11792 const QUOTED_IDENTIFIER = { match: concat(/`/, identifier, /`/) };
11793 const IMPLICIT_PARAMETER = {
11794 className: 'variable',
11795 match: /\$\d+/
11796 };
11797 const PROPERTY_WRAPPER_PROJECTION = {
11798 className: 'variable',
11799 match: `\\$${identifierCharacter}+`
11800 };
11801 const IDENTIFIERS = [
11802 QUOTED_IDENTIFIER,
11803 IMPLICIT_PARAMETER,
11804 PROPERTY_WRAPPER_PROJECTION
11805 ];
11806
11807 // https://docs.swift.org/swift-book/ReferenceManual/Attributes.html
11808 const AVAILABLE_ATTRIBUTE = {
11809 match: /(@|#(un)?)available/,
11810 className: "keyword",
11811 starts: { contains: [
11812 {
11813 begin: /\(/,
11814 end: /\)/,
11815 keywords: availabilityKeywords,
11816 contains: [
11817 ...OPERATORS,
11818 NUMBER,
11819 STRING
11820 ]
11821 }
11822 ] }
11823 };
11824 const KEYWORD_ATTRIBUTE = {
11825 className: 'keyword',
11826 match: concat(/@/, either(...keywordAttributes))
11827 };
11828 const USER_DEFINED_ATTRIBUTE = {
11829 className: 'meta',
11830 match: concat(/@/, identifier)
11831 };
11832 const ATTRIBUTES = [
11833 AVAILABLE_ATTRIBUTE,
11834 KEYWORD_ATTRIBUTE,
11835 USER_DEFINED_ATTRIBUTE
11836 ];
11837
11838 // https://docs.swift.org/swift-book/ReferenceManual/Types.html
11839 const TYPE = {
11840 match: lookahead(/\b[A-Z]/),
11841 relevance: 0,
11842 contains: [
11843 { // Common Apple frameworks, for relevance boost
11844 className: 'type',
11845 match: concat(/(AV|CA|CF|CG|CI|CL|CM|CN|CT|MK|MP|MTK|MTL|NS|SCN|SK|UI|WK|XC)/, identifierCharacter, '+')
11846 },
11847 { // Type identifier
11848 className: 'type',
11849 match: typeIdentifier,
11850 relevance: 0
11851 },
11852 { // Optional type
11853 match: /[?!]+/,
11854 relevance: 0
11855 },
11856 { // Variadic parameter
11857 match: /\.\.\./,
11858 relevance: 0
11859 },
11860 { // Protocol composition
11861 match: concat(/\s+&\s+/, lookahead(typeIdentifier)),
11862 relevance: 0
11863 }
11864 ]
11865 };
11866 const GENERIC_ARGUMENTS = {
11867 begin: /</,
11868 end: />/,
11869 keywords: KEYWORDS,
11870 contains: [
11871 ...COMMENTS,
11872 ...KEYWORD_MODES,
11873 ...ATTRIBUTES,
11874 OPERATOR_GUARD,
11875 TYPE
11876 ]
11877 };
11878 TYPE.contains.push(GENERIC_ARGUMENTS);
11879
11880 // https://docs.swift.org/swift-book/ReferenceManual/Expressions.html#ID552
11881 // Prevents element names from being highlighted as keywords.
11882 const TUPLE_ELEMENT_NAME = {
11883 match: concat(identifier, /\s*:/),
11884 keywords: "_|0",
11885 relevance: 0
11886 };
11887 // Matches tuples as well as the parameter list of a function type.
11888 const TUPLE = {
11889 begin: /\(/,
11890 end: /\)/,
11891 relevance: 0,
11892 keywords: KEYWORDS,
11893 contains: [
11894 'self',
11895 TUPLE_ELEMENT_NAME,
11896 ...COMMENTS,
11897 ...KEYWORD_MODES,
11898 ...BUILT_INS,
11899 ...OPERATORS,
11900 NUMBER,
11901 STRING,
11902 ...IDENTIFIERS,
11903 ...ATTRIBUTES,
11904 TYPE
11905 ]
11906 };
11907
11908 const GENERIC_PARAMETERS = {
11909 begin: /</,
11910 end: />/,
11911 contains: [
11912 ...COMMENTS,
11913 TYPE
11914 ]
11915 };
11916 const FUNCTION_PARAMETER_NAME = {
11917 begin: either(
11918 lookahead(concat(identifier, /\s*:/)),
11919 lookahead(concat(identifier, /\s+/, identifier, /\s*:/))
11920 ),
11921 end: /:/,
11922 relevance: 0,
11923 contains: [
11924 {
11925 className: 'keyword',
11926 match: /\b_\b/
11927 },
11928 {
11929 className: 'params',
11930 match: identifier
11931 }
11932 ]
11933 };
11934 const FUNCTION_PARAMETERS = {
11935 begin: /\(/,
11936 end: /\)/,
11937 keywords: KEYWORDS,
11938 contains: [
11939 FUNCTION_PARAMETER_NAME,
11940 ...COMMENTS,
11941 ...KEYWORD_MODES,
11942 ...OPERATORS,
11943 NUMBER,
11944 STRING,
11945 ...ATTRIBUTES,
11946 TYPE,
11947 TUPLE
11948 ],
11949 endsParent: true,
11950 illegal: /["']/
11951 };
11952 // https://docs.swift.org/swift-book/ReferenceManual/Declarations.html#ID362
11953 const FUNCTION = {
11954 match: [
11955 /func/,
11956 /\s+/,
11957 either(QUOTED_IDENTIFIER.match, identifier, operator)
11958 ],
11959 className: {
11960 1: "keyword",
11961 3: "title.function"
11962 },
11963 contains: [
11964 GENERIC_PARAMETERS,
11965 FUNCTION_PARAMETERS,
11966 WHITESPACE
11967 ],
11968 illegal: [
11969 /\[/,
11970 /%/
11971 ]
11972 };
11973
11974 // https://docs.swift.org/swift-book/ReferenceManual/Declarations.html#ID375
11975 // https://docs.swift.org/swift-book/ReferenceManual/Declarations.html#ID379
11976 const INIT_SUBSCRIPT = {
11977 match: [
11978 /\b(?:subscript|init[?!]?)/,
11979 /\s*(?=[<(])/,
11980 ],
11981 className: { 1: "keyword" },
11982 contains: [
11983 GENERIC_PARAMETERS,
11984 FUNCTION_PARAMETERS,
11985 WHITESPACE
11986 ],
11987 illegal: /\[|%/
11988 };
11989 // https://docs.swift.org/swift-book/ReferenceManual/Declarations.html#ID380
11990 const OPERATOR_DECLARATION = {
11991 match: [
11992 /operator/,
11993 /\s+/,
11994 operator
11995 ],
11996 className: {
11997 1: "keyword",
11998 3: "title"
11999 }
12000 };
12001
12002 // https://docs.swift.org/swift-book/ReferenceManual/Declarations.html#ID550
12003 const PRECEDENCEGROUP = {
12004 begin: [
12005 /precedencegroup/,
12006 /\s+/,
12007 typeIdentifier
12008 ],
12009 className: {
12010 1: "keyword",
12011 3: "title"
12012 },
12013 contains: [ TYPE ],
12014 keywords: [
12015 ...precedencegroupKeywords,
12016 ...literals
12017 ],
12018 end: /}/
12019 };
12020
12021 // Add supported submodes to string interpolation.
12022 for (const variant of STRING.variants) {
12023 const interpolation = variant.contains.find(mode => mode.label === "interpol");
12024 // TODO: Interpolation can contain any expression, so there's room for improvement here.
12025 interpolation.keywords = KEYWORDS;
12026 const submodes = [
12027 ...KEYWORD_MODES,
12028 ...BUILT_INS,
12029 ...OPERATORS,
12030 NUMBER,
12031 STRING,
12032 ...IDENTIFIERS
12033 ];
12034 interpolation.contains = [
12035 ...submodes,
12036 {
12037 begin: /\(/,
12038 end: /\)/,
12039 contains: [
12040 'self',
12041 ...submodes
12042 ]
12043 }
12044 ];
12045 }
12046
12047 return {
12048 name: 'Swift',
12049 keywords: KEYWORDS,
12050 contains: [
12051 ...COMMENTS,
12052 FUNCTION,
12053 INIT_SUBSCRIPT,
12054 {
12055 beginKeywords: 'struct protocol class extension enum actor',
12056 end: '\\{',
12057 excludeEnd: true,
12058 keywords: KEYWORDS,
12059 contains: [
12060 hljs.inherit(hljs.TITLE_MODE, {
12061 className: "title.class",
12062 begin: /[A-Za-z$_][\u00C0-\u02B80-9A-Za-z$_]*/
12063 }),
12064 ...KEYWORD_MODES
12065 ]
12066 },
12067 OPERATOR_DECLARATION,
12068 PRECEDENCEGROUP,
12069 {
12070 beginKeywords: 'import',
12071 end: /$/,
12072 contains: [ ...COMMENTS ],
12073 relevance: 0
12074 },
12075 ...KEYWORD_MODES,
12076 ...BUILT_INS,
12077 ...OPERATORS,
12078 NUMBER,
12079 STRING,
12080 ...IDENTIFIERS,
12081 ...ATTRIBUTES,
12082 TYPE,
12083 TUPLE
12084 ]
12085 };
12086 }
12087
12088 /*
12089 Language: TypeScript
12090 Author: Panu Horsmalahti <panu.horsmalahti@iki.fi>
12091 Contributors: Ike Ku <dempfi@yahoo.com>
12092 Description: TypeScript is a strict superset of JavaScript
12093 Website: https://www.typescriptlang.org
12094 Category: common, scripting
12095 */
12096
12097 /** @type LanguageFn */
12098 function typescript(hljs) {
12099 const tsLanguage = javascript(hljs);
12100
12101 const IDENT_RE$1 = IDENT_RE;
12102 const TYPES = [
12103 "any",
12104 "void",
12105 "number",
12106 "boolean",
12107 "string",
12108 "object",
12109 "never",
12110 "symbol",
12111 "bigint",
12112 "unknown"
12113 ];
12114 const NAMESPACE = {
12115 beginKeywords: 'namespace',
12116 end: /\{/,
12117 excludeEnd: true,
12118 contains: [ tsLanguage.exports.CLASS_REFERENCE ]
12119 };
12120 const INTERFACE = {
12121 beginKeywords: 'interface',
12122 end: /\{/,
12123 excludeEnd: true,
12124 keywords: {
12125 keyword: 'interface extends',
12126 built_in: TYPES
12127 },
12128 contains: [ tsLanguage.exports.CLASS_REFERENCE ]
12129 };
12130 const USE_STRICT = {
12131 className: 'meta',
12132 relevance: 10,
12133 begin: /^\s*['"]use strict['"]/
12134 };
12135 const TS_SPECIFIC_KEYWORDS = [
12136 "type",
12137 "namespace",
12138 "interface",
12139 "public",
12140 "private",
12141 "protected",
12142 "implements",
12143 "declare",
12144 "abstract",
12145 "readonly",
12146 "enum",
12147 "override"
12148 ];
12149 const KEYWORDS$1 = {
12150 $pattern: IDENT_RE,
12151 keyword: KEYWORDS.concat(TS_SPECIFIC_KEYWORDS),
12152 literal: LITERALS,
12153 built_in: BUILT_INS.concat(TYPES),
12154 "variable.language": BUILT_IN_VARIABLES
12155 };
12156 const DECORATOR = {
12157 className: 'meta',
12158 begin: '@' + IDENT_RE$1,
12159 };
12160
12161 const swapMode = (mode, label, replacement) => {
12162 const indx = mode.contains.findIndex(m => m.label === label);
12163 if (indx === -1) { throw new Error("can not find mode to replace"); }
12164
12165 mode.contains.splice(indx, 1, replacement);
12166 };
12167
12168
12169 // this should update anywhere keywords is used since
12170 // it will be the same actual JS object
12171 Object.assign(tsLanguage.keywords, KEYWORDS$1);
12172
12173 tsLanguage.exports.PARAMS_CONTAINS.push(DECORATOR);
12174 tsLanguage.contains = tsLanguage.contains.concat([
12175 DECORATOR,
12176 NAMESPACE,
12177 INTERFACE,
12178 ]);
12179
12180 // TS gets a simpler shebang rule than JS
12181 swapMode(tsLanguage, "shebang", hljs.SHEBANG());
12182 // JS use strict rule purposely excludes `asm` which makes no sense
12183 swapMode(tsLanguage, "use_strict", USE_STRICT);
12184
12185 const functionDeclaration = tsLanguage.contains.find(m => m.label === "func.def");
12186 functionDeclaration.relevance = 0; // () => {} is more typical in TypeScript
12187
12188 Object.assign(tsLanguage, {
12189 name: 'TypeScript',
12190 aliases: [
12191 'ts',
12192 'tsx'
12193 ]
12194 });
12195
12196 return tsLanguage;
12197 }
12198
12199 /*
12200 Language: Visual Basic .NET
12201 Description: Visual Basic .NET (VB.NET) is a multi-paradigm, object-oriented programming language, implemented on the .NET Framework.
12202 Authors: Poren Chiang <ren.chiang@gmail.com>, Jan Pilzer
12203 Website: https://docs.microsoft.com/dotnet/visual-basic/getting-started
12204 Category: common
12205 */
12206
12207 /** @type LanguageFn */
12208 function vbnet(hljs) {
12209 const regex = hljs.regex;
12210 /**
12211 * Character Literal
12212 * Either a single character ("a"C) or an escaped double quote (""""C).
12213 */
12214 const CHARACTER = {
12215 className: 'string',
12216 begin: /"(""|[^/n])"C\b/
12217 };
12218
12219 const STRING = {
12220 className: 'string',
12221 begin: /"/,
12222 end: /"/,
12223 illegal: /\n/,
12224 contains: [
12225 {
12226 // double quote escape
12227 begin: /""/ }
12228 ]
12229 };
12230
12231 /** Date Literals consist of a date, a time, or both separated by whitespace, surrounded by # */
12232 const MM_DD_YYYY = /\d{1,2}\/\d{1,2}\/\d{4}/;
12233 const YYYY_MM_DD = /\d{4}-\d{1,2}-\d{1,2}/;
12234 const TIME_12H = /(\d|1[012])(:\d+){0,2} *(AM|PM)/;
12235 const TIME_24H = /\d{1,2}(:\d{1,2}){1,2}/;
12236 const DATE = {
12237 className: 'literal',
12238 variants: [
12239 {
12240 // #YYYY-MM-DD# (ISO-Date) or #M/D/YYYY# (US-Date)
12241 begin: regex.concat(/# */, regex.either(YYYY_MM_DD, MM_DD_YYYY), / *#/) },
12242 {
12243 // #H:mm[:ss]# (24h Time)
12244 begin: regex.concat(/# */, TIME_24H, / *#/) },
12245 {
12246 // #h[:mm[:ss]] A# (12h Time)
12247 begin: regex.concat(/# */, TIME_12H, / *#/) },
12248 {
12249 // date plus time
12250 begin: regex.concat(
12251 /# */,
12252 regex.either(YYYY_MM_DD, MM_DD_YYYY),
12253 / +/,
12254 regex.either(TIME_12H, TIME_24H),
12255 / *#/
12256 ) }
12257 ]
12258 };
12259
12260 const NUMBER = {
12261 className: 'number',
12262 relevance: 0,
12263 variants: [
12264 {
12265 // Float
12266 begin: /\b\d[\d_]*((\.[\d_]+(E[+-]?[\d_]+)?)|(E[+-]?[\d_]+))[RFD@!#]?/ },
12267 {
12268 // Integer (base 10)
12269 begin: /\b\d[\d_]*((U?[SIL])|[%&])?/ },
12270 {
12271 // Integer (base 16)
12272 begin: /&H[\dA-F_]+((U?[SIL])|[%&])?/ },
12273 {
12274 // Integer (base 8)
12275 begin: /&O[0-7_]+((U?[SIL])|[%&])?/ },
12276 {
12277 // Integer (base 2)
12278 begin: /&B[01_]+((U?[SIL])|[%&])?/ }
12279 ]
12280 };
12281
12282 const LABEL = {
12283 className: 'label',
12284 begin: /^\w+:/
12285 };
12286
12287 const DOC_COMMENT = hljs.COMMENT(/'''/, /$/, { contains: [
12288 {
12289 className: 'doctag',
12290 begin: /<\/?/,
12291 end: />/
12292 }
12293 ] });
12294
12295 const COMMENT = hljs.COMMENT(null, /$/, { variants: [
12296 { begin: /'/ },
12297 {
12298 // TODO: Use multi-class for leading spaces
12299 begin: /([\t ]|^)REM(?=\s)/ }
12300 ] });
12301
12302 const DIRECTIVES = {
12303 className: 'meta',
12304 // TODO: Use multi-class for indentation once available
12305 begin: /[\t ]*#(const|disable|else|elseif|enable|end|externalsource|if|region)\b/,
12306 end: /$/,
12307 keywords: { keyword:
12308 'const disable else elseif enable end externalsource if region then' },
12309 contains: [ COMMENT ]
12310 };
12311
12312 return {
12313 name: 'Visual Basic .NET',
12314 aliases: [ 'vb' ],
12315 case_insensitive: true,
12316 classNameAliases: { label: 'symbol' },
12317 keywords: {
12318 keyword:
12319 'addhandler alias aggregate ansi as async assembly auto binary by byref byval ' /* a-b */
12320 + 'call case catch class compare const continue custom declare default delegate dim distinct do ' /* c-d */
12321 + 'each equals else elseif end enum erase error event exit explicit finally for friend from function ' /* e-f */
12322 + 'get global goto group handles if implements imports in inherits interface into iterator ' /* g-i */
12323 + 'join key let lib loop me mid module mustinherit mustoverride mybase myclass ' /* j-m */
12324 + 'namespace narrowing new next notinheritable notoverridable ' /* n */
12325 + 'of off on operator option optional order overloads overridable overrides ' /* o */
12326 + 'paramarray partial preserve private property protected public ' /* p */
12327 + 'raiseevent readonly redim removehandler resume return ' /* r */
12328 + 'select set shadows shared skip static step stop structure strict sub synclock ' /* s */
12329 + 'take text then throw to try unicode until using when where while widening with withevents writeonly yield' /* t-y */,
12330 built_in:
12331 // Operators https://docs.microsoft.com/dotnet/visual-basic/language-reference/operators
12332 'addressof and andalso await directcast gettype getxmlnamespace is isfalse isnot istrue like mod nameof new not or orelse trycast typeof xor '
12333 // Type Conversion Functions https://docs.microsoft.com/dotnet/visual-basic/language-reference/functions/type-conversion-functions
12334 + 'cbool cbyte cchar cdate cdbl cdec cint clng cobj csbyte cshort csng cstr cuint culng cushort',
12335 type:
12336 // Data types https://docs.microsoft.com/dotnet/visual-basic/language-reference/data-types
12337 'boolean byte char date decimal double integer long object sbyte short single string uinteger ulong ushort',
12338 literal: 'true false nothing'
12339 },
12340 illegal:
12341 '//|\\{|\\}|endif|gosub|variant|wend|^\\$ ' /* reserved deprecated keywords */,
12342 contains: [
12343 CHARACTER,
12344 STRING,
12345 DATE,
12346 NUMBER,
12347 LABEL,
12348 DOC_COMMENT,
12349 COMMENT,
12350 DIRECTIVES
12351 ]
12352 };
12353 }
12354
12355 /*
12356 Language: WebAssembly
12357 Website: https://webassembly.org
12358 Description: Wasm is designed as a portable compilation target for programming languages, enabling deployment on the web for client and server applications.
12359 Category: web, common
12360 Audit: 2020
12361 */
12362
12363 /** @type LanguageFn */
12364 function wasm(hljs) {
12365 hljs.regex;
12366 const BLOCK_COMMENT = hljs.COMMENT(/\(;/, /;\)/);
12367 BLOCK_COMMENT.contains.push("self");
12368 const LINE_COMMENT = hljs.COMMENT(/;;/, /$/);
12369
12370 const KWS = [
12371 "anyfunc",
12372 "block",
12373 "br",
12374 "br_if",
12375 "br_table",
12376 "call",
12377 "call_indirect",
12378 "data",
12379 "drop",
12380 "elem",
12381 "else",
12382 "end",
12383 "export",
12384 "func",
12385 "global.get",
12386 "global.set",
12387 "local.get",
12388 "local.set",
12389 "local.tee",
12390 "get_global",
12391 "get_local",
12392 "global",
12393 "if",
12394 "import",
12395 "local",
12396 "loop",
12397 "memory",
12398 "memory.grow",
12399 "memory.size",
12400 "module",
12401 "mut",
12402 "nop",
12403 "offset",
12404 "param",
12405 "result",
12406 "return",
12407 "select",
12408 "set_global",
12409 "set_local",
12410 "start",
12411 "table",
12412 "tee_local",
12413 "then",
12414 "type",
12415 "unreachable"
12416 ];
12417
12418 const FUNCTION_REFERENCE = {
12419 begin: [
12420 /(?:func|call|call_indirect)/,
12421 /\s+/,
12422 /\$[^\s)]+/
12423 ],
12424 className: {
12425 1: "keyword",
12426 3: "title.function"
12427 }
12428 };
12429
12430 const ARGUMENT = {
12431 className: "variable",
12432 begin: /\$[\w_]+/
12433 };
12434
12435 const PARENS = {
12436 match: /(\((?!;)|\))+/,
12437 className: "punctuation",
12438 relevance: 0
12439 };
12440
12441 const NUMBER = {
12442 className: "number",
12443 relevance: 0,
12444 // borrowed from Prism, TODO: split out into variants
12445 match: /[+-]?\b(?:\d(?:_?\d)*(?:\.\d(?:_?\d)*)?(?:[eE][+-]?\d(?:_?\d)*)?|0x[\da-fA-F](?:_?[\da-fA-F])*(?:\.[\da-fA-F](?:_?[\da-fA-D])*)?(?:[pP][+-]?\d(?:_?\d)*)?)\b|\binf\b|\bnan(?::0x[\da-fA-F](?:_?[\da-fA-D])*)?\b/
12446 };
12447
12448 const TYPE = {
12449 // look-ahead prevents us from gobbling up opcodes
12450 match: /(i32|i64|f32|f64)(?!\.)/,
12451 className: "type"
12452 };
12453
12454 const MATH_OPERATIONS = {
12455 className: "keyword",
12456 // borrowed from Prism, TODO: split out into variants
12457 match: /\b(f32|f64|i32|i64)(?:\.(?:abs|add|and|ceil|clz|const|convert_[su]\/i(?:32|64)|copysign|ctz|demote\/f64|div(?:_[su])?|eqz?|extend_[su]\/i32|floor|ge(?:_[su])?|gt(?:_[su])?|le(?:_[su])?|load(?:(?:8|16|32)_[su])?|lt(?:_[su])?|max|min|mul|nearest|neg?|or|popcnt|promote\/f32|reinterpret\/[fi](?:32|64)|rem_[su]|rot[lr]|shl|shr_[su]|store(?:8|16|32)?|sqrt|sub|trunc(?:_[su]\/f(?:32|64))?|wrap\/i64|xor))\b/
12458 };
12459
12460 const OFFSET_ALIGN = {
12461 match: [
12462 /(?:offset|align)/,
12463 /\s*/,
12464 /=/
12465 ],
12466 className: {
12467 1: "keyword",
12468 3: "operator"
12469 }
12470 };
12471
12472 return {
12473 name: 'WebAssembly',
12474 keywords: {
12475 $pattern: /[\w.]+/,
12476 keyword: KWS
12477 },
12478 contains: [
12479 LINE_COMMENT,
12480 BLOCK_COMMENT,
12481 OFFSET_ALIGN,
12482 ARGUMENT,
12483 PARENS,
12484 FUNCTION_REFERENCE,
12485 hljs.QUOTE_STRING_MODE,
12486 TYPE,
12487 MATH_OPERATIONS,
12488 NUMBER
12489 ]
12490 };
12491 }
12492
12493 /*
12494 Language: YAML
12495 Description: Yet Another Markdown Language
12496 Author: Stefan Wienert <stwienert@gmail.com>
12497 Contributors: Carl Baxter <carl@cbax.tech>
12498 Requires: ruby.js
12499 Website: https://yaml.org
12500 Category: common, config
12501 */
12502 function yaml(hljs) {
12503 const LITERALS = 'true false yes no null';
12504
12505 // YAML spec allows non-reserved URI characters in tags.
12506 const URI_CHARACTERS = '[\\w#;/?:@&=+$,.~*\'()[\\]]+';
12507
12508 // Define keys as starting with a word character
12509 // ...containing word chars, spaces, colons, forward-slashes, hyphens and periods
12510 // ...and ending with a colon followed immediately by a space, tab or newline.
12511 // The YAML spec allows for much more than this, but this covers most use-cases.
12512 const KEY = {
12513 className: 'attr',
12514 variants: [
12515 { begin: '\\w[\\w :\\/.-]*:(?=[ \t]|$)' },
12516 { // double quoted keys
12517 begin: '"\\w[\\w :\\/.-]*":(?=[ \t]|$)' },
12518 { // single quoted keys
12519 begin: '\'\\w[\\w :\\/.-]*\':(?=[ \t]|$)' }
12520 ]
12521 };
12522
12523 const TEMPLATE_VARIABLES = {
12524 className: 'template-variable',
12525 variants: [
12526 { // jinja templates Ansible
12527 begin: /\{\{/,
12528 end: /\}\}/
12529 },
12530 { // Ruby i18n
12531 begin: /%\{/,
12532 end: /\}/
12533 }
12534 ]
12535 };
12536 const STRING = {
12537 className: 'string',
12538 relevance: 0,
12539 variants: [
12540 {
12541 begin: /'/,
12542 end: /'/
12543 },
12544 {
12545 begin: /"/,
12546 end: /"/
12547 },
12548 { begin: /\S+/ }
12549 ],
12550 contains: [
12551 hljs.BACKSLASH_ESCAPE,
12552 TEMPLATE_VARIABLES
12553 ]
12554 };
12555
12556 // Strings inside of value containers (objects) can't contain braces,
12557 // brackets, or commas
12558 const CONTAINER_STRING = hljs.inherit(STRING, { variants: [
12559 {
12560 begin: /'/,
12561 end: /'/
12562 },
12563 {
12564 begin: /"/,
12565 end: /"/
12566 },
12567 { begin: /[^\s,{}[\]]+/ }
12568 ] });
12569
12570 const DATE_RE = '[0-9]{4}(-[0-9][0-9]){0,2}';
12571 const TIME_RE = '([Tt \\t][0-9][0-9]?(:[0-9][0-9]){2})?';
12572 const FRACTION_RE = '(\\.[0-9]*)?';
12573 const ZONE_RE = '([ \\t])*(Z|[-+][0-9][0-9]?(:[0-9][0-9])?)?';
12574 const TIMESTAMP = {
12575 className: 'number',
12576 begin: '\\b' + DATE_RE + TIME_RE + FRACTION_RE + ZONE_RE + '\\b'
12577 };
12578
12579 const VALUE_CONTAINER = {
12580 end: ',',
12581 endsWithParent: true,
12582 excludeEnd: true,
12583 keywords: LITERALS,
12584 relevance: 0
12585 };
12586 const OBJECT = {
12587 begin: /\{/,
12588 end: /\}/,
12589 contains: [ VALUE_CONTAINER ],
12590 illegal: '\\n',
12591 relevance: 0
12592 };
12593 const ARRAY = {
12594 begin: '\\[',
12595 end: '\\]',
12596 contains: [ VALUE_CONTAINER ],
12597 illegal: '\\n',
12598 relevance: 0
12599 };
12600
12601 const MODES = [
12602 KEY,
12603 {
12604 className: 'meta',
12605 begin: '^---\\s*$',
12606 relevance: 10
12607 },
12608 { // multi line string
12609 // Blocks start with a | or > followed by a newline
12610 //
12611 // Indentation of subsequent lines must be the same to
12612 // be considered part of the block
12613 className: 'string',
12614 begin: '[\\|>]([1-9]?[+-])?[ ]*\\n( +)[^ ][^\\n]*\\n(\\2[^\\n]+\\n?)*'
12615 },
12616 { // Ruby/Rails erb
12617 begin: '<%[%=-]?',
12618 end: '[%-]?%>',
12619 subLanguage: 'ruby',
12620 excludeBegin: true,
12621 excludeEnd: true,
12622 relevance: 0
12623 },
12624 { // named tags
12625 className: 'type',
12626 begin: '!\\w+!' + URI_CHARACTERS
12627 },
12628 // https://yaml.org/spec/1.2/spec.html#id2784064
12629 { // verbatim tags
12630 className: 'type',
12631 begin: '!<' + URI_CHARACTERS + ">"
12632 },
12633 { // primary tags
12634 className: 'type',
12635 begin: '!' + URI_CHARACTERS
12636 },
12637 { // secondary tags
12638 className: 'type',
12639 begin: '!!' + URI_CHARACTERS
12640 },
12641 { // fragment id &ref
12642 className: 'meta',
12643 begin: '&' + hljs.UNDERSCORE_IDENT_RE + '$'
12644 },
12645 { // fragment reference *ref
12646 className: 'meta',
12647 begin: '\\*' + hljs.UNDERSCORE_IDENT_RE + '$'
12648 },
12649 { // array listing
12650 className: 'bullet',
12651 // TODO: remove |$ hack when we have proper look-ahead support
12652 begin: '-(?=[ ]|$)',
12653 relevance: 0
12654 },
12655 hljs.HASH_COMMENT_MODE,
12656 {
12657 beginKeywords: LITERALS,
12658 keywords: { literal: LITERALS }
12659 },
12660 TIMESTAMP,
12661 // numbers are any valid C-style number that
12662 // sit isolated from other words
12663 {
12664 className: 'number',
12665 begin: hljs.C_NUMBER_RE + '\\b',
12666 relevance: 0
12667 },
12668 OBJECT,
12669 ARRAY,
12670 STRING
12671 ];
12672
12673 const VALUE_MODES = [ ...MODES ];
12674 VALUE_MODES.pop();
12675 VALUE_MODES.push(CONTAINER_STRING);
12676 VALUE_CONTAINER.contains = VALUE_MODES;
12677
12678 return {
12679 name: 'YAML',
12680 case_insensitive: true,
12681 aliases: [ 'yml' ],
12682 contains: MODES
12683 };
12684 }
12685
12686 var builtIns = /*#__PURE__*/Object.freeze({
12687 __proto__: null,
12688 grmr_bash: bash,
12689 grmr_c: c,
12690 grmr_cpp: cpp,
12691 grmr_csharp: csharp,
12692 grmr_css: css,
12693 grmr_diff: diff,
12694 grmr_go: go,
12695 grmr_graphql: graphql,
12696 grmr_ini: ini,
12697 grmr_java: java,
12698 grmr_javascript: javascript,
12699 grmr_json: json,
12700 grmr_kotlin: kotlin,
12701 grmr_less: less,
12702 grmr_lua: lua,
12703 grmr_makefile: makefile,
12704 grmr_xml: xml,
12705 grmr_markdown: markdown,
12706 grmr_objectivec: objectivec,
12707 grmr_perl: perl,
12708 grmr_php: php,
12709 grmr_php_template: phpTemplate,
12710 grmr_plaintext: plaintext,
12711 grmr_python: python,
12712 grmr_python_repl: pythonRepl,
12713 grmr_r: r,
12714 grmr_ruby: ruby,
12715 grmr_rust: rust,
12716 grmr_scss: scss,
12717 grmr_shell: shell,
12718 grmr_sql: sql,
12719 grmr_swift: swift,
12720 grmr_typescript: typescript,
12721 grmr_vbnet: vbnet,
12722 grmr_wasm: wasm,
12723 grmr_yaml: yaml
12724 });
12725
12726 const hljs = HighlightJS;
12727
12728 for (const key of Object.keys(builtIns)) {
12729 // our builtInLanguages Rollup plugin has to use `_` to allow identifiers to be
12730 // compatible with `export` naming conventions, so we need to convert the
12731 // identifiers back into the more typical dash style that we use for language
12732 // naming via the API
12733 const languageName = key.replace("grmr_", "").replace("_", "-");
12734 hljs.registerLanguage(languageName, builtIns[key]);
12735 }
12736
12737 return hljs;
12738
12739})();
12740if (typeof exports === 'object' && typeof module !== 'undefined') { module.exports = hljs; }