UNPKG

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