UNPKG

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