UNPKG

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