UNPKG

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