UNPKG

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