Mercurial
comparison third_party/highlight/highlight.js @ 173:827c6ac504cd hg-web
Merged in default here.
| author | MrJuneJune <me@mrjunejune.com> |
|---|---|
| date | Mon, 19 Jan 2026 18:59:10 -0800 |
| parents | 2db6253f355d |
| children | a06710325c30 |
comparison
equal
deleted
inserted
replaced
| 151:c033667da5f9 | 173:827c6ac504cd |
|---|---|
| 1 /*! | |
| 2 Highlight.js v11.11.1 (git: 08cb242e7d) | |
| 3 (c) 2006-2025 Josh Goebel <[email protected]> and other contributors | |
| 4 License: BSD-3-Clause | |
| 5 */ | |
| 6 var hljs = (function () { | |
| 7 'use strict'; | |
| 8 | |
| 9 /* eslint-disable no-multi-assign */ | |
| 10 | |
| 11 function deepFreeze(obj) { | |
| 12 if (obj instanceof Map) { | |
| 13 obj.clear = | |
| 14 obj.delete = | |
| 15 obj.set = | |
| 16 function () { | |
| 17 throw new Error('map is read-only'); | |
| 18 }; | |
| 19 } else if (obj instanceof Set) { | |
| 20 obj.add = | |
| 21 obj.clear = | |
| 22 obj.delete = | |
| 23 function () { | |
| 24 throw new Error('set is read-only'); | |
| 25 }; | |
| 26 } | |
| 27 | |
| 28 // Freeze self | |
| 29 Object.freeze(obj); | |
| 30 | |
| 31 Object.getOwnPropertyNames(obj).forEach((name) => { | |
| 32 const prop = obj[name]; | |
| 33 const type = typeof prop; | |
| 34 | |
| 35 // Freeze prop if it is an object or function and also not already frozen | |
| 36 if ((type === 'object' || type === 'function') && !Object.isFrozen(prop)) { | |
| 37 deepFreeze(prop); | |
| 38 } | |
| 39 }); | |
| 40 | |
| 41 return obj; | |
| 42 } | |
| 43 | |
| 44 /** @typedef {import('highlight.js').CallbackResponse} CallbackResponse */ | |
| 45 /** @typedef {import('highlight.js').CompiledMode} CompiledMode */ | |
| 46 /** @implements CallbackResponse */ | |
| 47 | |
| 48 class Response { | |
| 49 /** | |
| 50 * @param {CompiledMode} mode | |
| 51 */ | |
| 52 constructor(mode) { | |
| 53 // eslint-disable-next-line no-undefined | |
| 54 if (mode.data === undefined) mode.data = {}; | |
| 55 | |
| 56 this.data = mode.data; | |
| 57 this.isMatchIgnored = false; | |
| 58 } | |
| 59 | |
| 60 ignoreMatch() { | |
| 61 this.isMatchIgnored = true; | |
| 62 } | |
| 63 } | |
| 64 | |
| 65 /** | |
| 66 * @param {string} value | |
| 67 * @returns {string} | |
| 68 */ | |
| 69 function escapeHTML(value) { | |
| 70 return value | |
| 71 .replace(/&/g, '&') | |
| 72 .replace(/</g, '<') | |
| 73 .replace(/>/g, '>') | |
| 74 .replace(/"/g, '"') | |
| 75 .replace(/'/g, '''); | |
| 76 } | |
| 77 | |
| 78 /** | |
| 79 * performs a shallow merge of multiple objects into one | |
| 80 * | |
| 81 * @template T | |
| 82 * @param {T} original | |
| 83 * @param {Record<string,any>[]} objects | |
| 84 * @returns {T} a single new object | |
| 85 */ | |
| 86 function inherit$1(original, ...objects) { | |
| 87 /** @type Record<string,any> */ | |
| 88 const result = Object.create(null); | |
| 89 | |
| 90 for (const key in original) { | |
| 91 result[key] = original[key]; | |
| 92 } | |
| 93 objects.forEach(function(obj) { | |
| 94 for (const key in obj) { | |
| 95 result[key] = obj[key]; | |
| 96 } | |
| 97 }); | |
| 98 return /** @type {T} */ (result); | |
| 99 } | |
| 100 | |
| 101 /** | |
| 102 * @typedef {object} Renderer | |
| 103 * @property {(text: string) => void} addText | |
| 104 * @property {(node: Node) => void} openNode | |
| 105 * @property {(node: Node) => void} closeNode | |
| 106 * @property {() => string} value | |
| 107 */ | |
| 108 | |
| 109 /** @typedef {{scope?: string, language?: string, sublanguage?: boolean}} Node */ | |
| 110 /** @typedef {{walk: (r: Renderer) => void}} Tree */ | |
| 111 /** */ | |
| 112 | |
| 113 const SPAN_CLOSE = '</span>'; | |
| 114 | |
| 115 /** | |
| 116 * Determines if a node needs to be wrapped in <span> | |
| 117 * | |
| 118 * @param {Node} node */ | |
| 119 const emitsWrappingTags = (node) => { | |
| 120 // rarely we can have a sublanguage where language is undefined | |
| 121 // TODO: track down why | |
| 122 return !!node.scope; | |
| 123 }; | |
| 124 | |
| 125 /** | |
| 126 * | |
| 127 * @param {string} name | |
| 128 * @param {{prefix:string}} options | |
| 129 */ | |
| 130 const scopeToCSSClass = (name, { prefix }) => { | |
| 131 // sub-language | |
| 132 if (name.startsWith("language:")) { | |
| 133 return name.replace("language:", "language-"); | |
| 134 } | |
| 135 // tiered scope: comment.line | |
| 136 if (name.includes(".")) { | |
| 137 const pieces = name.split("."); | |
| 138 return [ | |
| 139 `${prefix}${pieces.shift()}`, | |
| 140 ...(pieces.map((x, i) => `${x}${"_".repeat(i + 1)}`)) | |
| 141 ].join(" "); | |
| 142 } | |
| 143 // simple scope | |
| 144 return `${prefix}${name}`; | |
| 145 }; | |
| 146 | |
| 147 /** @type {Renderer} */ | |
| 148 class HTMLRenderer { | |
| 149 /** | |
| 150 * Creates a new HTMLRenderer | |
| 151 * | |
| 152 * @param {Tree} parseTree - the parse tree (must support `walk` API) | |
| 153 * @param {{classPrefix: string}} options | |
| 154 */ | |
| 155 constructor(parseTree, options) { | |
| 156 this.buffer = ""; | |
| 157 this.classPrefix = options.classPrefix; | |
| 158 parseTree.walk(this); | |
| 159 } | |
| 160 | |
| 161 /** | |
| 162 * Adds texts to the output stream | |
| 163 * | |
| 164 * @param {string} text */ | |
| 165 addText(text) { | |
| 166 this.buffer += escapeHTML(text); | |
| 167 } | |
| 168 | |
| 169 /** | |
| 170 * Adds a node open to the output stream (if needed) | |
| 171 * | |
| 172 * @param {Node} node */ | |
| 173 openNode(node) { | |
| 174 if (!emitsWrappingTags(node)) return; | |
| 175 | |
| 176 const className = scopeToCSSClass(node.scope, | |
| 177 { prefix: this.classPrefix }); | |
| 178 this.span(className); | |
| 179 } | |
| 180 | |
| 181 /** | |
| 182 * Adds a node close to the output stream (if needed) | |
| 183 * | |
| 184 * @param {Node} node */ | |
| 185 closeNode(node) { | |
| 186 if (!emitsWrappingTags(node)) return; | |
| 187 | |
| 188 this.buffer += SPAN_CLOSE; | |
| 189 } | |
| 190 | |
| 191 /** | |
| 192 * returns the accumulated buffer | |
| 193 */ | |
| 194 value() { | |
| 195 return this.buffer; | |
| 196 } | |
| 197 | |
| 198 // helpers | |
| 199 | |
| 200 /** | |
| 201 * Builds a span element | |
| 202 * | |
| 203 * @param {string} className */ | |
| 204 span(className) { | |
| 205 this.buffer += `<span class="${className}">`; | |
| 206 } | |
| 207 } | |
| 208 | |
| 209 /** @typedef {{scope?: string, language?: string, children: Node[]} | string} Node */ | |
| 210 /** @typedef {{scope?: string, language?: string, children: Node[]} } DataNode */ | |
| 211 /** @typedef {import('highlight.js').Emitter} Emitter */ | |
| 212 /** */ | |
| 213 | |
| 214 /** @returns {DataNode} */ | |
| 215 const newNode = (opts = {}) => { | |
| 216 /** @type DataNode */ | |
| 217 const result = { children: [] }; | |
| 218 Object.assign(result, opts); | |
| 219 return result; | |
| 220 }; | |
| 221 | |
| 222 class TokenTree { | |
| 223 constructor() { | |
| 224 /** @type DataNode */ | |
| 225 this.rootNode = newNode(); | |
| 226 this.stack = [this.rootNode]; | |
| 227 } | |
| 228 | |
| 229 get top() { | |
| 230 return this.stack[this.stack.length - 1]; | |
| 231 } | |
| 232 | |
| 233 get root() { return this.rootNode; } | |
| 234 | |
| 235 /** @param {Node} node */ | |
| 236 add(node) { | |
| 237 this.top.children.push(node); | |
| 238 } | |
| 239 | |
| 240 /** @param {string} scope */ | |
| 241 openNode(scope) { | |
| 242 /** @type Node */ | |
| 243 const node = newNode({ scope }); | |
| 244 this.add(node); | |
| 245 this.stack.push(node); | |
| 246 } | |
| 247 | |
| 248 closeNode() { | |
| 249 if (this.stack.length > 1) { | |
| 250 return this.stack.pop(); | |
| 251 } | |
| 252 // eslint-disable-next-line no-undefined | |
| 253 return undefined; | |
| 254 } | |
| 255 | |
| 256 closeAllNodes() { | |
| 257 while (this.closeNode()); | |
| 258 } | |
| 259 | |
| 260 toJSON() { | |
| 261 return JSON.stringify(this.rootNode, null, 4); | |
| 262 } | |
| 263 | |
| 264 /** | |
| 265 * @typedef { import("./html_renderer").Renderer } Renderer | |
| 266 * @param {Renderer} builder | |
| 267 */ | |
| 268 walk(builder) { | |
| 269 // this does not | |
| 270 return this.constructor._walk(builder, this.rootNode); | |
| 271 // this works | |
| 272 // return TokenTree._walk(builder, this.rootNode); | |
| 273 } | |
| 274 | |
| 275 /** | |
| 276 * @param {Renderer} builder | |
| 277 * @param {Node} node | |
| 278 */ | |
| 279 static _walk(builder, node) { | |
| 280 if (typeof node === "string") { | |
| 281 builder.addText(node); | |
| 282 } else if (node.children) { | |
| 283 builder.openNode(node); | |
| 284 node.children.forEach((child) => this._walk(builder, child)); | |
| 285 builder.closeNode(node); | |
| 286 } | |
| 287 return builder; | |
| 288 } | |
| 289 | |
| 290 /** | |
| 291 * @param {Node} node | |
| 292 */ | |
| 293 static _collapse(node) { | |
| 294 if (typeof node === "string") return; | |
| 295 if (!node.children) return; | |
| 296 | |
| 297 if (node.children.every(el => typeof el === "string")) { | |
| 298 // node.text = node.children.join(""); | |
| 299 // delete node.children; | |
| 300 node.children = [node.children.join("")]; | |
| 301 } else { | |
| 302 node.children.forEach((child) => { | |
| 303 TokenTree._collapse(child); | |
| 304 }); | |
| 305 } | |
| 306 } | |
| 307 } | |
| 308 | |
| 309 /** | |
| 310 Currently this is all private API, but this is the minimal API necessary | |
| 311 that an Emitter must implement to fully support the parser. | |
| 312 | |
| 313 Minimal interface: | |
| 314 | |
| 315 - addText(text) | |
| 316 - __addSublanguage(emitter, subLanguageName) | |
| 317 - startScope(scope) | |
| 318 - endScope() | |
| 319 - finalize() | |
| 320 - toHTML() | |
| 321 | |
| 322 */ | |
| 323 | |
| 324 /** | |
| 325 * @implements {Emitter} | |
| 326 */ | |
| 327 class TokenTreeEmitter extends TokenTree { | |
| 328 /** | |
| 329 * @param {*} options | |
| 330 */ | |
| 331 constructor(options) { | |
| 332 super(); | |
| 333 this.options = options; | |
| 334 } | |
| 335 | |
| 336 /** | |
| 337 * @param {string} text | |
| 338 */ | |
| 339 addText(text) { | |
| 340 if (text === "") { return; } | |
| 341 | |
| 342 this.add(text); | |
| 343 } | |
| 344 | |
| 345 /** @param {string} scope */ | |
| 346 startScope(scope) { | |
| 347 this.openNode(scope); | |
| 348 } | |
| 349 | |
| 350 endScope() { | |
| 351 this.closeNode(); | |
| 352 } | |
| 353 | |
| 354 /** | |
| 355 * @param {Emitter & {root: DataNode}} emitter | |
| 356 * @param {string} name | |
| 357 */ | |
| 358 __addSublanguage(emitter, name) { | |
| 359 /** @type DataNode */ | |
| 360 const node = emitter.root; | |
| 361 if (name) node.scope = `language:${name}`; | |
| 362 | |
| 363 this.add(node); | |
| 364 } | |
| 365 | |
| 366 toHTML() { | |
| 367 const renderer = new HTMLRenderer(this, this.options); | |
| 368 return renderer.value(); | |
| 369 } | |
| 370 | |
| 371 finalize() { | |
| 372 this.closeAllNodes(); | |
| 373 return true; | |
| 374 } | |
| 375 } | |
| 376 | |
| 377 /** | |
| 378 * @param {string} value | |
| 379 * @returns {RegExp} | |
| 380 * */ | |
| 381 | |
| 382 /** | |
| 383 * @param {RegExp | string } re | |
| 384 * @returns {string} | |
| 385 */ | |
| 386 function source(re) { | |
| 387 if (!re) return null; | |
| 388 if (typeof re === "string") return re; | |
| 389 | |
| 390 return re.source; | |
| 391 } | |
| 392 | |
| 393 /** | |
| 394 * @param {RegExp | string } re | |
| 395 * @returns {string} | |
| 396 */ | |
| 397 function lookahead(re) { | |
| 398 return concat('(?=', re, ')'); | |
| 399 } | |
| 400 | |
| 401 /** | |
| 402 * @param {RegExp | string } re | |
| 403 * @returns {string} | |
| 404 */ | |
| 405 function anyNumberOfTimes(re) { | |
| 406 return concat('(?:', re, ')*'); | |
| 407 } | |
| 408 | |
| 409 /** | |
| 410 * @param {RegExp | string } re | |
| 411 * @returns {string} | |
| 412 */ | |
| 413 function optional(re) { | |
| 414 return concat('(?:', re, ')?'); | |
| 415 } | |
| 416 | |
| 417 /** | |
| 418 * @param {...(RegExp | string) } args | |
| 419 * @returns {string} | |
| 420 */ | |
| 421 function concat(...args) { | |
| 422 const joined = args.map((x) => source(x)).join(""); | |
| 423 return joined; | |
| 424 } | |
| 425 | |
| 426 /** | |
| 427 * @param { Array<string | RegExp | Object> } args | |
| 428 * @returns {object} | |
| 429 */ | |
| 430 function stripOptionsFromArgs(args) { | |
| 431 const opts = args[args.length - 1]; | |
| 432 | |
| 433 if (typeof opts === 'object' && opts.constructor === Object) { | |
| 434 args.splice(args.length - 1, 1); | |
| 435 return opts; | |
| 436 } else { | |
| 437 return {}; | |
| 438 } | |
| 439 } | |
| 440 | |
| 441 /** @typedef { {capture?: boolean} } RegexEitherOptions */ | |
| 442 | |
| 443 /** | |
| 444 * Any of the passed expresssions may match | |
| 445 * | |
| 446 * Creates a huge this | this | that | that match | |
| 447 * @param {(RegExp | string)[] | [...(RegExp | string)[], RegexEitherOptions]} args | |
| 448 * @returns {string} | |
| 449 */ | |
| 450 function either(...args) { | |
| 451 /** @type { object & {capture?: boolean} } */ | |
| 452 const opts = stripOptionsFromArgs(args); | |
| 453 const joined = '(' | |
| 454 + (opts.capture ? "" : "?:") | |
| 455 + args.map((x) => source(x)).join("|") + ")"; | |
| 456 return joined; | |
| 457 } | |
| 458 | |
| 459 /** | |
| 460 * @param {RegExp | string} re | |
| 461 * @returns {number} | |
| 462 */ | |
| 463 function countMatchGroups(re) { | |
| 464 return (new RegExp(re.toString() + '|')).exec('').length - 1; | |
| 465 } | |
| 466 | |
| 467 /** | |
| 468 * Does lexeme start with a regular expression match at the beginning | |
| 469 * @param {RegExp} re | |
| 470 * @param {string} lexeme | |
| 471 */ | |
| 472 function startsWith(re, lexeme) { | |
| 473 const match = re && re.exec(lexeme); | |
| 474 return match && match.index === 0; | |
| 475 } | |
| 476 | |
| 477 // BACKREF_RE matches an open parenthesis or backreference. To avoid | |
| 478 // an incorrect parse, it additionally matches the following: | |
| 479 // - [...] elements, where the meaning of parentheses and escapes change | |
| 480 // - other escape sequences, so we do not misparse escape sequences as | |
| 481 // interesting elements | |
| 482 // - non-matching or lookahead parentheses, which do not capture. These | |
| 483 // follow the '(' with a '?'. | |
| 484 const BACKREF_RE = /\[(?:[^\\\]]|\\.)*\]|\(\??|\\([1-9][0-9]*)|\\./; | |
| 485 | |
| 486 // **INTERNAL** Not intended for outside usage | |
| 487 // join logically computes regexps.join(separator), but fixes the | |
| 488 // backreferences so they continue to match. | |
| 489 // it also places each individual regular expression into it's own | |
| 490 // match group, keeping track of the sequencing of those match groups | |
| 491 // is currently an exercise for the caller. :-) | |
| 492 /** | |
| 493 * @param {(string | RegExp)[]} regexps | |
| 494 * @param {{joinWith: string}} opts | |
| 495 * @returns {string} | |
| 496 */ | |
| 497 function _rewriteBackreferences(regexps, { joinWith }) { | |
| 498 let numCaptures = 0; | |
| 499 | |
| 500 return regexps.map((regex) => { | |
| 501 numCaptures += 1; | |
| 502 const offset = numCaptures; | |
| 503 let re = source(regex); | |
| 504 let out = ''; | |
| 505 | |
| 506 while (re.length > 0) { | |
| 507 const match = BACKREF_RE.exec(re); | |
| 508 if (!match) { | |
| 509 out += re; | |
| 510 break; | |
| 511 } | |
| 512 out += re.substring(0, match.index); | |
| 513 re = re.substring(match.index + match[0].length); | |
| 514 if (match[0][0] === '\\' && match[1]) { | |
| 515 // Adjust the backreference. | |
| 516 out += '\\' + String(Number(match[1]) + offset); | |
| 517 } else { | |
| 518 out += match[0]; | |
| 519 if (match[0] === '(') { | |
| 520 numCaptures++; | |
| 521 } | |
| 522 } | |
| 523 } | |
| 524 return out; | |
| 525 }).map(re => `(${re})`).join(joinWith); | |
| 526 } | |
| 527 | |
| 528 /** @typedef {import('highlight.js').Mode} Mode */ | |
| 529 /** @typedef {import('highlight.js').ModeCallback} ModeCallback */ | |
| 530 | |
| 531 // Common regexps | |
| 532 const MATCH_NOTHING_RE = /\b\B/; | |
| 533 const IDENT_RE = '[a-zA-Z]\\w*'; | |
| 534 const UNDERSCORE_IDENT_RE = '[a-zA-Z_]\\w*'; | |
| 535 const NUMBER_RE = '\\b\\d+(\\.\\d+)?'; | |
| 536 const C_NUMBER_RE = '(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)'; // 0x..., 0..., decimal, float | |
| 537 const BINARY_NUMBER_RE = '\\b(0b[01]+)'; // 0b... | |
| 538 const RE_STARTERS_RE = '!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~'; | |
| 539 | |
| 540 /** | |
| 541 * @param { Partial<Mode> & {binary?: string | RegExp} } opts | |
| 542 */ | |
| 543 const SHEBANG = (opts = {}) => { | |
| 544 const beginShebang = /^#![ ]*\//; | |
| 545 if (opts.binary) { | |
| 546 opts.begin = concat( | |
| 547 beginShebang, | |
| 548 /.*\b/, | |
| 549 opts.binary, | |
| 550 /\b.*/); | |
| 551 } | |
| 552 return inherit$1({ | |
| 553 scope: 'meta', | |
| 554 begin: beginShebang, | |
| 555 end: /$/, | |
| 556 relevance: 0, | |
| 557 /** @type {ModeCallback} */ | |
| 558 "on:begin": (m, resp) => { | |
| 559 if (m.index !== 0) resp.ignoreMatch(); | |
| 560 } | |
| 561 }, opts); | |
| 562 }; | |
| 563 | |
| 564 // Common modes | |
| 565 const BACKSLASH_ESCAPE = { | |
| 566 begin: '\\\\[\\s\\S]', relevance: 0 | |
| 567 }; | |
| 568 const APOS_STRING_MODE = { | |
| 569 scope: 'string', | |
| 570 begin: '\'', | |
| 571 end: '\'', | |
| 572 illegal: '\\n', | |
| 573 contains: [BACKSLASH_ESCAPE] | |
| 574 }; | |
| 575 const QUOTE_STRING_MODE = { | |
| 576 scope: 'string', | |
| 577 begin: '"', | |
| 578 end: '"', | |
| 579 illegal: '\\n', | |
| 580 contains: [BACKSLASH_ESCAPE] | |
| 581 }; | |
| 582 const PHRASAL_WORDS_MODE = { | |
| 583 begin: /\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\b/ | |
| 584 }; | |
| 585 /** | |
| 586 * Creates a comment mode | |
| 587 * | |
| 588 * @param {string | RegExp} begin | |
| 589 * @param {string | RegExp} end | |
| 590 * @param {Mode | {}} [modeOptions] | |
| 591 * @returns {Partial<Mode>} | |
| 592 */ | |
| 593 const COMMENT = function(begin, end, modeOptions = {}) { | |
| 594 const mode = inherit$1( | |
| 595 { | |
| 596 scope: 'comment', | |
| 597 begin, | |
| 598 end, | |
| 599 contains: [] | |
| 600 }, | |
| 601 modeOptions | |
| 602 ); | |
| 603 mode.contains.push({ | |
| 604 scope: 'doctag', | |
| 605 // hack to avoid the space from being included. the space is necessary to | |
| 606 // match here to prevent the plain text rule below from gobbling up doctags | |
| 607 begin: '[ ]*(?=(TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):)', | |
| 608 end: /(TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):/, | |
| 609 excludeBegin: true, | |
| 610 relevance: 0 | |
| 611 }); | |
| 612 const ENGLISH_WORD = either( | |
| 613 // list of common 1 and 2 letter words in English | |
| 614 "I", | |
| 615 "a", | |
| 616 "is", | |
| 617 "so", | |
| 618 "us", | |
| 619 "to", | |
| 620 "at", | |
| 621 "if", | |
| 622 "in", | |
| 623 "it", | |
| 624 "on", | |
| 625 // note: this is not an exhaustive list of contractions, just popular ones | |
| 626 /[A-Za-z]+['](d|ve|re|ll|t|s|n)/, // contractions - can't we'd they're let's, etc | |
| 627 /[A-Za-z]+[-][a-z]+/, // `no-way`, etc. | |
| 628 /[A-Za-z][a-z]{2,}/ // allow capitalized words at beginning of sentences | |
| 629 ); | |
| 630 // looking like plain text, more likely to be a comment | |
| 631 mode.contains.push( | |
| 632 { | |
| 633 // TODO: how to include ", (, ) without breaking grammars that use these for | |
| 634 // comment delimiters? | |
| 635 // begin: /[ ]+([()"]?([A-Za-z'-]{3,}|is|a|I|so|us|[tT][oO]|at|if|in|it|on)[.]?[()":]?([.][ ]|[ ]|\))){3}/ | |
| 636 // --- | |
| 637 | |
| 638 // this tries to find sequences of 3 english words in a row (without any | |
| 639 // "programming" type syntax) this gives us a strong signal that we've | |
| 640 // TRULY found a comment - vs perhaps scanning with the wrong language. | |
| 641 // It's possible to find something that LOOKS like the start of the | |
| 642 // comment - but then if there is no readable text - good chance it is a | |
| 643 // false match and not a comment. | |
| 644 // | |
| 645 // for a visual example please see: | |
| 646 // https://github.com/highlightjs/highlight.js/issues/2827 | |
| 647 | |
| 648 begin: concat( | |
| 649 /[ ]+/, // necessary to prevent us gobbling up doctags like /* @author Bob Mcgill */ | |
| 650 '(', | |
| 651 ENGLISH_WORD, | |
| 652 /[.]?[:]?([.][ ]|[ ])/, | |
| 653 '){3}') // look for 3 words in a row | |
| 654 } | |
| 655 ); | |
| 656 return mode; | |
| 657 }; | |
| 658 const C_LINE_COMMENT_MODE = COMMENT('//', '$'); | |
| 659 const C_BLOCK_COMMENT_MODE = COMMENT('/\\*', '\\*/'); | |
| 660 const HASH_COMMENT_MODE = COMMENT('#', '$'); | |
| 661 const NUMBER_MODE = { | |
| 662 scope: 'number', | |
| 663 begin: NUMBER_RE, | |
| 664 relevance: 0 | |
| 665 }; | |
| 666 const C_NUMBER_MODE = { | |
| 667 scope: 'number', | |
| 668 begin: C_NUMBER_RE, | |
| 669 relevance: 0 | |
| 670 }; | |
| 671 const BINARY_NUMBER_MODE = { | |
| 672 scope: 'number', | |
| 673 begin: BINARY_NUMBER_RE, | |
| 674 relevance: 0 | |
| 675 }; | |
| 676 const REGEXP_MODE = { | |
| 677 scope: "regexp", | |
| 678 begin: /\/(?=[^/\n]*\/)/, | |
| 679 end: /\/[gimuy]*/, | |
| 680 contains: [ | |
| 681 BACKSLASH_ESCAPE, | |
| 682 { | |
| 683 begin: /\[/, | |
| 684 end: /\]/, | |
| 685 relevance: 0, | |
| 686 contains: [BACKSLASH_ESCAPE] | |
| 687 } | |
| 688 ] | |
| 689 }; | |
| 690 const TITLE_MODE = { | |
| 691 scope: 'title', | |
| 692 begin: IDENT_RE, | |
| 693 relevance: 0 | |
| 694 }; | |
| 695 const UNDERSCORE_TITLE_MODE = { | |
| 696 scope: 'title', | |
| 697 begin: UNDERSCORE_IDENT_RE, | |
| 698 relevance: 0 | |
| 699 }; | |
| 700 const METHOD_GUARD = { | |
| 701 // excludes method names from keyword processing | |
| 702 begin: '\\.\\s*' + UNDERSCORE_IDENT_RE, | |
| 703 relevance: 0 | |
| 704 }; | |
| 705 | |
| 706 /** | |
| 707 * Adds end same as begin mechanics to a mode | |
| 708 * | |
| 709 * Your mode must include at least a single () match group as that first match | |
| 710 * group is what is used for comparison | |
| 711 * @param {Partial<Mode>} mode | |
| 712 */ | |
| 713 const END_SAME_AS_BEGIN = function(mode) { | |
| 714 return Object.assign(mode, | |
| 715 { | |
| 716 /** @type {ModeCallback} */ | |
| 717 'on:begin': (m, resp) => { resp.data._beginMatch = m[1]; }, | |
| 718 /** @type {ModeCallback} */ | |
| 719 'on:end': (m, resp) => { if (resp.data._beginMatch !== m[1]) resp.ignoreMatch(); } | |
| 720 }); | |
| 721 }; | |
| 722 | |
| 723 var MODES = /*#__PURE__*/Object.freeze({ | |
| 724 __proto__: null, | |
| 725 APOS_STRING_MODE: APOS_STRING_MODE, | |
| 726 BACKSLASH_ESCAPE: BACKSLASH_ESCAPE, | |
| 727 BINARY_NUMBER_MODE: BINARY_NUMBER_MODE, | |
| 728 BINARY_NUMBER_RE: BINARY_NUMBER_RE, | |
| 729 COMMENT: COMMENT, | |
| 730 C_BLOCK_COMMENT_MODE: C_BLOCK_COMMENT_MODE, | |
| 731 C_LINE_COMMENT_MODE: C_LINE_COMMENT_MODE, | |
| 732 C_NUMBER_MODE: C_NUMBER_MODE, | |
| 733 C_NUMBER_RE: C_NUMBER_RE, | |
| 734 END_SAME_AS_BEGIN: END_SAME_AS_BEGIN, | |
| 735 HASH_COMMENT_MODE: HASH_COMMENT_MODE, | |
| 736 IDENT_RE: IDENT_RE, | |
| 737 MATCH_NOTHING_RE: MATCH_NOTHING_RE, | |
| 738 METHOD_GUARD: METHOD_GUARD, | |
| 739 NUMBER_MODE: NUMBER_MODE, | |
| 740 NUMBER_RE: NUMBER_RE, | |
| 741 PHRASAL_WORDS_MODE: PHRASAL_WORDS_MODE, | |
| 742 QUOTE_STRING_MODE: QUOTE_STRING_MODE, | |
| 743 REGEXP_MODE: REGEXP_MODE, | |
| 744 RE_STARTERS_RE: RE_STARTERS_RE, | |
| 745 SHEBANG: SHEBANG, | |
| 746 TITLE_MODE: TITLE_MODE, | |
| 747 UNDERSCORE_IDENT_RE: UNDERSCORE_IDENT_RE, | |
| 748 UNDERSCORE_TITLE_MODE: UNDERSCORE_TITLE_MODE | |
| 749 }); | |
| 750 | |
| 751 /** | |
| 752 @typedef {import('highlight.js').CallbackResponse} CallbackResponse | |
| 753 @typedef {import('highlight.js').CompilerExt} CompilerExt | |
| 754 */ | |
| 755 | |
| 756 // Grammar extensions / plugins | |
| 757 // See: https://github.com/highlightjs/highlight.js/issues/2833 | |
| 758 | |
| 759 // Grammar extensions allow "syntactic sugar" to be added to the grammar modes | |
| 760 // without requiring any underlying changes to the compiler internals. | |
| 761 | |
| 762 // `compileMatch` being the perfect small example of now allowing a grammar | |
| 763 // author to write `match` when they desire to match a single expression rather | |
| 764 // than being forced to use `begin`. The extension then just moves `match` into | |
| 765 // `begin` when it runs. Ie, no features have been added, but we've just made | |
| 766 // the experience of writing (and reading grammars) a little bit nicer. | |
| 767 | |
| 768 // ------ | |
| 769 | |
| 770 // TODO: We need negative look-behind support to do this properly | |
| 771 /** | |
| 772 * Skip a match if it has a preceding dot | |
| 773 * | |
| 774 * This is used for `beginKeywords` to prevent matching expressions such as | |
| 775 * `bob.keyword.do()`. The mode compiler automatically wires this up as a | |
| 776 * special _internal_ 'on:begin' callback for modes with `beginKeywords` | |
| 777 * @param {RegExpMatchArray} match | |
| 778 * @param {CallbackResponse} response | |
| 779 */ | |
| 780 function skipIfHasPrecedingDot(match, response) { | |
| 781 const before = match.input[match.index - 1]; | |
| 782 if (before === ".") { | |
| 783 response.ignoreMatch(); | |
| 784 } | |
| 785 } | |
| 786 | |
| 787 /** | |
| 788 * | |
| 789 * @type {CompilerExt} | |
| 790 */ | |
| 791 function scopeClassName(mode, _parent) { | |
| 792 // eslint-disable-next-line no-undefined | |
| 793 if (mode.className !== undefined) { | |
| 794 mode.scope = mode.className; | |
| 795 delete mode.className; | |
| 796 } | |
| 797 } | |
| 798 | |
| 799 /** | |
| 800 * `beginKeywords` syntactic sugar | |
| 801 * @type {CompilerExt} | |
| 802 */ | |
| 803 function beginKeywords(mode, parent) { | |
| 804 if (!parent) return; | |
| 805 if (!mode.beginKeywords) return; | |
| 806 | |
| 807 // for languages with keywords that include non-word characters checking for | |
| 808 // a word boundary is not sufficient, so instead we check for a word boundary | |
| 809 // or whitespace - this does no harm in any case since our keyword engine | |
| 810 // doesn't allow spaces in keywords anyways and we still check for the boundary | |
| 811 // first | |
| 812 mode.begin = '\\b(' + mode.beginKeywords.split(' ').join('|') + ')(?!\\.)(?=\\b|\\s)'; | |
| 813 mode.__beforeBegin = skipIfHasPrecedingDot; | |
| 814 mode.keywords = mode.keywords || mode.beginKeywords; | |
| 815 delete mode.beginKeywords; | |
| 816 | |
| 817 // prevents double relevance, the keywords themselves provide | |
| 818 // relevance, the mode doesn't need to double it | |
| 819 // eslint-disable-next-line no-undefined | |
| 820 if (mode.relevance === undefined) mode.relevance = 0; | |
| 821 } | |
| 822 | |
| 823 /** | |
| 824 * Allow `illegal` to contain an array of illegal values | |
| 825 * @type {CompilerExt} | |
| 826 */ | |
| 827 function compileIllegal(mode, _parent) { | |
| 828 if (!Array.isArray(mode.illegal)) return; | |
| 829 | |
| 830 mode.illegal = either(...mode.illegal); | |
| 831 } | |
| 832 | |
| 833 /** | |
| 834 * `match` to match a single expression for readability | |
| 835 * @type {CompilerExt} | |
| 836 */ | |
| 837 function compileMatch(mode, _parent) { | |
| 838 if (!mode.match) return; | |
| 839 if (mode.begin || mode.end) throw new Error("begin & end are not supported with match"); | |
| 840 | |
| 841 mode.begin = mode.match; | |
| 842 delete mode.match; | |
| 843 } | |
| 844 | |
| 845 /** | |
| 846 * provides the default 1 relevance to all modes | |
| 847 * @type {CompilerExt} | |
| 848 */ | |
| 849 function compileRelevance(mode, _parent) { | |
| 850 // eslint-disable-next-line no-undefined | |
| 851 if (mode.relevance === undefined) mode.relevance = 1; | |
| 852 } | |
| 853 | |
| 854 // allow beforeMatch to act as a "qualifier" for the match | |
| 855 // the full match begin must be [beforeMatch][begin] | |
| 856 const beforeMatchExt = (mode, parent) => { | |
| 857 if (!mode.beforeMatch) return; | |
| 858 // starts conflicts with endsParent which we need to make sure the child | |
| 859 // rule is not matched multiple times | |
| 860 if (mode.starts) throw new Error("beforeMatch cannot be used with starts"); | |
| 861 | |
| 862 const originalMode = Object.assign({}, mode); | |
| 863 Object.keys(mode).forEach((key) => { delete mode[key]; }); | |
| 864 | |
| 865 mode.keywords = originalMode.keywords; | |
| 866 mode.begin = concat(originalMode.beforeMatch, lookahead(originalMode.begin)); | |
| 867 mode.starts = { | |
| 868 relevance: 0, | |
| 869 contains: [ | |
| 870 Object.assign(originalMode, { endsParent: true }) | |
| 871 ] | |
| 872 }; | |
| 873 mode.relevance = 0; | |
| 874 | |
| 875 delete originalMode.beforeMatch; | |
| 876 }; | |
| 877 | |
| 878 // keywords that should have no default relevance value | |
| 879 const COMMON_KEYWORDS = [ | |
| 880 'of', | |
| 881 'and', | |
| 882 'for', | |
| 883 'in', | |
| 884 'not', | |
| 885 'or', | |
| 886 'if', | |
| 887 'then', | |
| 888 'parent', // common variable name | |
| 889 'list', // common variable name | |
| 890 'value' // common variable name | |
| 891 ]; | |
| 892 | |
| 893 const DEFAULT_KEYWORD_SCOPE = "keyword"; | |
| 894 | |
| 895 /** | |
| 896 * Given raw keywords from a language definition, compile them. | |
| 897 * | |
| 898 * @param {string | Record<string,string|string[]> | Array<string>} rawKeywords | |
| 899 * @param {boolean} caseInsensitive | |
| 900 */ | |
| 901 function compileKeywords(rawKeywords, caseInsensitive, scopeName = DEFAULT_KEYWORD_SCOPE) { | |
| 902 /** @type {import("highlight.js/private").KeywordDict} */ | |
| 903 const compiledKeywords = Object.create(null); | |
| 904 | |
| 905 // input can be a string of keywords, an array of keywords, or a object with | |
| 906 // named keys representing scopeName (which can then point to a string or array) | |
| 907 if (typeof rawKeywords === 'string') { | |
| 908 compileList(scopeName, rawKeywords.split(" ")); | |
| 909 } else if (Array.isArray(rawKeywords)) { | |
| 910 compileList(scopeName, rawKeywords); | |
| 911 } else { | |
| 912 Object.keys(rawKeywords).forEach(function(scopeName) { | |
| 913 // collapse all our objects back into the parent object | |
| 914 Object.assign( | |
| 915 compiledKeywords, | |
| 916 compileKeywords(rawKeywords[scopeName], caseInsensitive, scopeName) | |
| 917 ); | |
| 918 }); | |
| 919 } | |
| 920 return compiledKeywords; | |
| 921 | |
| 922 // --- | |
| 923 | |
| 924 /** | |
| 925 * Compiles an individual list of keywords | |
| 926 * | |
| 927 * Ex: "for if when while|5" | |
| 928 * | |
| 929 * @param {string} scopeName | |
| 930 * @param {Array<string>} keywordList | |
| 931 */ | |
| 932 function compileList(scopeName, keywordList) { | |
| 933 if (caseInsensitive) { | |
| 934 keywordList = keywordList.map(x => x.toLowerCase()); | |
| 935 } | |
| 936 keywordList.forEach(function(keyword) { | |
| 937 const pair = keyword.split('|'); | |
| 938 compiledKeywords[pair[0]] = [scopeName, scoreForKeyword(pair[0], pair[1])]; | |
| 939 }); | |
| 940 } | |
| 941 } | |
| 942 | |
| 943 /** | |
| 944 * Returns the proper score for a given keyword | |
| 945 * | |
| 946 * Also takes into account comment keywords, which will be scored 0 UNLESS | |
| 947 * another score has been manually assigned. | |
| 948 * @param {string} keyword | |
| 949 * @param {string} [providedScore] | |
| 950 */ | |
| 951 function scoreForKeyword(keyword, providedScore) { | |
| 952 // manual scores always win over common keywords | |
| 953 // so you can force a score of 1 if you really insist | |
| 954 if (providedScore) { | |
| 955 return Number(providedScore); | |
| 956 } | |
| 957 | |
| 958 return commonKeyword(keyword) ? 0 : 1; | |
| 959 } | |
| 960 | |
| 961 /** | |
| 962 * Determines if a given keyword is common or not | |
| 963 * | |
| 964 * @param {string} keyword */ | |
| 965 function commonKeyword(keyword) { | |
| 966 return COMMON_KEYWORDS.includes(keyword.toLowerCase()); | |
| 967 } | |
| 968 | |
| 969 /* | |
| 970 | |
| 971 For the reasoning behind this please see: | |
| 972 https://github.com/highlightjs/highlight.js/issues/2880#issuecomment-747275419 | |
| 973 | |
| 974 */ | |
| 975 | |
| 976 /** | |
| 977 * @type {Record<string, boolean>} | |
| 978 */ | |
| 979 const seenDeprecations = {}; | |
| 980 | |
| 981 /** | |
| 982 * @param {string} message | |
| 983 */ | |
| 984 const error = (message) => { | |
| 985 console.error(message); | |
| 986 }; | |
| 987 | |
| 988 /** | |
| 989 * @param {string} message | |
| 990 * @param {any} args | |
| 991 */ | |
| 992 const warn = (message, ...args) => { | |
| 993 console.log(`WARN: ${message}`, ...args); | |
| 994 }; | |
| 995 | |
| 996 /** | |
| 997 * @param {string} version | |
| 998 * @param {string} message | |
| 999 */ | |
| 1000 const deprecated = (version, message) => { | |
| 1001 if (seenDeprecations[`${version}/${message}`]) return; | |
| 1002 | |
| 1003 console.log(`Deprecated as of ${version}. ${message}`); | |
| 1004 seenDeprecations[`${version}/${message}`] = true; | |
| 1005 }; | |
| 1006 | |
| 1007 /* eslint-disable no-throw-literal */ | |
| 1008 | |
| 1009 /** | |
| 1010 @typedef {import('highlight.js').CompiledMode} CompiledMode | |
| 1011 */ | |
| 1012 | |
| 1013 const MultiClassError = new Error(); | |
| 1014 | |
| 1015 /** | |
| 1016 * Renumbers labeled scope names to account for additional inner match | |
| 1017 * groups that otherwise would break everything. | |
| 1018 * | |
| 1019 * Lets say we 3 match scopes: | |
| 1020 * | |
| 1021 * { 1 => ..., 2 => ..., 3 => ... } | |
| 1022 * | |
| 1023 * So what we need is a clean match like this: | |
| 1024 * | |
| 1025 * (a)(b)(c) => [ "a", "b", "c" ] | |
| 1026 * | |
| 1027 * But this falls apart with inner match groups: | |
| 1028 * | |
| 1029 * (a)(((b)))(c) => ["a", "b", "b", "b", "c" ] | |
| 1030 * | |
| 1031 * Our scopes are now "out of alignment" and we're repeating `b` 3 times. | |
| 1032 * What needs to happen is the numbers are remapped: | |
| 1033 * | |
| 1034 * { 1 => ..., 2 => ..., 5 => ... } | |
| 1035 * | |
| 1036 * We also need to know that the ONLY groups that should be output | |
| 1037 * are 1, 2, and 5. This function handles this behavior. | |
| 1038 * | |
| 1039 * @param {CompiledMode} mode | |
| 1040 * @param {Array<RegExp | string>} regexes | |
| 1041 * @param {{key: "beginScope"|"endScope"}} opts | |
| 1042 */ | |
| 1043 function remapScopeNames(mode, regexes, { key }) { | |
| 1044 let offset = 0; | |
| 1045 const scopeNames = mode[key]; | |
| 1046 /** @type Record<number,boolean> */ | |
| 1047 const emit = {}; | |
| 1048 /** @type Record<number,string> */ | |
| 1049 const positions = {}; | |
| 1050 | |
| 1051 for (let i = 1; i <= regexes.length; i++) { | |
| 1052 positions[i + offset] = scopeNames[i]; | |
| 1053 emit[i + offset] = true; | |
| 1054 offset += countMatchGroups(regexes[i - 1]); | |
| 1055 } | |
| 1056 // we use _emit to keep track of which match groups are "top-level" to avoid double | |
| 1057 // output from inside match groups | |
| 1058 mode[key] = positions; | |
| 1059 mode[key]._emit = emit; | |
| 1060 mode[key]._multi = true; | |
| 1061 } | |
| 1062 | |
| 1063 /** | |
| 1064 * @param {CompiledMode} mode | |
| 1065 */ | |
| 1066 function beginMultiClass(mode) { | |
| 1067 if (!Array.isArray(mode.begin)) return; | |
| 1068 | |
| 1069 if (mode.skip || mode.excludeBegin || mode.returnBegin) { | |
| 1070 error("skip, excludeBegin, returnBegin not compatible with beginScope: {}"); | |
| 1071 throw MultiClassError; | |
| 1072 } | |
| 1073 | |
| 1074 if (typeof mode.beginScope !== "object" || mode.beginScope === null) { | |
| 1075 error("beginScope must be object"); | |
| 1076 throw MultiClassError; | |
| 1077 } | |
| 1078 | |
| 1079 remapScopeNames(mode, mode.begin, { key: "beginScope" }); | |
| 1080 mode.begin = _rewriteBackreferences(mode.begin, { joinWith: "" }); | |
| 1081 } | |
| 1082 | |
| 1083 /** | |
| 1084 * @param {CompiledMode} mode | |
| 1085 */ | |
| 1086 function endMultiClass(mode) { | |
| 1087 if (!Array.isArray(mode.end)) return; | |
| 1088 | |
| 1089 if (mode.skip || mode.excludeEnd || mode.returnEnd) { | |
| 1090 error("skip, excludeEnd, returnEnd not compatible with endScope: {}"); | |
| 1091 throw MultiClassError; | |
| 1092 } | |
| 1093 | |
| 1094 if (typeof mode.endScope !== "object" || mode.endScope === null) { | |
| 1095 error("endScope must be object"); | |
| 1096 throw MultiClassError; | |
| 1097 } | |
| 1098 | |
| 1099 remapScopeNames(mode, mode.end, { key: "endScope" }); | |
| 1100 mode.end = _rewriteBackreferences(mode.end, { joinWith: "" }); | |
| 1101 } | |
| 1102 | |
| 1103 /** | |
| 1104 * this exists only to allow `scope: {}` to be used beside `match:` | |
| 1105 * Otherwise `beginScope` would necessary and that would look weird | |
| 1106 | |
| 1107 { | |
| 1108 match: [ /def/, /\w+/ ] | |
| 1109 scope: { 1: "keyword" , 2: "title" } | |
| 1110 } | |
| 1111 | |
| 1112 * @param {CompiledMode} mode | |
| 1113 */ | |
| 1114 function scopeSugar(mode) { | |
| 1115 if (mode.scope && typeof mode.scope === "object" && mode.scope !== null) { | |
| 1116 mode.beginScope = mode.scope; | |
| 1117 delete mode.scope; | |
| 1118 } | |
| 1119 } | |
| 1120 | |
| 1121 /** | |
| 1122 * @param {CompiledMode} mode | |
| 1123 */ | |
| 1124 function MultiClass(mode) { | |
| 1125 scopeSugar(mode); | |
| 1126 | |
| 1127 if (typeof mode.beginScope === "string") { | |
| 1128 mode.beginScope = { _wrap: mode.beginScope }; | |
| 1129 } | |
| 1130 if (typeof mode.endScope === "string") { | |
| 1131 mode.endScope = { _wrap: mode.endScope }; | |
| 1132 } | |
| 1133 | |
| 1134 beginMultiClass(mode); | |
| 1135 endMultiClass(mode); | |
| 1136 } | |
| 1137 | |
| 1138 /** | |
| 1139 @typedef {import('highlight.js').Mode} Mode | |
| 1140 @typedef {import('highlight.js').CompiledMode} CompiledMode | |
| 1141 @typedef {import('highlight.js').Language} Language | |
| 1142 @typedef {import('highlight.js').HLJSPlugin} HLJSPlugin | |
| 1143 @typedef {import('highlight.js').CompiledLanguage} CompiledLanguage | |
| 1144 */ | |
| 1145 | |
| 1146 // compilation | |
| 1147 | |
| 1148 /** | |
| 1149 * Compiles a language definition result | |
| 1150 * | |
| 1151 * Given the raw result of a language definition (Language), compiles this so | |
| 1152 * that it is ready for highlighting code. | |
| 1153 * @param {Language} language | |
| 1154 * @returns {CompiledLanguage} | |
| 1155 */ | |
| 1156 function compileLanguage(language) { | |
| 1157 /** | |
| 1158 * Builds a regex with the case sensitivity of the current language | |
| 1159 * | |
| 1160 * @param {RegExp | string} value | |
| 1161 * @param {boolean} [global] | |
| 1162 */ | |
| 1163 function langRe(value, global) { | |
| 1164 return new RegExp( | |
| 1165 source(value), | |
| 1166 'm' | |
| 1167 + (language.case_insensitive ? 'i' : '') | |
| 1168 + (language.unicodeRegex ? 'u' : '') | |
| 1169 + (global ? 'g' : '') | |
| 1170 ); | |
| 1171 } | |
| 1172 | |
| 1173 /** | |
| 1174 Stores multiple regular expressions and allows you to quickly search for | |
| 1175 them all in a string simultaneously - returning the first match. It does | |
| 1176 this by creating a huge (a|b|c) regex - each individual item wrapped with () | |
| 1177 and joined by `|` - using match groups to track position. When a match is | |
| 1178 found checking which position in the array has content allows us to figure | |
| 1179 out which of the original regexes / match groups triggered the match. | |
| 1180 | |
| 1181 The match object itself (the result of `Regex.exec`) is returned but also | |
| 1182 enhanced by merging in any meta-data that was registered with the regex. | |
| 1183 This is how we keep track of which mode matched, and what type of rule | |
| 1184 (`illegal`, `begin`, end, etc). | |
| 1185 */ | |
| 1186 class MultiRegex { | |
| 1187 constructor() { | |
| 1188 this.matchIndexes = {}; | |
| 1189 // @ts-ignore | |
| 1190 this.regexes = []; | |
| 1191 this.matchAt = 1; | |
| 1192 this.position = 0; | |
| 1193 } | |
| 1194 | |
| 1195 // @ts-ignore | |
| 1196 addRule(re, opts) { | |
| 1197 opts.position = this.position++; | |
| 1198 // @ts-ignore | |
| 1199 this.matchIndexes[this.matchAt] = opts; | |
| 1200 this.regexes.push([opts, re]); | |
| 1201 this.matchAt += countMatchGroups(re) + 1; | |
| 1202 } | |
| 1203 | |
| 1204 compile() { | |
| 1205 if (this.regexes.length === 0) { | |
| 1206 // avoids the need to check length every time exec is called | |
| 1207 // @ts-ignore | |
| 1208 this.exec = () => null; | |
| 1209 } | |
| 1210 const terminators = this.regexes.map(el => el[1]); | |
| 1211 this.matcherRe = langRe(_rewriteBackreferences(terminators, { joinWith: '|' }), true); | |
| 1212 this.lastIndex = 0; | |
| 1213 } | |
| 1214 | |
| 1215 /** @param {string} s */ | |
| 1216 exec(s) { | |
| 1217 this.matcherRe.lastIndex = this.lastIndex; | |
| 1218 const match = this.matcherRe.exec(s); | |
| 1219 if (!match) { return null; } | |
| 1220 | |
| 1221 // eslint-disable-next-line no-undefined | |
| 1222 const i = match.findIndex((el, i) => i > 0 && el !== undefined); | |
| 1223 // @ts-ignore | |
| 1224 const matchData = this.matchIndexes[i]; | |
| 1225 // trim off any earlier non-relevant match groups (ie, the other regex | |
| 1226 // match groups that make up the multi-matcher) | |
| 1227 match.splice(0, i); | |
| 1228 | |
| 1229 return Object.assign(match, matchData); | |
| 1230 } | |
| 1231 } | |
| 1232 | |
| 1233 /* | |
| 1234 Created to solve the key deficiently with MultiRegex - there is no way to | |
| 1235 test for multiple matches at a single location. Why would we need to do | |
| 1236 that? In the future a more dynamic engine will allow certain matches to be | |
| 1237 ignored. An example: if we matched say the 3rd regex in a large group but | |
| 1238 decided to ignore it - we'd need to started testing again at the 4th | |
| 1239 regex... but MultiRegex itself gives us no real way to do that. | |
| 1240 | |
| 1241 So what this class creates MultiRegexs on the fly for whatever search | |
| 1242 position they are needed. | |
| 1243 | |
| 1244 NOTE: These additional MultiRegex objects are created dynamically. For most | |
| 1245 grammars most of the time we will never actually need anything more than the | |
| 1246 first MultiRegex - so this shouldn't have too much overhead. | |
| 1247 | |
| 1248 Say this is our search group, and we match regex3, but wish to ignore it. | |
| 1249 | |
| 1250 regex1 | regex2 | regex3 | regex4 | regex5 ' ie, startAt = 0 | |
| 1251 | |
| 1252 What we need is a new MultiRegex that only includes the remaining | |
| 1253 possibilities: | |
| 1254 | |
| 1255 regex4 | regex5 ' ie, startAt = 3 | |
| 1256 | |
| 1257 This class wraps all that complexity up in a simple API... `startAt` decides | |
| 1258 where in the array of expressions to start doing the matching. It | |
| 1259 auto-increments, so if a match is found at position 2, then startAt will be | |
| 1260 set to 3. If the end is reached startAt will return to 0. | |
| 1261 | |
| 1262 MOST of the time the parser will be setting startAt manually to 0. | |
| 1263 */ | |
| 1264 class ResumableMultiRegex { | |
| 1265 constructor() { | |
| 1266 // @ts-ignore | |
| 1267 this.rules = []; | |
| 1268 // @ts-ignore | |
| 1269 this.multiRegexes = []; | |
| 1270 this.count = 0; | |
| 1271 | |
| 1272 this.lastIndex = 0; | |
| 1273 this.regexIndex = 0; | |
| 1274 } | |
| 1275 | |
| 1276 // @ts-ignore | |
| 1277 getMatcher(index) { | |
| 1278 if (this.multiRegexes[index]) return this.multiRegexes[index]; | |
| 1279 | |
| 1280 const matcher = new MultiRegex(); | |
| 1281 this.rules.slice(index).forEach(([re, opts]) => matcher.addRule(re, opts)); | |
| 1282 matcher.compile(); | |
| 1283 this.multiRegexes[index] = matcher; | |
| 1284 return matcher; | |
| 1285 } | |
| 1286 | |
| 1287 resumingScanAtSamePosition() { | |
| 1288 return this.regexIndex !== 0; | |
| 1289 } | |
| 1290 | |
| 1291 considerAll() { | |
| 1292 this.regexIndex = 0; | |
| 1293 } | |
| 1294 | |
| 1295 // @ts-ignore | |
| 1296 addRule(re, opts) { | |
| 1297 this.rules.push([re, opts]); | |
| 1298 if (opts.type === "begin") this.count++; | |
| 1299 } | |
| 1300 | |
| 1301 /** @param {string} s */ | |
| 1302 exec(s) { | |
| 1303 const m = this.getMatcher(this.regexIndex); | |
| 1304 m.lastIndex = this.lastIndex; | |
| 1305 let result = m.exec(s); | |
| 1306 | |
| 1307 // The following is because we have no easy way to say "resume scanning at the | |
| 1308 // existing position but also skip the current rule ONLY". What happens is | |
| 1309 // all prior rules are also skipped which can result in matching the wrong | |
| 1310 // thing. Example of matching "booger": | |
| 1311 | |
| 1312 // our matcher is [string, "booger", number] | |
| 1313 // | |
| 1314 // ....booger.... | |
| 1315 | |
| 1316 // if "booger" is ignored then we'd really need a regex to scan from the | |
| 1317 // SAME position for only: [string, number] but ignoring "booger" (if it | |
| 1318 // was the first match), a simple resume would scan ahead who knows how | |
| 1319 // far looking only for "number", ignoring potential string matches (or | |
| 1320 // future "booger" matches that might be valid.) | |
| 1321 | |
| 1322 // So what we do: We execute two matchers, one resuming at the same | |
| 1323 // position, but the second full matcher starting at the position after: | |
| 1324 | |
| 1325 // /--- resume first regex match here (for [number]) | |
| 1326 // |/---- full match here for [string, "booger", number] | |
| 1327 // vv | |
| 1328 // ....booger.... | |
| 1329 | |
| 1330 // Which ever results in a match first is then used. So this 3-4 step | |
| 1331 // process essentially allows us to say "match at this position, excluding | |
| 1332 // a prior rule that was ignored". | |
| 1333 // | |
| 1334 // 1. Match "booger" first, ignore. Also proves that [string] does non match. | |
| 1335 // 2. Resume matching for [number] | |
| 1336 // 3. Match at index + 1 for [string, "booger", number] | |
| 1337 // 4. If #2 and #3 result in matches, which came first? | |
| 1338 if (this.resumingScanAtSamePosition()) { | |
| 1339 if (result && result.index === this.lastIndex) ; else { // use the second matcher result | |
| 1340 const m2 = this.getMatcher(0); | |
| 1341 m2.lastIndex = this.lastIndex + 1; | |
| 1342 result = m2.exec(s); | |
| 1343 } | |
| 1344 } | |
| 1345 | |
| 1346 if (result) { | |
| 1347 this.regexIndex += result.position + 1; | |
| 1348 if (this.regexIndex === this.count) { | |
| 1349 // wrap-around to considering all matches again | |
| 1350 this.considerAll(); | |
| 1351 } | |
| 1352 } | |
| 1353 | |
| 1354 return result; | |
| 1355 } | |
| 1356 } | |
| 1357 | |
| 1358 /** | |
| 1359 * Given a mode, builds a huge ResumableMultiRegex that can be used to walk | |
| 1360 * the content and find matches. | |
| 1361 * | |
| 1362 * @param {CompiledMode} mode | |
| 1363 * @returns {ResumableMultiRegex} | |
| 1364 */ | |
| 1365 function buildModeRegex(mode) { | |
| 1366 const mm = new ResumableMultiRegex(); | |
| 1367 | |
| 1368 mode.contains.forEach(term => mm.addRule(term.begin, { rule: term, type: "begin" })); | |
| 1369 | |
| 1370 if (mode.terminatorEnd) { | |
| 1371 mm.addRule(mode.terminatorEnd, { type: "end" }); | |
| 1372 } | |
| 1373 if (mode.illegal) { | |
| 1374 mm.addRule(mode.illegal, { type: "illegal" }); | |
| 1375 } | |
| 1376 | |
| 1377 return mm; | |
| 1378 } | |
| 1379 | |
| 1380 /** skip vs abort vs ignore | |
| 1381 * | |
| 1382 * @skip - The mode is still entered and exited normally (and contains rules apply), | |
| 1383 * but all content is held and added to the parent buffer rather than being | |
| 1384 * output when the mode ends. Mostly used with `sublanguage` to build up | |
| 1385 * a single large buffer than can be parsed by sublanguage. | |
| 1386 * | |
| 1387 * - The mode begin ands ends normally. | |
| 1388 * - Content matched is added to the parent mode buffer. | |
| 1389 * - The parser cursor is moved forward normally. | |
| 1390 * | |
| 1391 * @abort - A hack placeholder until we have ignore. Aborts the mode (as if it | |
| 1392 * never matched) but DOES NOT continue to match subsequent `contains` | |
| 1393 * modes. Abort is bad/suboptimal because it can result in modes | |
| 1394 * farther down not getting applied because an earlier rule eats the | |
| 1395 * content but then aborts. | |
| 1396 * | |
| 1397 * - The mode does not begin. | |
| 1398 * - Content matched by `begin` is added to the mode buffer. | |
| 1399 * - The parser cursor is moved forward accordingly. | |
| 1400 * | |
| 1401 * @ignore - Ignores the mode (as if it never matched) and continues to match any | |
| 1402 * subsequent `contains` modes. Ignore isn't technically possible with | |
| 1403 * the current parser implementation. | |
| 1404 * | |
| 1405 * - The mode does not begin. | |
| 1406 * - Content matched by `begin` is ignored. | |
| 1407 * - The parser cursor is not moved forward. | |
| 1408 */ | |
| 1409 | |
| 1410 /** | |
| 1411 * Compiles an individual mode | |
| 1412 * | |
| 1413 * This can raise an error if the mode contains certain detectable known logic | |
| 1414 * issues. | |
| 1415 * @param {Mode} mode | |
| 1416 * @param {CompiledMode | null} [parent] | |
| 1417 * @returns {CompiledMode | never} | |
| 1418 */ | |
| 1419 function compileMode(mode, parent) { | |
| 1420 const cmode = /** @type CompiledMode */ (mode); | |
| 1421 if (mode.isCompiled) return cmode; | |
| 1422 | |
| 1423 [ | |
| 1424 scopeClassName, | |
| 1425 // do this early so compiler extensions generally don't have to worry about | |
| 1426 // the distinction between match/begin | |
| 1427 compileMatch, | |
| 1428 MultiClass, | |
| 1429 beforeMatchExt | |
| 1430 ].forEach(ext => ext(mode, parent)); | |
| 1431 | |
| 1432 language.compilerExtensions.forEach(ext => ext(mode, parent)); | |
| 1433 | |
| 1434 // __beforeBegin is considered private API, internal use only | |
| 1435 mode.__beforeBegin = null; | |
| 1436 | |
| 1437 [ | |
| 1438 beginKeywords, | |
| 1439 // do this later so compiler extensions that come earlier have access to the | |
| 1440 // raw array if they wanted to perhaps manipulate it, etc. | |
| 1441 compileIllegal, | |
| 1442 // default to 1 relevance if not specified | |
| 1443 compileRelevance | |
| 1444 ].forEach(ext => ext(mode, parent)); | |
| 1445 | |
| 1446 mode.isCompiled = true; | |
| 1447 | |
| 1448 let keywordPattern = null; | |
| 1449 if (typeof mode.keywords === "object" && mode.keywords.$pattern) { | |
| 1450 // we need a copy because keywords might be compiled multiple times | |
| 1451 // so we can't go deleting $pattern from the original on the first | |
| 1452 // pass | |
| 1453 mode.keywords = Object.assign({}, mode.keywords); | |
| 1454 keywordPattern = mode.keywords.$pattern; | |
| 1455 delete mode.keywords.$pattern; | |
| 1456 } | |
| 1457 keywordPattern = keywordPattern || /\w+/; | |
| 1458 | |
| 1459 if (mode.keywords) { | |
| 1460 mode.keywords = compileKeywords(mode.keywords, language.case_insensitive); | |
| 1461 } | |
| 1462 | |
| 1463 cmode.keywordPatternRe = langRe(keywordPattern, true); | |
| 1464 | |
| 1465 if (parent) { | |
| 1466 if (!mode.begin) mode.begin = /\B|\b/; | |
| 1467 cmode.beginRe = langRe(cmode.begin); | |
| 1468 if (!mode.end && !mode.endsWithParent) mode.end = /\B|\b/; | |
| 1469 if (mode.end) cmode.endRe = langRe(cmode.end); | |
| 1470 cmode.terminatorEnd = source(cmode.end) || ''; | |
| 1471 if (mode.endsWithParent && parent.terminatorEnd) { | |
| 1472 cmode.terminatorEnd += (mode.end ? '|' : '') + parent.terminatorEnd; | |
| 1473 } | |
| 1474 } | |
| 1475 if (mode.illegal) cmode.illegalRe = langRe(/** @type {RegExp | string} */ (mode.illegal)); | |
| 1476 if (!mode.contains) mode.contains = []; | |
| 1477 | |
| 1478 mode.contains = [].concat(...mode.contains.map(function(c) { | |
| 1479 return expandOrCloneMode(c === 'self' ? mode : c); | |
| 1480 })); | |
| 1481 mode.contains.forEach(function(c) { compileMode(/** @type Mode */ (c), cmode); }); | |
| 1482 | |
| 1483 if (mode.starts) { | |
| 1484 compileMode(mode.starts, parent); | |
| 1485 } | |
| 1486 | |
| 1487 cmode.matcher = buildModeRegex(cmode); | |
| 1488 return cmode; | |
| 1489 } | |
| 1490 | |
| 1491 if (!language.compilerExtensions) language.compilerExtensions = []; | |
| 1492 | |
| 1493 // self is not valid at the top-level | |
| 1494 if (language.contains && language.contains.includes('self')) { | |
| 1495 throw new Error("ERR: contains `self` is not supported at the top-level of a language. See documentation."); | |
| 1496 } | |
| 1497 | |
| 1498 // we need a null object, which inherit will guarantee | |
| 1499 language.classNameAliases = inherit$1(language.classNameAliases || {}); | |
| 1500 | |
| 1501 return compileMode(/** @type Mode */ (language)); | |
| 1502 } | |
| 1503 | |
| 1504 /** | |
| 1505 * Determines if a mode has a dependency on it's parent or not | |
| 1506 * | |
| 1507 * If a mode does have a parent dependency then often we need to clone it if | |
| 1508 * it's used in multiple places so that each copy points to the correct parent, | |
| 1509 * where-as modes without a parent can often safely be re-used at the bottom of | |
| 1510 * a mode chain. | |
| 1511 * | |
| 1512 * @param {Mode | null} mode | |
| 1513 * @returns {boolean} - is there a dependency on the parent? | |
| 1514 * */ | |
| 1515 function dependencyOnParent(mode) { | |
| 1516 if (!mode) return false; | |
| 1517 | |
| 1518 return mode.endsWithParent || dependencyOnParent(mode.starts); | |
| 1519 } | |
| 1520 | |
| 1521 /** | |
| 1522 * Expands a mode or clones it if necessary | |
| 1523 * | |
| 1524 * This is necessary for modes with parental dependenceis (see notes on | |
| 1525 * `dependencyOnParent`) and for nodes that have `variants` - which must then be | |
| 1526 * exploded into their own individual modes at compile time. | |
| 1527 * | |
| 1528 * @param {Mode} mode | |
| 1529 * @returns {Mode | Mode[]} | |
| 1530 * */ | |
| 1531 function expandOrCloneMode(mode) { | |
| 1532 if (mode.variants && !mode.cachedVariants) { | |
| 1533 mode.cachedVariants = mode.variants.map(function(variant) { | |
| 1534 return inherit$1(mode, { variants: null }, variant); | |
| 1535 }); | |
| 1536 } | |
| 1537 | |
| 1538 // EXPAND | |
| 1539 // if we have variants then essentially "replace" the mode with the variants | |
| 1540 // this happens in compileMode, where this function is called from | |
| 1541 if (mode.cachedVariants) { | |
| 1542 return mode.cachedVariants; | |
| 1543 } | |
| 1544 | |
| 1545 // CLONE | |
| 1546 // if we have dependencies on parents then we need a unique | |
| 1547 // instance of ourselves, so we can be reused with many | |
| 1548 // different parents without issue | |
| 1549 if (dependencyOnParent(mode)) { | |
| 1550 return inherit$1(mode, { starts: mode.starts ? inherit$1(mode.starts) : null }); | |
| 1551 } | |
| 1552 | |
| 1553 if (Object.isFrozen(mode)) { | |
| 1554 return inherit$1(mode); | |
| 1555 } | |
| 1556 | |
| 1557 // no special dependency issues, just return ourselves | |
| 1558 return mode; | |
| 1559 } | |
| 1560 | |
| 1561 var version = "11.11.1"; | |
| 1562 | |
| 1563 class HTMLInjectionError extends Error { | |
| 1564 constructor(reason, html) { | |
| 1565 super(reason); | |
| 1566 this.name = "HTMLInjectionError"; | |
| 1567 this.html = html; | |
| 1568 } | |
| 1569 } | |
| 1570 | |
| 1571 /* | |
| 1572 Syntax highlighting with language autodetection. | |
| 1573 https://highlightjs.org/ | |
| 1574 */ | |
| 1575 | |
| 1576 | |
| 1577 | |
| 1578 /** | |
| 1579 @typedef {import('highlight.js').Mode} Mode | |
| 1580 @typedef {import('highlight.js').CompiledMode} CompiledMode | |
| 1581 @typedef {import('highlight.js').CompiledScope} CompiledScope | |
| 1582 @typedef {import('highlight.js').Language} Language | |
| 1583 @typedef {import('highlight.js').HLJSApi} HLJSApi | |
| 1584 @typedef {import('highlight.js').HLJSPlugin} HLJSPlugin | |
| 1585 @typedef {import('highlight.js').PluginEvent} PluginEvent | |
| 1586 @typedef {import('highlight.js').HLJSOptions} HLJSOptions | |
| 1587 @typedef {import('highlight.js').LanguageFn} LanguageFn | |
| 1588 @typedef {import('highlight.js').HighlightedHTMLElement} HighlightedHTMLElement | |
| 1589 @typedef {import('highlight.js').BeforeHighlightContext} BeforeHighlightContext | |
| 1590 @typedef {import('highlight.js/private').MatchType} MatchType | |
| 1591 @typedef {import('highlight.js/private').KeywordData} KeywordData | |
| 1592 @typedef {import('highlight.js/private').EnhancedMatch} EnhancedMatch | |
| 1593 @typedef {import('highlight.js/private').AnnotatedError} AnnotatedError | |
| 1594 @typedef {import('highlight.js').AutoHighlightResult} AutoHighlightResult | |
| 1595 @typedef {import('highlight.js').HighlightOptions} HighlightOptions | |
| 1596 @typedef {import('highlight.js').HighlightResult} HighlightResult | |
| 1597 */ | |
| 1598 | |
| 1599 | |
| 1600 const escape = escapeHTML; | |
| 1601 const inherit = inherit$1; | |
| 1602 const NO_MATCH = Symbol("nomatch"); | |
| 1603 const MAX_KEYWORD_HITS = 7; | |
| 1604 | |
| 1605 /** | |
| 1606 * @param {any} hljs - object that is extended (legacy) | |
| 1607 * @returns {HLJSApi} | |
| 1608 */ | |
| 1609 const HLJS = function(hljs) { | |
| 1610 // Global internal variables used within the highlight.js library. | |
| 1611 /** @type {Record<string, Language>} */ | |
| 1612 const languages = Object.create(null); | |
| 1613 /** @type {Record<string, string>} */ | |
| 1614 const aliases = Object.create(null); | |
| 1615 /** @type {HLJSPlugin[]} */ | |
| 1616 const plugins = []; | |
| 1617 | |
| 1618 // safe/production mode - swallows more errors, tries to keep running | |
| 1619 // even if a single syntax or parse hits a fatal error | |
| 1620 let SAFE_MODE = true; | |
| 1621 const LANGUAGE_NOT_FOUND = "Could not find the language '{}', did you forget to load/include a language module?"; | |
| 1622 /** @type {Language} */ | |
| 1623 const PLAINTEXT_LANGUAGE = { disableAutodetect: true, name: 'Plain text', contains: [] }; | |
| 1624 | |
| 1625 // Global options used when within external APIs. This is modified when | |
| 1626 // calling the `hljs.configure` function. | |
| 1627 /** @type HLJSOptions */ | |
| 1628 let options = { | |
| 1629 ignoreUnescapedHTML: false, | |
| 1630 throwUnescapedHTML: false, | |
| 1631 noHighlightRe: /^(no-?highlight)$/i, | |
| 1632 languageDetectRe: /\blang(?:uage)?-([\w-]+)\b/i, | |
| 1633 classPrefix: 'hljs-', | |
| 1634 cssSelector: 'pre code', | |
| 1635 languages: null, | |
| 1636 // beta configuration options, subject to change, welcome to discuss | |
| 1637 // https://github.com/highlightjs/highlight.js/issues/1086 | |
| 1638 __emitter: TokenTreeEmitter | |
| 1639 }; | |
| 1640 | |
| 1641 /* Utility functions */ | |
| 1642 | |
| 1643 /** | |
| 1644 * Tests a language name to see if highlighting should be skipped | |
| 1645 * @param {string} languageName | |
| 1646 */ | |
| 1647 function shouldNotHighlight(languageName) { | |
| 1648 return options.noHighlightRe.test(languageName); | |
| 1649 } | |
| 1650 | |
| 1651 /** | |
| 1652 * @param {HighlightedHTMLElement} block - the HTML element to determine language for | |
| 1653 */ | |
| 1654 function blockLanguage(block) { | |
| 1655 let classes = block.className + ' '; | |
| 1656 | |
| 1657 classes += block.parentNode ? block.parentNode.className : ''; | |
| 1658 | |
| 1659 // language-* takes precedence over non-prefixed class names. | |
| 1660 const match = options.languageDetectRe.exec(classes); | |
| 1661 if (match) { | |
| 1662 const language = getLanguage(match[1]); | |
| 1663 if (!language) { | |
| 1664 warn(LANGUAGE_NOT_FOUND.replace("{}", match[1])); | |
| 1665 warn("Falling back to no-highlight mode for this block.", block); | |
| 1666 } | |
| 1667 return language ? match[1] : 'no-highlight'; | |
| 1668 } | |
| 1669 | |
| 1670 return classes | |
| 1671 .split(/\s+/) | |
| 1672 .find((_class) => shouldNotHighlight(_class) || getLanguage(_class)); | |
| 1673 } | |
| 1674 | |
| 1675 /** | |
| 1676 * Core highlighting function. | |
| 1677 * | |
| 1678 * OLD API | |
| 1679 * highlight(lang, code, ignoreIllegals, continuation) | |
| 1680 * | |
| 1681 * NEW API | |
| 1682 * highlight(code, {lang, ignoreIllegals}) | |
| 1683 * | |
| 1684 * @param {string} codeOrLanguageName - the language to use for highlighting | |
| 1685 * @param {string | HighlightOptions} optionsOrCode - the code to highlight | |
| 1686 * @param {boolean} [ignoreIllegals] - whether to ignore illegal matches, default is to bail | |
| 1687 * | |
| 1688 * @returns {HighlightResult} Result - an object that represents the result | |
| 1689 * @property {string} language - the language name | |
| 1690 * @property {number} relevance - the relevance score | |
| 1691 * @property {string} value - the highlighted HTML code | |
| 1692 * @property {string} code - the original raw code | |
| 1693 * @property {CompiledMode} top - top of the current mode stack | |
| 1694 * @property {boolean} illegal - indicates whether any illegal matches were found | |
| 1695 */ | |
| 1696 function highlight(codeOrLanguageName, optionsOrCode, ignoreIllegals) { | |
| 1697 let code = ""; | |
| 1698 let languageName = ""; | |
| 1699 if (typeof optionsOrCode === "object") { | |
| 1700 code = codeOrLanguageName; | |
| 1701 ignoreIllegals = optionsOrCode.ignoreIllegals; | |
| 1702 languageName = optionsOrCode.language; | |
| 1703 } else { | |
| 1704 // old API | |
| 1705 deprecated("10.7.0", "highlight(lang, code, ...args) has been deprecated."); | |
| 1706 deprecated("10.7.0", "Please use highlight(code, options) instead.\nhttps://github.com/highlightjs/highlight.js/issues/2277"); | |
| 1707 languageName = codeOrLanguageName; | |
| 1708 code = optionsOrCode; | |
| 1709 } | |
| 1710 | |
| 1711 // https://github.com/highlightjs/highlight.js/issues/3149 | |
| 1712 // eslint-disable-next-line no-undefined | |
| 1713 if (ignoreIllegals === undefined) { ignoreIllegals = true; } | |
| 1714 | |
| 1715 /** @type {BeforeHighlightContext} */ | |
| 1716 const context = { | |
| 1717 code, | |
| 1718 language: languageName | |
| 1719 }; | |
| 1720 // the plugin can change the desired language or the code to be highlighted | |
| 1721 // just be changing the object it was passed | |
| 1722 fire("before:highlight", context); | |
| 1723 | |
| 1724 // a before plugin can usurp the result completely by providing it's own | |
| 1725 // in which case we don't even need to call highlight | |
| 1726 const result = context.result | |
| 1727 ? context.result | |
| 1728 : _highlight(context.language, context.code, ignoreIllegals); | |
| 1729 | |
| 1730 result.code = context.code; | |
| 1731 // the plugin can change anything in result to suite it | |
| 1732 fire("after:highlight", result); | |
| 1733 | |
| 1734 return result; | |
| 1735 } | |
| 1736 | |
| 1737 /** | |
| 1738 * private highlight that's used internally and does not fire callbacks | |
| 1739 * | |
| 1740 * @param {string} languageName - the language to use for highlighting | |
| 1741 * @param {string} codeToHighlight - the code to highlight | |
| 1742 * @param {boolean?} [ignoreIllegals] - whether to ignore illegal matches, default is to bail | |
| 1743 * @param {CompiledMode?} [continuation] - current continuation mode, if any | |
| 1744 * @returns {HighlightResult} - result of the highlight operation | |
| 1745 */ | |
| 1746 function _highlight(languageName, codeToHighlight, ignoreIllegals, continuation) { | |
| 1747 const keywordHits = Object.create(null); | |
| 1748 | |
| 1749 /** | |
| 1750 * Return keyword data if a match is a keyword | |
| 1751 * @param {CompiledMode} mode - current mode | |
| 1752 * @param {string} matchText - the textual match | |
| 1753 * @returns {KeywordData | false} | |
| 1754 */ | |
| 1755 function keywordData(mode, matchText) { | |
| 1756 return mode.keywords[matchText]; | |
| 1757 } | |
| 1758 | |
| 1759 function processKeywords() { | |
| 1760 if (!top.keywords) { | |
| 1761 emitter.addText(modeBuffer); | |
| 1762 return; | |
| 1763 } | |
| 1764 | |
| 1765 let lastIndex = 0; | |
| 1766 top.keywordPatternRe.lastIndex = 0; | |
| 1767 let match = top.keywordPatternRe.exec(modeBuffer); | |
| 1768 let buf = ""; | |
| 1769 | |
| 1770 while (match) { | |
| 1771 buf += modeBuffer.substring(lastIndex, match.index); | |
| 1772 const word = language.case_insensitive ? match[0].toLowerCase() : match[0]; | |
| 1773 const data = keywordData(top, word); | |
| 1774 if (data) { | |
| 1775 const [kind, keywordRelevance] = data; | |
| 1776 emitter.addText(buf); | |
| 1777 buf = ""; | |
| 1778 | |
| 1779 keywordHits[word] = (keywordHits[word] || 0) + 1; | |
| 1780 if (keywordHits[word] <= MAX_KEYWORD_HITS) relevance += keywordRelevance; | |
| 1781 if (kind.startsWith("_")) { | |
| 1782 // _ implied for relevance only, do not highlight | |
| 1783 // by applying a class name | |
| 1784 buf += match[0]; | |
| 1785 } else { | |
| 1786 const cssClass = language.classNameAliases[kind] || kind; | |
| 1787 emitKeyword(match[0], cssClass); | |
| 1788 } | |
| 1789 } else { | |
| 1790 buf += match[0]; | |
| 1791 } | |
| 1792 lastIndex = top.keywordPatternRe.lastIndex; | |
| 1793 match = top.keywordPatternRe.exec(modeBuffer); | |
| 1794 } | |
| 1795 buf += modeBuffer.substring(lastIndex); | |
| 1796 emitter.addText(buf); | |
| 1797 } | |
| 1798 | |
| 1799 function processSubLanguage() { | |
| 1800 if (modeBuffer === "") return; | |
| 1801 /** @type HighlightResult */ | |
| 1802 let result = null; | |
| 1803 | |
| 1804 if (typeof top.subLanguage === 'string') { | |
| 1805 if (!languages[top.subLanguage]) { | |
| 1806 emitter.addText(modeBuffer); | |
| 1807 return; | |
| 1808 } | |
| 1809 result = _highlight(top.subLanguage, modeBuffer, true, continuations[top.subLanguage]); | |
| 1810 continuations[top.subLanguage] = /** @type {CompiledMode} */ (result._top); | |
| 1811 } else { | |
| 1812 result = highlightAuto(modeBuffer, top.subLanguage.length ? top.subLanguage : null); | |
| 1813 } | |
| 1814 | |
| 1815 // Counting embedded language score towards the host language may be disabled | |
| 1816 // with zeroing the containing mode relevance. Use case in point is Markdown that | |
| 1817 // allows XML everywhere and makes every XML snippet to have a much larger Markdown | |
| 1818 // score. | |
| 1819 if (top.relevance > 0) { | |
| 1820 relevance += result.relevance; | |
| 1821 } | |
| 1822 emitter.__addSublanguage(result._emitter, result.language); | |
| 1823 } | |
| 1824 | |
| 1825 function processBuffer() { | |
| 1826 if (top.subLanguage != null) { | |
| 1827 processSubLanguage(); | |
| 1828 } else { | |
| 1829 processKeywords(); | |
| 1830 } | |
| 1831 modeBuffer = ''; | |
| 1832 } | |
| 1833 | |
| 1834 /** | |
| 1835 * @param {string} text | |
| 1836 * @param {string} scope | |
| 1837 */ | |
| 1838 function emitKeyword(keyword, scope) { | |
| 1839 if (keyword === "") return; | |
| 1840 | |
| 1841 emitter.startScope(scope); | |
| 1842 emitter.addText(keyword); | |
| 1843 emitter.endScope(); | |
| 1844 } | |
| 1845 | |
| 1846 /** | |
| 1847 * @param {CompiledScope} scope | |
| 1848 * @param {RegExpMatchArray} match | |
| 1849 */ | |
| 1850 function emitMultiClass(scope, match) { | |
| 1851 let i = 1; | |
| 1852 const max = match.length - 1; | |
| 1853 while (i <= max) { | |
| 1854 if (!scope._emit[i]) { i++; continue; } | |
| 1855 const klass = language.classNameAliases[scope[i]] || scope[i]; | |
| 1856 const text = match[i]; | |
| 1857 if (klass) { | |
| 1858 emitKeyword(text, klass); | |
| 1859 } else { | |
| 1860 modeBuffer = text; | |
| 1861 processKeywords(); | |
| 1862 modeBuffer = ""; | |
| 1863 } | |
| 1864 i++; | |
| 1865 } | |
| 1866 } | |
| 1867 | |
| 1868 /** | |
| 1869 * @param {CompiledMode} mode - new mode to start | |
| 1870 * @param {RegExpMatchArray} match | |
| 1871 */ | |
| 1872 function startNewMode(mode, match) { | |
| 1873 if (mode.scope && typeof mode.scope === "string") { | |
| 1874 emitter.openNode(language.classNameAliases[mode.scope] || mode.scope); | |
| 1875 } | |
| 1876 if (mode.beginScope) { | |
| 1877 // beginScope just wraps the begin match itself in a scope | |
| 1878 if (mode.beginScope._wrap) { | |
| 1879 emitKeyword(modeBuffer, language.classNameAliases[mode.beginScope._wrap] || mode.beginScope._wrap); | |
| 1880 modeBuffer = ""; | |
| 1881 } else if (mode.beginScope._multi) { | |
| 1882 // at this point modeBuffer should just be the match | |
| 1883 emitMultiClass(mode.beginScope, match); | |
| 1884 modeBuffer = ""; | |
| 1885 } | |
| 1886 } | |
| 1887 | |
| 1888 top = Object.create(mode, { parent: { value: top } }); | |
| 1889 return top; | |
| 1890 } | |
| 1891 | |
| 1892 /** | |
| 1893 * @param {CompiledMode } mode - the mode to potentially end | |
| 1894 * @param {RegExpMatchArray} match - the latest match | |
| 1895 * @param {string} matchPlusRemainder - match plus remainder of content | |
| 1896 * @returns {CompiledMode | void} - the next mode, or if void continue on in current mode | |
| 1897 */ | |
| 1898 function endOfMode(mode, match, matchPlusRemainder) { | |
| 1899 let matched = startsWith(mode.endRe, matchPlusRemainder); | |
| 1900 | |
| 1901 if (matched) { | |
| 1902 if (mode["on:end"]) { | |
| 1903 const resp = new Response(mode); | |
| 1904 mode["on:end"](match, resp); | |
| 1905 if (resp.isMatchIgnored) matched = false; | |
| 1906 } | |
| 1907 | |
| 1908 if (matched) { | |
| 1909 while (mode.endsParent && mode.parent) { | |
| 1910 mode = mode.parent; | |
| 1911 } | |
| 1912 return mode; | |
| 1913 } | |
| 1914 } | |
| 1915 // even if on:end fires an `ignore` it's still possible | |
| 1916 // that we might trigger the end node because of a parent mode | |
| 1917 if (mode.endsWithParent) { | |
| 1918 return endOfMode(mode.parent, match, matchPlusRemainder); | |
| 1919 } | |
| 1920 } | |
| 1921 | |
| 1922 /** | |
| 1923 * Handle matching but then ignoring a sequence of text | |
| 1924 * | |
| 1925 * @param {string} lexeme - string containing full match text | |
| 1926 */ | |
| 1927 function doIgnore(lexeme) { | |
| 1928 if (top.matcher.regexIndex === 0) { | |
| 1929 // no more regexes to potentially match here, so we move the cursor forward one | |
| 1930 // space | |
| 1931 modeBuffer += lexeme[0]; | |
| 1932 return 1; | |
| 1933 } else { | |
| 1934 // no need to move the cursor, we still have additional regexes to try and | |
| 1935 // match at this very spot | |
| 1936 resumeScanAtSamePosition = true; | |
| 1937 return 0; | |
| 1938 } | |
| 1939 } | |
| 1940 | |
| 1941 /** | |
| 1942 * Handle the start of a new potential mode match | |
| 1943 * | |
| 1944 * @param {EnhancedMatch} match - the current match | |
| 1945 * @returns {number} how far to advance the parse cursor | |
| 1946 */ | |
| 1947 function doBeginMatch(match) { | |
| 1948 const lexeme = match[0]; | |
| 1949 const newMode = match.rule; | |
| 1950 | |
| 1951 const resp = new Response(newMode); | |
| 1952 // first internal before callbacks, then the public ones | |
| 1953 const beforeCallbacks = [newMode.__beforeBegin, newMode["on:begin"]]; | |
| 1954 for (const cb of beforeCallbacks) { | |
| 1955 if (!cb) continue; | |
| 1956 cb(match, resp); | |
| 1957 if (resp.isMatchIgnored) return doIgnore(lexeme); | |
| 1958 } | |
| 1959 | |
| 1960 if (newMode.skip) { | |
| 1961 modeBuffer += lexeme; | |
| 1962 } else { | |
| 1963 if (newMode.excludeBegin) { | |
| 1964 modeBuffer += lexeme; | |
| 1965 } | |
| 1966 processBuffer(); | |
| 1967 if (!newMode.returnBegin && !newMode.excludeBegin) { | |
| 1968 modeBuffer = lexeme; | |
| 1969 } | |
| 1970 } | |
| 1971 startNewMode(newMode, match); | |
| 1972 return newMode.returnBegin ? 0 : lexeme.length; | |
| 1973 } | |
| 1974 | |
| 1975 /** | |
| 1976 * Handle the potential end of mode | |
| 1977 * | |
| 1978 * @param {RegExpMatchArray} match - the current match | |
| 1979 */ | |
| 1980 function doEndMatch(match) { | |
| 1981 const lexeme = match[0]; | |
| 1982 const matchPlusRemainder = codeToHighlight.substring(match.index); | |
| 1983 | |
| 1984 const endMode = endOfMode(top, match, matchPlusRemainder); | |
| 1985 if (!endMode) { return NO_MATCH; } | |
| 1986 | |
| 1987 const origin = top; | |
| 1988 if (top.endScope && top.endScope._wrap) { | |
| 1989 processBuffer(); | |
| 1990 emitKeyword(lexeme, top.endScope._wrap); | |
| 1991 } else if (top.endScope && top.endScope._multi) { | |
| 1992 processBuffer(); | |
| 1993 emitMultiClass(top.endScope, match); | |
| 1994 } else if (origin.skip) { | |
| 1995 modeBuffer += lexeme; | |
| 1996 } else { | |
| 1997 if (!(origin.returnEnd || origin.excludeEnd)) { | |
| 1998 modeBuffer += lexeme; | |
| 1999 } | |
| 2000 processBuffer(); | |
| 2001 if (origin.excludeEnd) { | |
| 2002 modeBuffer = lexeme; | |
| 2003 } | |
| 2004 } | |
| 2005 do { | |
| 2006 if (top.scope) { | |
| 2007 emitter.closeNode(); | |
| 2008 } | |
| 2009 if (!top.skip && !top.subLanguage) { | |
| 2010 relevance += top.relevance; | |
| 2011 } | |
| 2012 top = top.parent; | |
| 2013 } while (top !== endMode.parent); | |
| 2014 if (endMode.starts) { | |
| 2015 startNewMode(endMode.starts, match); | |
| 2016 } | |
| 2017 return origin.returnEnd ? 0 : lexeme.length; | |
| 2018 } | |
| 2019 | |
| 2020 function processContinuations() { | |
| 2021 const list = []; | |
| 2022 for (let current = top; current !== language; current = current.parent) { | |
| 2023 if (current.scope) { | |
| 2024 list.unshift(current.scope); | |
| 2025 } | |
| 2026 } | |
| 2027 list.forEach(item => emitter.openNode(item)); | |
| 2028 } | |
| 2029 | |
| 2030 /** @type {{type?: MatchType, index?: number, rule?: Mode}}} */ | |
| 2031 let lastMatch = {}; | |
| 2032 | |
| 2033 /** | |
| 2034 * Process an individual match | |
| 2035 * | |
| 2036 * @param {string} textBeforeMatch - text preceding the match (since the last match) | |
| 2037 * @param {EnhancedMatch} [match] - the match itself | |
| 2038 */ | |
| 2039 function processLexeme(textBeforeMatch, match) { | |
| 2040 const lexeme = match && match[0]; | |
| 2041 | |
| 2042 // add non-matched text to the current mode buffer | |
| 2043 modeBuffer += textBeforeMatch; | |
| 2044 | |
| 2045 if (lexeme == null) { | |
| 2046 processBuffer(); | |
| 2047 return 0; | |
| 2048 } | |
| 2049 | |
| 2050 // we've found a 0 width match and we're stuck, so we need to advance | |
| 2051 // this happens when we have badly behaved rules that have optional matchers to the degree that | |
| 2052 // sometimes they can end up matching nothing at all | |
| 2053 // Ref: https://github.com/highlightjs/highlight.js/issues/2140 | |
| 2054 if (lastMatch.type === "begin" && match.type === "end" && lastMatch.index === match.index && lexeme === "") { | |
| 2055 // spit the "skipped" character that our regex choked on back into the output sequence | |
| 2056 modeBuffer += codeToHighlight.slice(match.index, match.index + 1); | |
| 2057 if (!SAFE_MODE) { | |
| 2058 /** @type {AnnotatedError} */ | |
| 2059 const err = new Error(`0 width match regex (${languageName})`); | |
| 2060 err.languageName = languageName; | |
| 2061 err.badRule = lastMatch.rule; | |
| 2062 throw err; | |
| 2063 } | |
| 2064 return 1; | |
| 2065 } | |
| 2066 lastMatch = match; | |
| 2067 | |
| 2068 if (match.type === "begin") { | |
| 2069 return doBeginMatch(match); | |
| 2070 } else if (match.type === "illegal" && !ignoreIllegals) { | |
| 2071 // illegal match, we do not continue processing | |
| 2072 /** @type {AnnotatedError} */ | |
| 2073 const err = new Error('Illegal lexeme "' + lexeme + '" for mode "' + (top.scope || '<unnamed>') + '"'); | |
| 2074 err.mode = top; | |
| 2075 throw err; | |
| 2076 } else if (match.type === "end") { | |
| 2077 const processed = doEndMatch(match); | |
| 2078 if (processed !== NO_MATCH) { | |
| 2079 return processed; | |
| 2080 } | |
| 2081 } | |
| 2082 | |
| 2083 // edge case for when illegal matches $ (end of line) which is technically | |
| 2084 // a 0 width match but not a begin/end match so it's not caught by the | |
| 2085 // first handler (when ignoreIllegals is true) | |
| 2086 if (match.type === "illegal" && lexeme === "") { | |
| 2087 // advance so we aren't stuck in an infinite loop | |
| 2088 modeBuffer += "\n"; | |
| 2089 return 1; | |
| 2090 } | |
| 2091 | |
| 2092 // infinite loops are BAD, this is a last ditch catch all. if we have a | |
| 2093 // decent number of iterations yet our index (cursor position in our | |
| 2094 // parsing) still 3x behind our index then something is very wrong | |
| 2095 // so we bail | |
| 2096 if (iterations > 100000 && iterations > match.index * 3) { | |
| 2097 const err = new Error('potential infinite loop, way more iterations than matches'); | |
| 2098 throw err; | |
| 2099 } | |
| 2100 | |
| 2101 /* | |
| 2102 Why might be find ourselves here? An potential end match that was | |
| 2103 triggered but could not be completed. IE, `doEndMatch` returned NO_MATCH. | |
| 2104 (this could be because a callback requests the match be ignored, etc) | |
| 2105 | |
| 2106 This causes no real harm other than stopping a few times too many. | |
| 2107 */ | |
| 2108 | |
| 2109 modeBuffer += lexeme; | |
| 2110 return lexeme.length; | |
| 2111 } | |
| 2112 | |
| 2113 const language = getLanguage(languageName); | |
| 2114 if (!language) { | |
| 2115 error(LANGUAGE_NOT_FOUND.replace("{}", languageName)); | |
| 2116 throw new Error('Unknown language: "' + languageName + '"'); | |
| 2117 } | |
| 2118 | |
| 2119 const md = compileLanguage(language); | |
| 2120 let result = ''; | |
| 2121 /** @type {CompiledMode} */ | |
| 2122 let top = continuation || md; | |
| 2123 /** @type Record<string,CompiledMode> */ | |
| 2124 const continuations = {}; // keep continuations for sub-languages | |
| 2125 const emitter = new options.__emitter(options); | |
| 2126 processContinuations(); | |
| 2127 let modeBuffer = ''; | |
| 2128 let relevance = 0; | |
| 2129 let index = 0; | |
| 2130 let iterations = 0; | |
| 2131 let resumeScanAtSamePosition = false; | |
| 2132 | |
| 2133 try { | |
| 2134 if (!language.__emitTokens) { | |
| 2135 top.matcher.considerAll(); | |
| 2136 | |
| 2137 for (;;) { | |
| 2138 iterations++; | |
| 2139 if (resumeScanAtSamePosition) { | |
| 2140 // only regexes not matched previously will now be | |
| 2141 // considered for a potential match | |
| 2142 resumeScanAtSamePosition = false; | |
| 2143 } else { | |
| 2144 top.matcher.considerAll(); | |
| 2145 } | |
| 2146 top.matcher.lastIndex = index; | |
| 2147 | |
| 2148 const match = top.matcher.exec(codeToHighlight); | |
| 2149 // console.log("match", match[0], match.rule && match.rule.begin) | |
| 2150 | |
| 2151 if (!match) break; | |
| 2152 | |
| 2153 const beforeMatch = codeToHighlight.substring(index, match.index); | |
| 2154 const processedCount = processLexeme(beforeMatch, match); | |
| 2155 index = match.index + processedCount; | |
| 2156 } | |
| 2157 processLexeme(codeToHighlight.substring(index)); | |
| 2158 } else { | |
| 2159 language.__emitTokens(codeToHighlight, emitter); | |
| 2160 } | |
| 2161 | |
| 2162 emitter.finalize(); | |
| 2163 result = emitter.toHTML(); | |
| 2164 | |
| 2165 return { | |
| 2166 language: languageName, | |
| 2167 value: result, | |
| 2168 relevance, | |
| 2169 illegal: false, | |
| 2170 _emitter: emitter, | |
| 2171 _top: top | |
| 2172 }; | |
| 2173 } catch (err) { | |
| 2174 if (err.message && err.message.includes('Illegal')) { | |
| 2175 return { | |
| 2176 language: languageName, | |
| 2177 value: escape(codeToHighlight), | |
| 2178 illegal: true, | |
| 2179 relevance: 0, | |
| 2180 _illegalBy: { | |
| 2181 message: err.message, | |
| 2182 index, | |
| 2183 context: codeToHighlight.slice(index - 100, index + 100), | |
| 2184 mode: err.mode, | |
| 2185 resultSoFar: result | |
| 2186 }, | |
| 2187 _emitter: emitter | |
| 2188 }; | |
| 2189 } else if (SAFE_MODE) { | |
| 2190 return { | |
| 2191 language: languageName, | |
| 2192 value: escape(codeToHighlight), | |
| 2193 illegal: false, | |
| 2194 relevance: 0, | |
| 2195 errorRaised: err, | |
| 2196 _emitter: emitter, | |
| 2197 _top: top | |
| 2198 }; | |
| 2199 } else { | |
| 2200 throw err; | |
| 2201 } | |
| 2202 } | |
| 2203 } | |
| 2204 | |
| 2205 /** | |
| 2206 * returns a valid highlight result, without actually doing any actual work, | |
| 2207 * auto highlight starts with this and it's possible for small snippets that | |
| 2208 * auto-detection may not find a better match | |
| 2209 * @param {string} code | |
| 2210 * @returns {HighlightResult} | |
| 2211 */ | |
| 2212 function justTextHighlightResult(code) { | |
| 2213 const result = { | |
| 2214 value: escape(code), | |
| 2215 illegal: false, | |
| 2216 relevance: 0, | |
| 2217 _top: PLAINTEXT_LANGUAGE, | |
| 2218 _emitter: new options.__emitter(options) | |
| 2219 }; | |
| 2220 result._emitter.addText(code); | |
| 2221 return result; | |
| 2222 } | |
| 2223 | |
| 2224 /** | |
| 2225 Highlighting with language detection. Accepts a string with the code to | |
| 2226 highlight. Returns an object with the following properties: | |
| 2227 | |
| 2228 - language (detected language) | |
| 2229 - relevance (int) | |
| 2230 - value (an HTML string with highlighting markup) | |
| 2231 - secondBest (object with the same structure for second-best heuristically | |
| 2232 detected language, may be absent) | |
| 2233 | |
| 2234 @param {string} code | |
| 2235 @param {Array<string>} [languageSubset] | |
| 2236 @returns {AutoHighlightResult} | |
| 2237 */ | |
| 2238 function highlightAuto(code, languageSubset) { | |
| 2239 languageSubset = languageSubset || options.languages || Object.keys(languages); | |
| 2240 const plaintext = justTextHighlightResult(code); | |
| 2241 | |
| 2242 const results = languageSubset.filter(getLanguage).filter(autoDetection).map(name => | |
| 2243 _highlight(name, code, false) | |
| 2244 ); | |
| 2245 results.unshift(plaintext); // plaintext is always an option | |
| 2246 | |
| 2247 const sorted = results.sort((a, b) => { | |
| 2248 // sort base on relevance | |
| 2249 if (a.relevance !== b.relevance) return b.relevance - a.relevance; | |
| 2250 | |
| 2251 // always award the tie to the base language | |
| 2252 // ie if C++ and Arduino are tied, it's more likely to be C++ | |
| 2253 if (a.language && b.language) { | |
| 2254 if (getLanguage(a.language).supersetOf === b.language) { | |
| 2255 return 1; | |
| 2256 } else if (getLanguage(b.language).supersetOf === a.language) { | |
| 2257 return -1; | |
| 2258 } | |
| 2259 } | |
| 2260 | |
| 2261 // otherwise say they are equal, which has the effect of sorting on | |
| 2262 // relevance while preserving the original ordering - which is how ties | |
| 2263 // have historically been settled, ie the language that comes first always | |
| 2264 // wins in the case of a tie | |
| 2265 return 0; | |
| 2266 }); | |
| 2267 | |
| 2268 const [best, secondBest] = sorted; | |
| 2269 | |
| 2270 /** @type {AutoHighlightResult} */ | |
| 2271 const result = best; | |
| 2272 result.secondBest = secondBest; | |
| 2273 | |
| 2274 return result; | |
| 2275 } | |
| 2276 | |
| 2277 /** | |
| 2278 * Builds new class name for block given the language name | |
| 2279 * | |
| 2280 * @param {HTMLElement} element | |
| 2281 * @param {string} [currentLang] | |
| 2282 * @param {string} [resultLang] | |
| 2283 */ | |
| 2284 function updateClassName(element, currentLang, resultLang) { | |
| 2285 const language = (currentLang && aliases[currentLang]) || resultLang; | |
| 2286 | |
| 2287 element.classList.add("hljs"); | |
| 2288 element.classList.add(`language-${language}`); | |
| 2289 } | |
| 2290 | |
| 2291 /** | |
| 2292 * Applies highlighting to a DOM node containing code. | |
| 2293 * | |
| 2294 * @param {HighlightedHTMLElement} element - the HTML element to highlight | |
| 2295 */ | |
| 2296 function highlightElement(element) { | |
| 2297 /** @type HTMLElement */ | |
| 2298 let node = null; | |
| 2299 const language = blockLanguage(element); | |
| 2300 | |
| 2301 if (shouldNotHighlight(language)) return; | |
| 2302 | |
| 2303 fire("before:highlightElement", | |
| 2304 { el: element, language }); | |
| 2305 | |
| 2306 if (element.dataset.highlighted) { | |
| 2307 console.log("Element previously highlighted. To highlight again, first unset `dataset.highlighted`.", element); | |
| 2308 return; | |
| 2309 } | |
| 2310 | |
| 2311 // we should be all text, no child nodes (unescaped HTML) - this is possibly | |
| 2312 // an HTML injection attack - it's likely too late if this is already in | |
| 2313 // production (the code has likely already done its damage by the time | |
| 2314 // we're seeing it)... but we yell loudly about this so that hopefully it's | |
| 2315 // more likely to be caught in development before making it to production | |
| 2316 if (element.children.length > 0) { | |
| 2317 if (!options.ignoreUnescapedHTML) { | |
| 2318 console.warn("One of your code blocks includes unescaped HTML. This is a potentially serious security risk."); | |
| 2319 console.warn("https://github.com/highlightjs/highlight.js/wiki/security"); | |
| 2320 console.warn("The element with unescaped HTML:"); | |
| 2321 console.warn(element); | |
| 2322 } | |
| 2323 if (options.throwUnescapedHTML) { | |
| 2324 const err = new HTMLInjectionError( | |
| 2325 "One of your code blocks includes unescaped HTML.", | |
| 2326 element.innerHTML | |
| 2327 ); | |
| 2328 throw err; | |
| 2329 } | |
| 2330 } | |
| 2331 | |
| 2332 node = element; | |
| 2333 const text = node.textContent; | |
| 2334 const result = language ? highlight(text, { language, ignoreIllegals: true }) : highlightAuto(text); | |
| 2335 | |
| 2336 element.innerHTML = result.value; | |
| 2337 element.dataset.highlighted = "yes"; | |
| 2338 updateClassName(element, language, result.language); | |
| 2339 element.result = { | |
| 2340 language: result.language, | |
| 2341 // TODO: remove with version 11.0 | |
| 2342 re: result.relevance, | |
| 2343 relevance: result.relevance | |
| 2344 }; | |
| 2345 if (result.secondBest) { | |
| 2346 element.secondBest = { | |
| 2347 language: result.secondBest.language, | |
| 2348 relevance: result.secondBest.relevance | |
| 2349 }; | |
| 2350 } | |
| 2351 | |
| 2352 fire("after:highlightElement", { el: element, result, text }); | |
| 2353 } | |
| 2354 | |
| 2355 /** | |
| 2356 * Updates highlight.js global options with the passed options | |
| 2357 * | |
| 2358 * @param {Partial<HLJSOptions>} userOptions | |
| 2359 */ | |
| 2360 function configure(userOptions) { | |
| 2361 options = inherit(options, userOptions); | |
| 2362 } | |
| 2363 | |
| 2364 // TODO: remove v12, deprecated | |
| 2365 const initHighlighting = () => { | |
| 2366 highlightAll(); | |
| 2367 deprecated("10.6.0", "initHighlighting() deprecated. Use highlightAll() now."); | |
| 2368 }; | |
| 2369 | |
| 2370 // TODO: remove v12, deprecated | |
| 2371 function initHighlightingOnLoad() { | |
| 2372 highlightAll(); | |
| 2373 deprecated("10.6.0", "initHighlightingOnLoad() deprecated. Use highlightAll() now."); | |
| 2374 } | |
| 2375 | |
| 2376 let wantsHighlight = false; | |
| 2377 | |
| 2378 /** | |
| 2379 * auto-highlights all pre>code elements on the page | |
| 2380 */ | |
| 2381 function highlightAll() { | |
| 2382 function boot() { | |
| 2383 // if a highlight was requested before DOM was loaded, do now | |
| 2384 highlightAll(); | |
| 2385 } | |
| 2386 | |
| 2387 // if we are called too early in the loading process | |
| 2388 if (document.readyState === "loading") { | |
| 2389 // make sure the event listener is only added once | |
| 2390 if (!wantsHighlight) { | |
| 2391 window.addEventListener('DOMContentLoaded', boot, false); | |
| 2392 } | |
| 2393 wantsHighlight = true; | |
| 2394 return; | |
| 2395 } | |
| 2396 | |
| 2397 const blocks = document.querySelectorAll(options.cssSelector); | |
| 2398 blocks.forEach(highlightElement); | |
| 2399 } | |
| 2400 | |
| 2401 /** | |
| 2402 * Register a language grammar module | |
| 2403 * | |
| 2404 * @param {string} languageName | |
| 2405 * @param {LanguageFn} languageDefinition | |
| 2406 */ | |
| 2407 function registerLanguage(languageName, languageDefinition) { | |
| 2408 let lang = null; | |
| 2409 try { | |
| 2410 lang = languageDefinition(hljs); | |
| 2411 } catch (error$1) { | |
| 2412 error("Language definition for '{}' could not be registered.".replace("{}", languageName)); | |
| 2413 // hard or soft error | |
| 2414 if (!SAFE_MODE) { throw error$1; } else { error(error$1); } | |
| 2415 // languages that have serious errors are replaced with essentially a | |
| 2416 // "plaintext" stand-in so that the code blocks will still get normal | |
| 2417 // css classes applied to them - and one bad language won't break the | |
| 2418 // entire highlighter | |
| 2419 lang = PLAINTEXT_LANGUAGE; | |
| 2420 } | |
| 2421 // give it a temporary name if it doesn't have one in the meta-data | |
| 2422 if (!lang.name) lang.name = languageName; | |
| 2423 languages[languageName] = lang; | |
| 2424 lang.rawDefinition = languageDefinition.bind(null, hljs); | |
| 2425 | |
| 2426 if (lang.aliases) { | |
| 2427 registerAliases(lang.aliases, { languageName }); | |
| 2428 } | |
| 2429 } | |
| 2430 | |
| 2431 /** | |
| 2432 * Remove a language grammar module | |
| 2433 * | |
| 2434 * @param {string} languageName | |
| 2435 */ | |
| 2436 function unregisterLanguage(languageName) { | |
| 2437 delete languages[languageName]; | |
| 2438 for (const alias of Object.keys(aliases)) { | |
| 2439 if (aliases[alias] === languageName) { | |
| 2440 delete aliases[alias]; | |
| 2441 } | |
| 2442 } | |
| 2443 } | |
| 2444 | |
| 2445 /** | |
| 2446 * @returns {string[]} List of language internal names | |
| 2447 */ | |
| 2448 function listLanguages() { | |
| 2449 return Object.keys(languages); | |
| 2450 } | |
| 2451 | |
| 2452 /** | |
| 2453 * @param {string} name - name of the language to retrieve | |
| 2454 * @returns {Language | undefined} | |
| 2455 */ | |
| 2456 function getLanguage(name) { | |
| 2457 name = (name || '').toLowerCase(); | |
| 2458 return languages[name] || languages[aliases[name]]; | |
| 2459 } | |
| 2460 | |
| 2461 /** | |
| 2462 * | |
| 2463 * @param {string|string[]} aliasList - single alias or list of aliases | |
| 2464 * @param {{languageName: string}} opts | |
| 2465 */ | |
| 2466 function registerAliases(aliasList, { languageName }) { | |
| 2467 if (typeof aliasList === 'string') { | |
| 2468 aliasList = [aliasList]; | |
| 2469 } | |
| 2470 aliasList.forEach(alias => { aliases[alias.toLowerCase()] = languageName; }); | |
| 2471 } | |
| 2472 | |
| 2473 /** | |
| 2474 * Determines if a given language has auto-detection enabled | |
| 2475 * @param {string} name - name of the language | |
| 2476 */ | |
| 2477 function autoDetection(name) { | |
| 2478 const lang = getLanguage(name); | |
| 2479 return lang && !lang.disableAutodetect; | |
| 2480 } | |
| 2481 | |
| 2482 /** | |
| 2483 * Upgrades the old highlightBlock plugins to the new | |
| 2484 * highlightElement API | |
| 2485 * @param {HLJSPlugin} plugin | |
| 2486 */ | |
| 2487 function upgradePluginAPI(plugin) { | |
| 2488 // TODO: remove with v12 | |
| 2489 if (plugin["before:highlightBlock"] && !plugin["before:highlightElement"]) { | |
| 2490 plugin["before:highlightElement"] = (data) => { | |
| 2491 plugin["before:highlightBlock"]( | |
| 2492 Object.assign({ block: data.el }, data) | |
| 2493 ); | |
| 2494 }; | |
| 2495 } | |
| 2496 if (plugin["after:highlightBlock"] && !plugin["after:highlightElement"]) { | |
| 2497 plugin["after:highlightElement"] = (data) => { | |
| 2498 plugin["after:highlightBlock"]( | |
| 2499 Object.assign({ block: data.el }, data) | |
| 2500 ); | |
| 2501 }; | |
| 2502 } | |
| 2503 } | |
| 2504 | |
| 2505 /** | |
| 2506 * @param {HLJSPlugin} plugin | |
| 2507 */ | |
| 2508 function addPlugin(plugin) { | |
| 2509 upgradePluginAPI(plugin); | |
| 2510 plugins.push(plugin); | |
| 2511 } | |
| 2512 | |
| 2513 /** | |
| 2514 * @param {HLJSPlugin} plugin | |
| 2515 */ | |
| 2516 function removePlugin(plugin) { | |
| 2517 const index = plugins.indexOf(plugin); | |
| 2518 if (index !== -1) { | |
| 2519 plugins.splice(index, 1); | |
| 2520 } | |
| 2521 } | |
| 2522 | |
| 2523 /** | |
| 2524 * | |
| 2525 * @param {PluginEvent} event | |
| 2526 * @param {any} args | |
| 2527 */ | |
| 2528 function fire(event, args) { | |
| 2529 const cb = event; | |
| 2530 plugins.forEach(function(plugin) { | |
| 2531 if (plugin[cb]) { | |
| 2532 plugin[cb](args); | |
| 2533 } | |
| 2534 }); | |
| 2535 } | |
| 2536 | |
| 2537 /** | |
| 2538 * DEPRECATED | |
| 2539 * @param {HighlightedHTMLElement} el | |
| 2540 */ | |
| 2541 function deprecateHighlightBlock(el) { | |
| 2542 deprecated("10.7.0", "highlightBlock will be removed entirely in v12.0"); | |
| 2543 deprecated("10.7.0", "Please use highlightElement now."); | |
| 2544 | |
| 2545 return highlightElement(el); | |
| 2546 } | |
| 2547 | |
| 2548 /* Interface definition */ | |
| 2549 Object.assign(hljs, { | |
| 2550 highlight, | |
| 2551 highlightAuto, | |
| 2552 highlightAll, | |
| 2553 highlightElement, | |
| 2554 // TODO: Remove with v12 API | |
| 2555 highlightBlock: deprecateHighlightBlock, | |
| 2556 configure, | |
| 2557 initHighlighting, | |
| 2558 initHighlightingOnLoad, | |
| 2559 registerLanguage, | |
| 2560 unregisterLanguage, | |
| 2561 listLanguages, | |
| 2562 getLanguage, | |
| 2563 registerAliases, | |
| 2564 autoDetection, | |
| 2565 inherit, | |
| 2566 addPlugin, | |
| 2567 removePlugin | |
| 2568 }); | |
| 2569 | |
| 2570 hljs.debugMode = function() { SAFE_MODE = false; }; | |
| 2571 hljs.safeMode = function() { SAFE_MODE = true; }; | |
| 2572 hljs.versionString = version; | |
| 2573 | |
| 2574 hljs.regex = { | |
| 2575 concat: concat, | |
| 2576 lookahead: lookahead, | |
| 2577 either: either, | |
| 2578 optional: optional, | |
| 2579 anyNumberOfTimes: anyNumberOfTimes | |
| 2580 }; | |
| 2581 | |
| 2582 for (const key in MODES) { | |
| 2583 // @ts-ignore | |
| 2584 if (typeof MODES[key] === "object") { | |
| 2585 // @ts-ignore | |
| 2586 deepFreeze(MODES[key]); | |
| 2587 } | |
| 2588 } | |
| 2589 | |
| 2590 // merge all the modes/regexes into our main object | |
| 2591 Object.assign(hljs, MODES); | |
| 2592 | |
| 2593 return hljs; | |
| 2594 }; | |
| 2595 | |
| 2596 // Other names for the variable may break build script | |
| 2597 const highlight = HLJS({}); | |
| 2598 | |
| 2599 // returns a new instance of the highlighter to be used for extensions | |
| 2600 // check https://github.com/wooorm/lowlight/issues/47 | |
| 2601 highlight.newInstance = () => HLJS({}); | |
| 2602 | |
| 2603 return highlight; | |
| 2604 | |
| 2605 })(); | |
| 2606 if (typeof exports === 'object' && typeof module !== 'undefined') { module.exports = hljs; } | |
| 2607 /*! `armasm` grammar compiled for Highlight.js 11.11.1 */ | |
| 2608 (function(){ | |
| 2609 var hljsGrammar = (function () { | |
| 2610 'use strict'; | |
| 2611 | |
| 2612 /* | |
| 2613 Language: ARM Assembly | |
| 2614 Author: Dan Panzarella <[email protected]> | |
| 2615 Description: ARM Assembly including Thumb and Thumb2 instructions | |
| 2616 Category: assembler | |
| 2617 */ | |
| 2618 | |
| 2619 /** @type LanguageFn */ | |
| 2620 function armasm(hljs) { | |
| 2621 // local labels: %?[FB]?[AT]?\d{1,2}\w+ | |
| 2622 | |
| 2623 const COMMENT = { variants: [ | |
| 2624 hljs.COMMENT('^[ \\t]*(?=#)', '$', { | |
| 2625 relevance: 0, | |
| 2626 excludeBegin: true | |
| 2627 }), | |
| 2628 hljs.COMMENT('[;@]', '$', { relevance: 0 }), | |
| 2629 hljs.C_LINE_COMMENT_MODE, | |
| 2630 hljs.C_BLOCK_COMMENT_MODE | |
| 2631 ] }; | |
| 2632 | |
| 2633 return { | |
| 2634 name: 'ARM Assembly', | |
| 2635 case_insensitive: true, | |
| 2636 aliases: [ 'arm' ], | |
| 2637 keywords: { | |
| 2638 $pattern: '\\.?' + hljs.IDENT_RE, | |
| 2639 meta: | |
| 2640 // GNU preprocs | |
| 2641 '.2byte .4byte .align .ascii .asciz .balign .byte .code .data .else .end .endif .endm .endr .equ .err .exitm .extern .global .hword .if .ifdef .ifndef .include .irp .long .macro .rept .req .section .set .skip .space .text .word .arm .thumb .code16 .code32 .force_thumb .thumb_func .ltorg ' | |
| 2642 // ARM directives | |
| 2643 + 'ALIAS ALIGN ARM AREA ASSERT ATTR CN CODE CODE16 CODE32 COMMON CP DATA DCB DCD DCDU DCDO DCFD DCFDU DCI DCQ DCQU DCW DCWU DN ELIF ELSE END ENDFUNC ENDIF ENDP ENTRY EQU EXPORT EXPORTAS EXTERN FIELD FILL FUNCTION GBLA GBLL GBLS GET GLOBAL IF IMPORT INCBIN INCLUDE INFO KEEP LCLA LCLL LCLS LTORG MACRO MAP MEND MEXIT NOFP OPT PRESERVE8 PROC QN READONLY RELOC REQUIRE REQUIRE8 RLIST FN ROUT SETA SETL SETS SN SPACE SUBT THUMB THUMBX TTL WHILE WEND ', | |
| 2644 built_in: | |
| 2645 'r0 r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12 r13 r14 r15 ' // standard registers | |
| 2646 + 'w0 w1 w2 w3 w4 w5 w6 w7 w8 w9 w10 w11 w12 w13 w14 w15 ' // 32 bit ARMv8 registers | |
| 2647 + 'w16 w17 w18 w19 w20 w21 w22 w23 w24 w25 w26 w27 w28 w29 w30 ' | |
| 2648 + 'x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 x12 x13 x14 x15 ' // 64 bit ARMv8 registers | |
| 2649 + 'x16 x17 x18 x19 x20 x21 x22 x23 x24 x25 x26 x27 x28 x29 x30 ' | |
| 2650 + 'pc lr sp ip sl sb fp ' // typical regs plus backward compatibility | |
| 2651 + 'a1 a2 a3 a4 v1 v2 v3 v4 v5 v6 v7 v8 f0 f1 f2 f3 f4 f5 f6 f7 ' // more regs and fp | |
| 2652 + 'p0 p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 p13 p14 p15 ' // coprocessor regs | |
| 2653 + 'c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 ' // more coproc | |
| 2654 + 'q0 q1 q2 q3 q4 q5 q6 q7 q8 q9 q10 q11 q12 q13 q14 q15 ' // advanced SIMD NEON regs | |
| 2655 | |
| 2656 // program status registers | |
| 2657 + 'cpsr_c cpsr_x cpsr_s cpsr_f cpsr_cx cpsr_cxs cpsr_xs cpsr_xsf cpsr_sf cpsr_cxsf ' | |
| 2658 + 'spsr_c spsr_x spsr_s spsr_f spsr_cx spsr_cxs spsr_xs spsr_xsf spsr_sf spsr_cxsf ' | |
| 2659 | |
| 2660 // NEON and VFP registers | |
| 2661 + 's0 s1 s2 s3 s4 s5 s6 s7 s8 s9 s10 s11 s12 s13 s14 s15 ' | |
| 2662 + 's16 s17 s18 s19 s20 s21 s22 s23 s24 s25 s26 s27 s28 s29 s30 s31 ' | |
| 2663 + 'd0 d1 d2 d3 d4 d5 d6 d7 d8 d9 d10 d11 d12 d13 d14 d15 ' | |
| 2664 + 'd16 d17 d18 d19 d20 d21 d22 d23 d24 d25 d26 d27 d28 d29 d30 d31 ' | |
| 2665 | |
| 2666 + '{PC} {VAR} {TRUE} {FALSE} {OPT} {CONFIG} {ENDIAN} {CODESIZE} {CPU} {FPU} {ARCHITECTURE} {PCSTOREOFFSET} {ARMASM_VERSION} {INTER} {ROPI} {RWPI} {SWST} {NOSWST} . @' | |
| 2667 }, | |
| 2668 contains: [ | |
| 2669 { | |
| 2670 className: 'keyword', | |
| 2671 begin: '\\b(' // mnemonics | |
| 2672 + 'adc|' | |
| 2673 + '(qd?|sh?|u[qh]?)?add(8|16)?|usada?8|(q|sh?|u[qh]?)?(as|sa)x|' | |
| 2674 + 'and|adrl?|sbc|rs[bc]|asr|b[lx]?|blx|bxj|cbn?z|tb[bh]|bic|' | |
| 2675 + 'bfc|bfi|[su]bfx|bkpt|cdp2?|clz|clrex|cmp|cmn|cpsi[ed]|cps|' | |
| 2676 + 'setend|dbg|dmb|dsb|eor|isb|it[te]{0,3}|lsl|lsr|ror|rrx|' | |
| 2677 + 'ldm(([id][ab])|f[ds])?|ldr((s|ex)?[bhd])?|movt?|mvn|mra|mar|' | |
| 2678 + 'mul|[us]mull|smul[bwt][bt]|smu[as]d|smmul|smmla|' | |
| 2679 + 'mla|umlaal|smlal?([wbt][bt]|d)|mls|smlsl?[ds]|smc|svc|sev|' | |
| 2680 + 'mia([bt]{2}|ph)?|mrr?c2?|mcrr2?|mrs|msr|orr|orn|pkh(tb|bt)|rbit|' | |
| 2681 + 'rev(16|sh)?|sel|[su]sat(16)?|nop|pop|push|rfe([id][ab])?|' | |
| 2682 + 'stm([id][ab])?|str(ex)?[bhd]?|(qd?)?sub|(sh?|q|u[qh]?)?sub(8|16)|' | |
| 2683 + '[su]xt(a?h|a?b(16)?)|srs([id][ab])?|swpb?|swi|smi|tst|teq|' | |
| 2684 + 'wfe|wfi|yield' | |
| 2685 + ')' | |
| 2686 + '(eq|ne|cs|cc|mi|pl|vs|vc|hi|ls|ge|lt|gt|le|al|hs|lo)?' // condition codes | |
| 2687 + '[sptrx]?' // legal postfixes | |
| 2688 + '(?=\\s)' // followed by space | |
| 2689 }, | |
| 2690 COMMENT, | |
| 2691 hljs.QUOTE_STRING_MODE, | |
| 2692 { | |
| 2693 className: 'string', | |
| 2694 begin: '\'', | |
| 2695 end: '[^\\\\]\'', | |
| 2696 relevance: 0 | |
| 2697 }, | |
| 2698 { | |
| 2699 className: 'title', | |
| 2700 begin: '\\|', | |
| 2701 end: '\\|', | |
| 2702 illegal: '\\n', | |
| 2703 relevance: 0 | |
| 2704 }, | |
| 2705 { | |
| 2706 className: 'number', | |
| 2707 variants: [ | |
| 2708 { // hex | |
| 2709 begin: '[#$=]?0x[0-9a-f]+' }, | |
| 2710 { // bin | |
| 2711 begin: '[#$=]?0b[01]+' }, | |
| 2712 { // literal | |
| 2713 begin: '[#$=]\\d+' }, | |
| 2714 { // bare number | |
| 2715 begin: '\\b\\d+' } | |
| 2716 ], | |
| 2717 relevance: 0 | |
| 2718 }, | |
| 2719 { | |
| 2720 className: 'symbol', | |
| 2721 variants: [ | |
| 2722 { // GNU ARM syntax | |
| 2723 begin: '^[ \\t]*[a-z_\\.\\$][a-z0-9_\\.\\$]+:' }, | |
| 2724 { // ARM syntax | |
| 2725 begin: '^[a-z_\\.\\$][a-z0-9_\\.\\$]+' }, | |
| 2726 { // label reference | |
| 2727 begin: '[=#]\\w+' } | |
| 2728 ], | |
| 2729 relevance: 0 | |
| 2730 } | |
| 2731 ] | |
| 2732 }; | |
| 2733 } | |
| 2734 | |
| 2735 return armasm; | |
| 2736 | |
| 2737 })(); | |
| 2738 | |
| 2739 hljs.registerLanguage('armasm', hljsGrammar); | |
| 2740 })();/*! `c` grammar compiled for Highlight.js 11.11.1 */ | |
| 2741 (function(){ | |
| 2742 var hljsGrammar = (function () { | |
| 2743 'use strict'; | |
| 2744 | |
| 2745 /* | |
| 2746 Language: C | |
| 2747 Category: common, system | |
| 2748 Website: https://en.wikipedia.org/wiki/C_(programming_language) | |
| 2749 */ | |
| 2750 | |
| 2751 /** @type LanguageFn */ | |
| 2752 function c(hljs) { | |
| 2753 const regex = hljs.regex; | |
| 2754 // added for historic reasons because `hljs.C_LINE_COMMENT_MODE` does | |
| 2755 // not include such support nor can we be sure all the grammars depending | |
| 2756 // on it would desire this behavior | |
| 2757 const C_LINE_COMMENT_MODE = hljs.COMMENT('//', '$', { contains: [ { begin: /\\\n/ } ] }); | |
| 2758 const DECLTYPE_AUTO_RE = 'decltype\\(auto\\)'; | |
| 2759 const NAMESPACE_RE = '[a-zA-Z_]\\w*::'; | |
| 2760 const TEMPLATE_ARGUMENT_RE = '<[^<>]+>'; | |
| 2761 const FUNCTION_TYPE_RE = '(' | |
| 2762 + DECLTYPE_AUTO_RE + '|' | |
| 2763 + regex.optional(NAMESPACE_RE) | |
| 2764 + '[a-zA-Z_]\\w*' + regex.optional(TEMPLATE_ARGUMENT_RE) | |
| 2765 + ')'; | |
| 2766 | |
| 2767 | |
| 2768 const TYPES = { | |
| 2769 className: 'type', | |
| 2770 variants: [ | |
| 2771 { begin: '\\b[a-z\\d_]*_t\\b' }, | |
| 2772 { match: /\batomic_[a-z]{3,6}\b/ } | |
| 2773 ] | |
| 2774 | |
| 2775 }; | |
| 2776 | |
| 2777 // https://en.cppreference.com/w/cpp/language/escape | |
| 2778 // \\ \x \xFF \u2837 \u00323747 \374 | |
| 2779 const CHARACTER_ESCAPES = '\\\\(x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4,8}|[0-7]{3}|\\S)'; | |
| 2780 const STRINGS = { | |
| 2781 className: 'string', | |
| 2782 variants: [ | |
| 2783 { | |
| 2784 begin: '(u8?|U|L)?"', | |
| 2785 end: '"', | |
| 2786 illegal: '\\n', | |
| 2787 contains: [ hljs.BACKSLASH_ESCAPE ] | |
| 2788 }, | |
| 2789 { | |
| 2790 begin: '(u8?|U|L)?\'(' + CHARACTER_ESCAPES + "|.)", | |
| 2791 end: '\'', | |
| 2792 illegal: '.' | |
| 2793 }, | |
| 2794 hljs.END_SAME_AS_BEGIN({ | |
| 2795 begin: /(?:u8?|U|L)?R"([^()\\ ]{0,16})\(/, | |
| 2796 end: /\)([^()\\ ]{0,16})"/ | |
| 2797 }) | |
| 2798 ] | |
| 2799 }; | |
| 2800 | |
| 2801 const NUMBERS = { | |
| 2802 className: 'number', | |
| 2803 variants: [ | |
| 2804 { match: /\b(0b[01']+)/ }, | |
| 2805 { match: /(-?)\b([\d']+(\.[\d']*)?|\.[\d']+)((ll|LL|l|L)(u|U)?|(u|U)(ll|LL|l|L)?|f|F|b|B)/ }, | |
| 2806 { match: /(-?)\b(0[xX][a-fA-F0-9]+(?:'[a-fA-F0-9]+)*(?:\.[a-fA-F0-9]*(?:'[a-fA-F0-9]*)*)?(?:[pP][-+]?[0-9]+)?(l|L)?(u|U)?)/ }, | |
| 2807 { match: /(-?)\b\d+(?:'\d+)*(?:\.\d*(?:'\d*)*)?(?:[eE][-+]?\d+)?/ } | |
| 2808 ], | |
| 2809 relevance: 0 | |
| 2810 }; | |
| 2811 | |
| 2812 const PREPROCESSOR = { | |
| 2813 className: 'meta', | |
| 2814 begin: /#\s*[a-z]+\b/, | |
| 2815 end: /$/, | |
| 2816 keywords: { keyword: | |
| 2817 'if else elif endif define undef warning error line ' | |
| 2818 + 'pragma _Pragma ifdef ifndef elifdef elifndef include' }, | |
| 2819 contains: [ | |
| 2820 { | |
| 2821 begin: /\\\n/, | |
| 2822 relevance: 0 | |
| 2823 }, | |
| 2824 hljs.inherit(STRINGS, { className: 'string' }), | |
| 2825 { | |
| 2826 className: 'string', | |
| 2827 begin: /<.*?>/ | |
| 2828 }, | |
| 2829 C_LINE_COMMENT_MODE, | |
| 2830 hljs.C_BLOCK_COMMENT_MODE | |
| 2831 ] | |
| 2832 }; | |
| 2833 | |
| 2834 const TITLE_MODE = { | |
| 2835 className: 'title', | |
| 2836 begin: regex.optional(NAMESPACE_RE) + hljs.IDENT_RE, | |
| 2837 relevance: 0 | |
| 2838 }; | |
| 2839 | |
| 2840 const FUNCTION_TITLE = regex.optional(NAMESPACE_RE) + hljs.IDENT_RE + '\\s*\\('; | |
| 2841 | |
| 2842 const C_KEYWORDS = [ | |
| 2843 "asm", | |
| 2844 "auto", | |
| 2845 "break", | |
| 2846 "case", | |
| 2847 "continue", | |
| 2848 "default", | |
| 2849 "do", | |
| 2850 "else", | |
| 2851 "enum", | |
| 2852 "extern", | |
| 2853 "for", | |
| 2854 "fortran", | |
| 2855 "goto", | |
| 2856 "if", | |
| 2857 "inline", | |
| 2858 "register", | |
| 2859 "restrict", | |
| 2860 "return", | |
| 2861 "sizeof", | |
| 2862 "typeof", | |
| 2863 "typeof_unqual", | |
| 2864 "struct", | |
| 2865 "switch", | |
| 2866 "typedef", | |
| 2867 "union", | |
| 2868 "volatile", | |
| 2869 "while", | |
| 2870 "_Alignas", | |
| 2871 "_Alignof", | |
| 2872 "_Atomic", | |
| 2873 "_Generic", | |
| 2874 "_Noreturn", | |
| 2875 "_Static_assert", | |
| 2876 "_Thread_local", | |
| 2877 // aliases | |
| 2878 "alignas", | |
| 2879 "alignof", | |
| 2880 "noreturn", | |
| 2881 "static_assert", | |
| 2882 "thread_local", | |
| 2883 // not a C keyword but is, for all intents and purposes, treated exactly like one. | |
| 2884 "_Pragma" | |
| 2885 ]; | |
| 2886 | |
| 2887 const C_TYPES = [ | |
| 2888 "float", | |
| 2889 "double", | |
| 2890 "signed", | |
| 2891 "unsigned", | |
| 2892 "int", | |
| 2893 "short", | |
| 2894 "long", | |
| 2895 "char", | |
| 2896 "void", | |
| 2897 "_Bool", | |
| 2898 "_BitInt", | |
| 2899 "_Complex", | |
| 2900 "_Imaginary", | |
| 2901 "_Decimal32", | |
| 2902 "_Decimal64", | |
| 2903 "_Decimal96", | |
| 2904 "_Decimal128", | |
| 2905 "_Decimal64x", | |
| 2906 "_Decimal128x", | |
| 2907 "_Float16", | |
| 2908 "_Float32", | |
| 2909 "_Float64", | |
| 2910 "_Float128", | |
| 2911 "_Float32x", | |
| 2912 "_Float64x", | |
| 2913 "_Float128x", | |
| 2914 // modifiers | |
| 2915 "const", | |
| 2916 "static", | |
| 2917 "constexpr", | |
| 2918 // aliases | |
| 2919 "complex", | |
| 2920 "bool", | |
| 2921 "imaginary" | |
| 2922 ]; | |
| 2923 | |
| 2924 const KEYWORDS = { | |
| 2925 keyword: C_KEYWORDS, | |
| 2926 type: C_TYPES, | |
| 2927 literal: 'true false NULL', | |
| 2928 // TODO: apply hinting work similar to what was done in cpp.js | |
| 2929 built_in: 'std string wstring cin cout cerr clog stdin stdout stderr stringstream istringstream ostringstream ' | |
| 2930 + 'auto_ptr deque list queue stack vector map set pair bitset multiset multimap unordered_set ' | |
| 2931 + 'unordered_map unordered_multiset unordered_multimap priority_queue make_pair array shared_ptr abort terminate abs acos ' | |
| 2932 + 'asin atan2 atan calloc ceil cosh cos exit exp fabs floor fmod fprintf fputs free frexp ' | |
| 2933 + 'fscanf future isalnum isalpha iscntrl isdigit isgraph islower isprint ispunct isspace isupper ' | |
| 2934 + 'isxdigit tolower toupper labs ldexp log10 log malloc realloc memchr memcmp memcpy memset modf pow ' | |
| 2935 + 'printf putchar puts scanf sinh sin snprintf sprintf sqrt sscanf strcat strchr strcmp ' | |
| 2936 + 'strcpy strcspn strlen strncat strncmp strncpy strpbrk strrchr strspn strstr tanh tan ' | |
| 2937 + 'vfprintf vprintf vsprintf endl initializer_list unique_ptr', | |
| 2938 }; | |
| 2939 | |
| 2940 const EXPRESSION_CONTAINS = [ | |
| 2941 PREPROCESSOR, | |
| 2942 TYPES, | |
| 2943 C_LINE_COMMENT_MODE, | |
| 2944 hljs.C_BLOCK_COMMENT_MODE, | |
| 2945 NUMBERS, | |
| 2946 STRINGS | |
| 2947 ]; | |
| 2948 | |
| 2949 const EXPRESSION_CONTEXT = { | |
| 2950 // This mode covers expression context where we can't expect a function | |
| 2951 // definition and shouldn't highlight anything that looks like one: | |
| 2952 // `return some()`, `else if()`, `(x*sum(1, 2))` | |
| 2953 variants: [ | |
| 2954 { | |
| 2955 begin: /=/, | |
| 2956 end: /;/ | |
| 2957 }, | |
| 2958 { | |
| 2959 begin: /\(/, | |
| 2960 end: /\)/ | |
| 2961 }, | |
| 2962 { | |
| 2963 beginKeywords: 'new throw return else', | |
| 2964 end: /;/ | |
| 2965 } | |
| 2966 ], | |
| 2967 keywords: KEYWORDS, | |
| 2968 contains: EXPRESSION_CONTAINS.concat([ | |
| 2969 { | |
| 2970 begin: /\(/, | |
| 2971 end: /\)/, | |
| 2972 keywords: KEYWORDS, | |
| 2973 contains: EXPRESSION_CONTAINS.concat([ 'self' ]), | |
| 2974 relevance: 0 | |
| 2975 } | |
| 2976 ]), | |
| 2977 relevance: 0 | |
| 2978 }; | |
| 2979 | |
| 2980 const FUNCTION_DECLARATION = { | |
| 2981 begin: '(' + FUNCTION_TYPE_RE + '[\\*&\\s]+)+' + FUNCTION_TITLE, | |
| 2982 returnBegin: true, | |
| 2983 end: /[{;=]/, | |
| 2984 excludeEnd: true, | |
| 2985 keywords: KEYWORDS, | |
| 2986 illegal: /[^\w\s\*&:<>.]/, | |
| 2987 contains: [ | |
| 2988 { // to prevent it from being confused as the function title | |
| 2989 begin: DECLTYPE_AUTO_RE, | |
| 2990 keywords: KEYWORDS, | |
| 2991 relevance: 0 | |
| 2992 }, | |
| 2993 { | |
| 2994 begin: FUNCTION_TITLE, | |
| 2995 returnBegin: true, | |
| 2996 contains: [ hljs.inherit(TITLE_MODE, { className: "title.function" }) ], | |
| 2997 relevance: 0 | |
| 2998 }, | |
| 2999 // allow for multiple declarations, e.g.: | |
| 3000 // extern void f(int), g(char); | |
| 3001 { | |
| 3002 relevance: 0, | |
| 3003 match: /,/ | |
| 3004 }, | |
| 3005 { | |
| 3006 className: 'params', | |
| 3007 begin: /\(/, | |
| 3008 end: /\)/, | |
| 3009 keywords: KEYWORDS, | |
| 3010 relevance: 0, | |
| 3011 contains: [ | |
| 3012 C_LINE_COMMENT_MODE, | |
| 3013 hljs.C_BLOCK_COMMENT_MODE, | |
| 3014 STRINGS, | |
| 3015 NUMBERS, | |
| 3016 TYPES, | |
| 3017 // Count matching parentheses. | |
| 3018 { | |
| 3019 begin: /\(/, | |
| 3020 end: /\)/, | |
| 3021 keywords: KEYWORDS, | |
| 3022 relevance: 0, | |
| 3023 contains: [ | |
| 3024 'self', | |
| 3025 C_LINE_COMMENT_MODE, | |
| 3026 hljs.C_BLOCK_COMMENT_MODE, | |
| 3027 STRINGS, | |
| 3028 NUMBERS, | |
| 3029 TYPES | |
| 3030 ] | |
| 3031 } | |
| 3032 ] | |
| 3033 }, | |
| 3034 TYPES, | |
| 3035 C_LINE_COMMENT_MODE, | |
| 3036 hljs.C_BLOCK_COMMENT_MODE, | |
| 3037 PREPROCESSOR | |
| 3038 ] | |
| 3039 }; | |
| 3040 | |
| 3041 return { | |
| 3042 name: "C", | |
| 3043 aliases: [ 'h' ], | |
| 3044 keywords: KEYWORDS, | |
| 3045 // Until differentiations are added between `c` and `cpp`, `c` will | |
| 3046 // not be auto-detected to avoid auto-detect conflicts between C and C++ | |
| 3047 disableAutodetect: true, | |
| 3048 illegal: '</', | |
| 3049 contains: [].concat( | |
| 3050 EXPRESSION_CONTEXT, | |
| 3051 FUNCTION_DECLARATION, | |
| 3052 EXPRESSION_CONTAINS, | |
| 3053 [ | |
| 3054 PREPROCESSOR, | |
| 3055 { | |
| 3056 begin: hljs.IDENT_RE + '::', | |
| 3057 keywords: KEYWORDS | |
| 3058 }, | |
| 3059 { | |
| 3060 className: 'class', | |
| 3061 beginKeywords: 'enum class struct union', | |
| 3062 end: /[{;:<>=]/, | |
| 3063 contains: [ | |
| 3064 { beginKeywords: "final class struct" }, | |
| 3065 hljs.TITLE_MODE | |
| 3066 ] | |
| 3067 } | |
| 3068 ]), | |
| 3069 exports: { | |
| 3070 preprocessor: PREPROCESSOR, | |
| 3071 strings: STRINGS, | |
| 3072 keywords: KEYWORDS | |
| 3073 } | |
| 3074 }; | |
| 3075 } | |
| 3076 | |
| 3077 return c; | |
| 3078 | |
| 3079 })(); | |
| 3080 | |
| 3081 hljs.registerLanguage('c', hljsGrammar); | |
| 3082 })();/*! `cpp` grammar compiled for Highlight.js 11.11.1 */ | |
| 3083 (function(){ | |
| 3084 var hljsGrammar = (function () { | |
| 3085 'use strict'; | |
| 3086 | |
| 3087 /* | |
| 3088 Language: C++ | |
| 3089 Category: common, system | |
| 3090 Website: https://isocpp.org | |
| 3091 */ | |
| 3092 | |
| 3093 /** @type LanguageFn */ | |
| 3094 function cpp(hljs) { | |
| 3095 const regex = hljs.regex; | |
| 3096 // added for historic reasons because `hljs.C_LINE_COMMENT_MODE` does | |
| 3097 // not include such support nor can we be sure all the grammars depending | |
| 3098 // on it would desire this behavior | |
| 3099 const C_LINE_COMMENT_MODE = hljs.COMMENT('//', '$', { contains: [ { begin: /\\\n/ } ] }); | |
| 3100 const DECLTYPE_AUTO_RE = 'decltype\\(auto\\)'; | |
| 3101 const NAMESPACE_RE = '[a-zA-Z_]\\w*::'; | |
| 3102 const TEMPLATE_ARGUMENT_RE = '<[^<>]+>'; | |
| 3103 const FUNCTION_TYPE_RE = '(?!struct)(' | |
| 3104 + DECLTYPE_AUTO_RE + '|' | |
| 3105 + regex.optional(NAMESPACE_RE) | |
| 3106 + '[a-zA-Z_]\\w*' + regex.optional(TEMPLATE_ARGUMENT_RE) | |
| 3107 + ')'; | |
| 3108 | |
| 3109 const CPP_PRIMITIVE_TYPES = { | |
| 3110 className: 'type', | |
| 3111 begin: '\\b[a-z\\d_]*_t\\b' | |
| 3112 }; | |
| 3113 | |
| 3114 // https://en.cppreference.com/w/cpp/language/escape | |
| 3115 // \\ \x \xFF \u2837 \u00323747 \374 | |
| 3116 const CHARACTER_ESCAPES = '\\\\(x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4,8}|[0-7]{3}|\\S)'; | |
| 3117 const STRINGS = { | |
| 3118 className: 'string', | |
| 3119 variants: [ | |
| 3120 { | |
| 3121 begin: '(u8?|U|L)?"', | |
| 3122 end: '"', | |
| 3123 illegal: '\\n', | |
| 3124 contains: [ hljs.BACKSLASH_ESCAPE ] | |
| 3125 }, | |
| 3126 { | |
| 3127 begin: '(u8?|U|L)?\'(' + CHARACTER_ESCAPES + '|.)', | |
| 3128 end: '\'', | |
| 3129 illegal: '.' | |
| 3130 }, | |
| 3131 hljs.END_SAME_AS_BEGIN({ | |
| 3132 begin: /(?:u8?|U|L)?R"([^()\\ ]{0,16})\(/, | |
| 3133 end: /\)([^()\\ ]{0,16})"/ | |
| 3134 }) | |
| 3135 ] | |
| 3136 }; | |
| 3137 | |
| 3138 const NUMBERS = { | |
| 3139 className: 'number', | |
| 3140 variants: [ | |
| 3141 // Floating-point literal. | |
| 3142 { begin: | |
| 3143 "[+-]?(?:" // Leading sign. | |
| 3144 // Decimal. | |
| 3145 + "(?:" | |
| 3146 +"[0-9](?:'?[0-9])*\\.(?:[0-9](?:'?[0-9])*)?" | |
| 3147 + "|\\.[0-9](?:'?[0-9])*" | |
| 3148 + ")(?:[Ee][+-]?[0-9](?:'?[0-9])*)?" | |
| 3149 + "|[0-9](?:'?[0-9])*[Ee][+-]?[0-9](?:'?[0-9])*" | |
| 3150 // Hexadecimal. | |
| 3151 + "|0[Xx](?:" | |
| 3152 +"[0-9A-Fa-f](?:'?[0-9A-Fa-f])*(?:\\.(?:[0-9A-Fa-f](?:'?[0-9A-Fa-f])*)?)?" | |
| 3153 + "|\\.[0-9A-Fa-f](?:'?[0-9A-Fa-f])*" | |
| 3154 + ")[Pp][+-]?[0-9](?:'?[0-9])*" | |
| 3155 + ")(?:" // Literal suffixes. | |
| 3156 + "[Ff](?:16|32|64|128)?" | |
| 3157 + "|(BF|bf)16" | |
| 3158 + "|[Ll]" | |
| 3159 + "|" // Literal suffix is optional. | |
| 3160 + ")" | |
| 3161 }, | |
| 3162 // Integer literal. | |
| 3163 { begin: | |
| 3164 "[+-]?\\b(?:" // Leading sign. | |
| 3165 + "0[Bb][01](?:'?[01])*" // Binary. | |
| 3166 + "|0[Xx][0-9A-Fa-f](?:'?[0-9A-Fa-f])*" // Hexadecimal. | |
| 3167 + "|0(?:'?[0-7])*" // Octal or just a lone zero. | |
| 3168 + "|[1-9](?:'?[0-9])*" // Decimal. | |
| 3169 + ")(?:" // Literal suffixes. | |
| 3170 + "[Uu](?:LL?|ll?)" | |
| 3171 + "|[Uu][Zz]?" | |
| 3172 + "|(?:LL?|ll?)[Uu]?" | |
| 3173 + "|[Zz][Uu]" | |
| 3174 + "|" // Literal suffix is optional. | |
| 3175 + ")" | |
| 3176 // Note: there are user-defined literal suffixes too, but perhaps having the custom suffix not part of the | |
| 3177 // literal highlight actually makes it stand out more. | |
| 3178 } | |
| 3179 ], | |
| 3180 relevance: 0 | |
| 3181 }; | |
| 3182 | |
| 3183 const PREPROCESSOR = { | |
| 3184 className: 'meta', | |
| 3185 begin: /#\s*[a-z]+\b/, | |
| 3186 end: /$/, | |
| 3187 keywords: { keyword: | |
| 3188 'if else elif endif define undef warning error line ' | |
| 3189 + 'pragma _Pragma ifdef ifndef include' }, | |
| 3190 contains: [ | |
| 3191 { | |
| 3192 begin: /\\\n/, | |
| 3193 relevance: 0 | |
| 3194 }, | |
| 3195 hljs.inherit(STRINGS, { className: 'string' }), | |
| 3196 { | |
| 3197 className: 'string', | |
| 3198 begin: /<.*?>/ | |
| 3199 }, | |
| 3200 C_LINE_COMMENT_MODE, | |
| 3201 hljs.C_BLOCK_COMMENT_MODE | |
| 3202 ] | |
| 3203 }; | |
| 3204 | |
| 3205 const TITLE_MODE = { | |
| 3206 className: 'title', | |
| 3207 begin: regex.optional(NAMESPACE_RE) + hljs.IDENT_RE, | |
| 3208 relevance: 0 | |
| 3209 }; | |
| 3210 | |
| 3211 const FUNCTION_TITLE = regex.optional(NAMESPACE_RE) + hljs.IDENT_RE + '\\s*\\('; | |
| 3212 | |
| 3213 // https://en.cppreference.com/w/cpp/keyword | |
| 3214 const RESERVED_KEYWORDS = [ | |
| 3215 'alignas', | |
| 3216 'alignof', | |
| 3217 'and', | |
| 3218 'and_eq', | |
| 3219 'asm', | |
| 3220 'atomic_cancel', | |
| 3221 'atomic_commit', | |
| 3222 'atomic_noexcept', | |
| 3223 'auto', | |
| 3224 'bitand', | |
| 3225 'bitor', | |
| 3226 'break', | |
| 3227 'case', | |
| 3228 'catch', | |
| 3229 'class', | |
| 3230 'co_await', | |
| 3231 'co_return', | |
| 3232 'co_yield', | |
| 3233 'compl', | |
| 3234 'concept', | |
| 3235 'const_cast|10', | |
| 3236 'consteval', | |
| 3237 'constexpr', | |
| 3238 'constinit', | |
| 3239 'continue', | |
| 3240 'decltype', | |
| 3241 'default', | |
| 3242 'delete', | |
| 3243 'do', | |
| 3244 'dynamic_cast|10', | |
| 3245 'else', | |
| 3246 'enum', | |
| 3247 'explicit', | |
| 3248 'export', | |
| 3249 'extern', | |
| 3250 'false', | |
| 3251 'final', | |
| 3252 'for', | |
| 3253 'friend', | |
| 3254 'goto', | |
| 3255 'if', | |
| 3256 'import', | |
| 3257 'inline', | |
| 3258 'module', | |
| 3259 'mutable', | |
| 3260 'namespace', | |
| 3261 'new', | |
| 3262 'noexcept', | |
| 3263 'not', | |
| 3264 'not_eq', | |
| 3265 'nullptr', | |
| 3266 'operator', | |
| 3267 'or', | |
| 3268 'or_eq', | |
| 3269 'override', | |
| 3270 'private', | |
| 3271 'protected', | |
| 3272 'public', | |
| 3273 'reflexpr', | |
| 3274 'register', | |
| 3275 'reinterpret_cast|10', | |
| 3276 'requires', | |
| 3277 'return', | |
| 3278 'sizeof', | |
| 3279 'static_assert', | |
| 3280 'static_cast|10', | |
| 3281 'struct', | |
| 3282 'switch', | |
| 3283 'synchronized', | |
| 3284 'template', | |
| 3285 'this', | |
| 3286 'thread_local', | |
| 3287 'throw', | |
| 3288 'transaction_safe', | |
| 3289 'transaction_safe_dynamic', | |
| 3290 'true', | |
| 3291 'try', | |
| 3292 'typedef', | |
| 3293 'typeid', | |
| 3294 'typename', | |
| 3295 'union', | |
| 3296 'using', | |
| 3297 'virtual', | |
| 3298 'volatile', | |
| 3299 'while', | |
| 3300 'xor', | |
| 3301 'xor_eq' | |
| 3302 ]; | |
| 3303 | |
| 3304 // https://en.cppreference.com/w/cpp/keyword | |
| 3305 const RESERVED_TYPES = [ | |
| 3306 'bool', | |
| 3307 'char', | |
| 3308 'char16_t', | |
| 3309 'char32_t', | |
| 3310 'char8_t', | |
| 3311 'double', | |
| 3312 'float', | |
| 3313 'int', | |
| 3314 'long', | |
| 3315 'short', | |
| 3316 'void', | |
| 3317 'wchar_t', | |
| 3318 'unsigned', | |
| 3319 'signed', | |
| 3320 'const', | |
| 3321 'static' | |
| 3322 ]; | |
| 3323 | |
| 3324 const TYPE_HINTS = [ | |
| 3325 'any', | |
| 3326 'auto_ptr', | |
| 3327 'barrier', | |
| 3328 'binary_semaphore', | |
| 3329 'bitset', | |
| 3330 'complex', | |
| 3331 'condition_variable', | |
| 3332 'condition_variable_any', | |
| 3333 'counting_semaphore', | |
| 3334 'deque', | |
| 3335 'false_type', | |
| 3336 'flat_map', | |
| 3337 'flat_set', | |
| 3338 'future', | |
| 3339 'imaginary', | |
| 3340 'initializer_list', | |
| 3341 'istringstream', | |
| 3342 'jthread', | |
| 3343 'latch', | |
| 3344 'lock_guard', | |
| 3345 'multimap', | |
| 3346 'multiset', | |
| 3347 'mutex', | |
| 3348 'optional', | |
| 3349 'ostringstream', | |
| 3350 'packaged_task', | |
| 3351 'pair', | |
| 3352 'promise', | |
| 3353 'priority_queue', | |
| 3354 'queue', | |
| 3355 'recursive_mutex', | |
| 3356 'recursive_timed_mutex', | |
| 3357 'scoped_lock', | |
| 3358 'set', | |
| 3359 'shared_future', | |
| 3360 'shared_lock', | |
| 3361 'shared_mutex', | |
| 3362 'shared_timed_mutex', | |
| 3363 'shared_ptr', | |
| 3364 'stack', | |
| 3365 'string_view', | |
| 3366 'stringstream', | |
| 3367 'timed_mutex', | |
| 3368 'thread', | |
| 3369 'true_type', | |
| 3370 'tuple', | |
| 3371 'unique_lock', | |
| 3372 'unique_ptr', | |
| 3373 'unordered_map', | |
| 3374 'unordered_multimap', | |
| 3375 'unordered_multiset', | |
| 3376 'unordered_set', | |
| 3377 'variant', | |
| 3378 'vector', | |
| 3379 'weak_ptr', | |
| 3380 'wstring', | |
| 3381 'wstring_view' | |
| 3382 ]; | |
| 3383 | |
| 3384 const FUNCTION_HINTS = [ | |
| 3385 'abort', | |
| 3386 'abs', | |
| 3387 'acos', | |
| 3388 'apply', | |
| 3389 'as_const', | |
| 3390 'asin', | |
| 3391 'atan', | |
| 3392 'atan2', | |
| 3393 'calloc', | |
| 3394 'ceil', | |
| 3395 'cerr', | |
| 3396 'cin', | |
| 3397 'clog', | |
| 3398 'cos', | |
| 3399 'cosh', | |
| 3400 'cout', | |
| 3401 'declval', | |
| 3402 'endl', | |
| 3403 'exchange', | |
| 3404 'exit', | |
| 3405 'exp', | |
| 3406 'fabs', | |
| 3407 'floor', | |
| 3408 'fmod', | |
| 3409 'forward', | |
| 3410 'fprintf', | |
| 3411 'fputs', | |
| 3412 'free', | |
| 3413 'frexp', | |
| 3414 'fscanf', | |
| 3415 'future', | |
| 3416 'invoke', | |
| 3417 'isalnum', | |
| 3418 'isalpha', | |
| 3419 'iscntrl', | |
| 3420 'isdigit', | |
| 3421 'isgraph', | |
| 3422 'islower', | |
| 3423 'isprint', | |
| 3424 'ispunct', | |
| 3425 'isspace', | |
| 3426 'isupper', | |
| 3427 'isxdigit', | |
| 3428 'labs', | |
| 3429 'launder', | |
| 3430 'ldexp', | |
| 3431 'log', | |
| 3432 'log10', | |
| 3433 'make_pair', | |
| 3434 'make_shared', | |
| 3435 'make_shared_for_overwrite', | |
| 3436 'make_tuple', | |
| 3437 'make_unique', | |
| 3438 'malloc', | |
| 3439 'memchr', | |
| 3440 'memcmp', | |
| 3441 'memcpy', | |
| 3442 'memset', | |
| 3443 'modf', | |
| 3444 'move', | |
| 3445 'pow', | |
| 3446 'printf', | |
| 3447 'putchar', | |
| 3448 'puts', | |
| 3449 'realloc', | |
| 3450 'scanf', | |
| 3451 'sin', | |
| 3452 'sinh', | |
| 3453 'snprintf', | |
| 3454 'sprintf', | |
| 3455 'sqrt', | |
| 3456 'sscanf', | |
| 3457 'std', | |
| 3458 'stderr', | |
| 3459 'stdin', | |
| 3460 'stdout', | |
| 3461 'strcat', | |
| 3462 'strchr', | |
| 3463 'strcmp', | |
| 3464 'strcpy', | |
| 3465 'strcspn', | |
| 3466 'strlen', | |
| 3467 'strncat', | |
| 3468 'strncmp', | |
| 3469 'strncpy', | |
| 3470 'strpbrk', | |
| 3471 'strrchr', | |
| 3472 'strspn', | |
| 3473 'strstr', | |
| 3474 'swap', | |
| 3475 'tan', | |
| 3476 'tanh', | |
| 3477 'terminate', | |
| 3478 'to_underlying', | |
| 3479 'tolower', | |
| 3480 'toupper', | |
| 3481 'vfprintf', | |
| 3482 'visit', | |
| 3483 'vprintf', | |
| 3484 'vsprintf' | |
| 3485 ]; | |
| 3486 | |
| 3487 const LITERALS = [ | |
| 3488 'NULL', | |
| 3489 'false', | |
| 3490 'nullopt', | |
| 3491 'nullptr', | |
| 3492 'true' | |
| 3493 ]; | |
| 3494 | |
| 3495 // https://en.cppreference.com/w/cpp/keyword | |
| 3496 const BUILT_IN = [ '_Pragma' ]; | |
| 3497 | |
| 3498 const CPP_KEYWORDS = { | |
| 3499 type: RESERVED_TYPES, | |
| 3500 keyword: RESERVED_KEYWORDS, | |
| 3501 literal: LITERALS, | |
| 3502 built_in: BUILT_IN, | |
| 3503 _type_hints: TYPE_HINTS | |
| 3504 }; | |
| 3505 | |
| 3506 const FUNCTION_DISPATCH = { | |
| 3507 className: 'function.dispatch', | |
| 3508 relevance: 0, | |
| 3509 keywords: { | |
| 3510 // Only for relevance, not highlighting. | |
| 3511 _hint: FUNCTION_HINTS }, | |
| 3512 begin: regex.concat( | |
| 3513 /\b/, | |
| 3514 /(?!decltype)/, | |
| 3515 /(?!if)/, | |
| 3516 /(?!for)/, | |
| 3517 /(?!switch)/, | |
| 3518 /(?!while)/, | |
| 3519 hljs.IDENT_RE, | |
| 3520 regex.lookahead(/(<[^<>]+>|)\s*\(/)) | |
| 3521 }; | |
| 3522 | |
| 3523 const EXPRESSION_CONTAINS = [ | |
| 3524 FUNCTION_DISPATCH, | |
| 3525 PREPROCESSOR, | |
| 3526 CPP_PRIMITIVE_TYPES, | |
| 3527 C_LINE_COMMENT_MODE, | |
| 3528 hljs.C_BLOCK_COMMENT_MODE, | |
| 3529 NUMBERS, | |
| 3530 STRINGS | |
| 3531 ]; | |
| 3532 | |
| 3533 const EXPRESSION_CONTEXT = { | |
| 3534 // This mode covers expression context where we can't expect a function | |
| 3535 // definition and shouldn't highlight anything that looks like one: | |
| 3536 // `return some()`, `else if()`, `(x*sum(1, 2))` | |
| 3537 variants: [ | |
| 3538 { | |
| 3539 begin: /=/, | |
| 3540 end: /;/ | |
| 3541 }, | |
| 3542 { | |
| 3543 begin: /\(/, | |
| 3544 end: /\)/ | |
| 3545 }, | |
| 3546 { | |
| 3547 beginKeywords: 'new throw return else', | |
| 3548 end: /;/ | |
| 3549 } | |
| 3550 ], | |
| 3551 keywords: CPP_KEYWORDS, | |
| 3552 contains: EXPRESSION_CONTAINS.concat([ | |
| 3553 { | |
| 3554 begin: /\(/, | |
| 3555 end: /\)/, | |
| 3556 keywords: CPP_KEYWORDS, | |
| 3557 contains: EXPRESSION_CONTAINS.concat([ 'self' ]), | |
| 3558 relevance: 0 | |
| 3559 } | |
| 3560 ]), | |
| 3561 relevance: 0 | |
| 3562 }; | |
| 3563 | |
| 3564 const FUNCTION_DECLARATION = { | |
| 3565 className: 'function', | |
| 3566 begin: '(' + FUNCTION_TYPE_RE + '[\\*&\\s]+)+' + FUNCTION_TITLE, | |
| 3567 returnBegin: true, | |
| 3568 end: /[{;=]/, | |
| 3569 excludeEnd: true, | |
| 3570 keywords: CPP_KEYWORDS, | |
| 3571 illegal: /[^\w\s\*&:<>.]/, | |
| 3572 contains: [ | |
| 3573 { // to prevent it from being confused as the function title | |
| 3574 begin: DECLTYPE_AUTO_RE, | |
| 3575 keywords: CPP_KEYWORDS, | |
| 3576 relevance: 0 | |
| 3577 }, | |
| 3578 { | |
| 3579 begin: FUNCTION_TITLE, | |
| 3580 returnBegin: true, | |
| 3581 contains: [ TITLE_MODE ], | |
| 3582 relevance: 0 | |
| 3583 }, | |
| 3584 // needed because we do not have look-behind on the below rule | |
| 3585 // to prevent it from grabbing the final : in a :: pair | |
| 3586 { | |
| 3587 begin: /::/, | |
| 3588 relevance: 0 | |
| 3589 }, | |
| 3590 // initializers | |
| 3591 { | |
| 3592 begin: /:/, | |
| 3593 endsWithParent: true, | |
| 3594 contains: [ | |
| 3595 STRINGS, | |
| 3596 NUMBERS | |
| 3597 ] | |
| 3598 }, | |
| 3599 // allow for multiple declarations, e.g.: | |
| 3600 // extern void f(int), g(char); | |
| 3601 { | |
| 3602 relevance: 0, | |
| 3603 match: /,/ | |
| 3604 }, | |
| 3605 { | |
| 3606 className: 'params', | |
| 3607 begin: /\(/, | |
| 3608 end: /\)/, | |
| 3609 keywords: CPP_KEYWORDS, | |
| 3610 relevance: 0, | |
| 3611 contains: [ | |
| 3612 C_LINE_COMMENT_MODE, | |
| 3613 hljs.C_BLOCK_COMMENT_MODE, | |
| 3614 STRINGS, | |
| 3615 NUMBERS, | |
| 3616 CPP_PRIMITIVE_TYPES, | |
| 3617 // Count matching parentheses. | |
| 3618 { | |
| 3619 begin: /\(/, | |
| 3620 end: /\)/, | |
| 3621 keywords: CPP_KEYWORDS, | |
| 3622 relevance: 0, | |
| 3623 contains: [ | |
| 3624 'self', | |
| 3625 C_LINE_COMMENT_MODE, | |
| 3626 hljs.C_BLOCK_COMMENT_MODE, | |
| 3627 STRINGS, | |
| 3628 NUMBERS, | |
| 3629 CPP_PRIMITIVE_TYPES | |
| 3630 ] | |
| 3631 } | |
| 3632 ] | |
| 3633 }, | |
| 3634 CPP_PRIMITIVE_TYPES, | |
| 3635 C_LINE_COMMENT_MODE, | |
| 3636 hljs.C_BLOCK_COMMENT_MODE, | |
| 3637 PREPROCESSOR | |
| 3638 ] | |
| 3639 }; | |
| 3640 | |
| 3641 return { | |
| 3642 name: 'C++', | |
| 3643 aliases: [ | |
| 3644 'cc', | |
| 3645 'c++', | |
| 3646 'h++', | |
| 3647 'hpp', | |
| 3648 'hh', | |
| 3649 'hxx', | |
| 3650 'cxx' | |
| 3651 ], | |
| 3652 keywords: CPP_KEYWORDS, | |
| 3653 illegal: '</', | |
| 3654 classNameAliases: { 'function.dispatch': 'built_in' }, | |
| 3655 contains: [].concat( | |
| 3656 EXPRESSION_CONTEXT, | |
| 3657 FUNCTION_DECLARATION, | |
| 3658 FUNCTION_DISPATCH, | |
| 3659 EXPRESSION_CONTAINS, | |
| 3660 [ | |
| 3661 PREPROCESSOR, | |
| 3662 { // containers: ie, `vector <int> rooms (9);` | |
| 3663 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|flat_map|flat_set)\\s*<(?!<)', | |
| 3664 end: '>', | |
| 3665 keywords: CPP_KEYWORDS, | |
| 3666 contains: [ | |
| 3667 'self', | |
| 3668 CPP_PRIMITIVE_TYPES | |
| 3669 ] | |
| 3670 }, | |
| 3671 { | |
| 3672 begin: hljs.IDENT_RE + '::', | |
| 3673 keywords: CPP_KEYWORDS | |
| 3674 }, | |
| 3675 { | |
| 3676 match: [ | |
| 3677 // extra complexity to deal with `enum class` and `enum struct` | |
| 3678 /\b(?:enum(?:\s+(?:class|struct))?|class|struct|union)/, | |
| 3679 /\s+/, | |
| 3680 /\w+/ | |
| 3681 ], | |
| 3682 className: { | |
| 3683 1: 'keyword', | |
| 3684 3: 'title.class' | |
| 3685 } | |
| 3686 } | |
| 3687 ]) | |
| 3688 }; | |
| 3689 } | |
| 3690 | |
| 3691 return cpp; | |
| 3692 | |
| 3693 })(); | |
| 3694 | |
| 3695 hljs.registerLanguage('cpp', hljsGrammar); | |
| 3696 })();/*! `css` grammar compiled for Highlight.js 11.11.1 */ | |
| 3697 (function(){ | |
| 3698 var hljsGrammar = (function () { | |
| 3699 'use strict'; | |
| 3700 | |
| 3701 const MODES = (hljs) => { | |
| 3702 return { | |
| 3703 IMPORTANT: { | |
| 3704 scope: 'meta', | |
| 3705 begin: '!important' | |
| 3706 }, | |
| 3707 BLOCK_COMMENT: hljs.C_BLOCK_COMMENT_MODE, | |
| 3708 HEXCOLOR: { | |
| 3709 scope: 'number', | |
| 3710 begin: /#(([0-9a-fA-F]{3,4})|(([0-9a-fA-F]{2}){3,4}))\b/ | |
| 3711 }, | |
| 3712 FUNCTION_DISPATCH: { | |
| 3713 className: "built_in", | |
| 3714 begin: /[\w-]+(?=\()/ | |
| 3715 }, | |
| 3716 ATTRIBUTE_SELECTOR_MODE: { | |
| 3717 scope: 'selector-attr', | |
| 3718 begin: /\[/, | |
| 3719 end: /\]/, | |
| 3720 illegal: '$', | |
| 3721 contains: [ | |
| 3722 hljs.APOS_STRING_MODE, | |
| 3723 hljs.QUOTE_STRING_MODE | |
| 3724 ] | |
| 3725 }, | |
| 3726 CSS_NUMBER_MODE: { | |
| 3727 scope: 'number', | |
| 3728 begin: hljs.NUMBER_RE + '(' + | |
| 3729 '%|em|ex|ch|rem' + | |
| 3730 '|vw|vh|vmin|vmax' + | |
| 3731 '|cm|mm|in|pt|pc|px' + | |
| 3732 '|deg|grad|rad|turn' + | |
| 3733 '|s|ms' + | |
| 3734 '|Hz|kHz' + | |
| 3735 '|dpi|dpcm|dppx' + | |
| 3736 ')?', | |
| 3737 relevance: 0 | |
| 3738 }, | |
| 3739 CSS_VARIABLE: { | |
| 3740 className: "attr", | |
| 3741 begin: /--[A-Za-z_][A-Za-z0-9_-]*/ | |
| 3742 } | |
| 3743 }; | |
| 3744 }; | |
| 3745 | |
| 3746 const HTML_TAGS = [ | |
| 3747 'a', | |
| 3748 'abbr', | |
| 3749 'address', | |
| 3750 'article', | |
| 3751 'aside', | |
| 3752 'audio', | |
| 3753 'b', | |
| 3754 'blockquote', | |
| 3755 'body', | |
| 3756 'button', | |
| 3757 'canvas', | |
| 3758 'caption', | |
| 3759 'cite', | |
| 3760 'code', | |
| 3761 'dd', | |
| 3762 'del', | |
| 3763 'details', | |
| 3764 'dfn', | |
| 3765 'div', | |
| 3766 'dl', | |
| 3767 'dt', | |
| 3768 'em', | |
| 3769 'fieldset', | |
| 3770 'figcaption', | |
| 3771 'figure', | |
| 3772 'footer', | |
| 3773 'form', | |
| 3774 'h1', | |
| 3775 'h2', | |
| 3776 'h3', | |
| 3777 'h4', | |
| 3778 'h5', | |
| 3779 'h6', | |
| 3780 'header', | |
| 3781 'hgroup', | |
| 3782 'html', | |
| 3783 'i', | |
| 3784 'iframe', | |
| 3785 'img', | |
| 3786 'input', | |
| 3787 'ins', | |
| 3788 'kbd', | |
| 3789 'label', | |
| 3790 'legend', | |
| 3791 'li', | |
| 3792 'main', | |
| 3793 'mark', | |
| 3794 'menu', | |
| 3795 'nav', | |
| 3796 'object', | |
| 3797 'ol', | |
| 3798 'optgroup', | |
| 3799 'option', | |
| 3800 'p', | |
| 3801 'picture', | |
| 3802 'q', | |
| 3803 'quote', | |
| 3804 'samp', | |
| 3805 'section', | |
| 3806 'select', | |
| 3807 'source', | |
| 3808 'span', | |
| 3809 'strong', | |
| 3810 'summary', | |
| 3811 'sup', | |
| 3812 'table', | |
| 3813 'tbody', | |
| 3814 'td', | |
| 3815 'textarea', | |
| 3816 'tfoot', | |
| 3817 'th', | |
| 3818 'thead', | |
| 3819 'time', | |
| 3820 'tr', | |
| 3821 'ul', | |
| 3822 'var', | |
| 3823 'video' | |
| 3824 ]; | |
| 3825 | |
| 3826 const SVG_TAGS = [ | |
| 3827 'defs', | |
| 3828 'g', | |
| 3829 'marker', | |
| 3830 'mask', | |
| 3831 'pattern', | |
| 3832 'svg', | |
| 3833 'switch', | |
| 3834 'symbol', | |
| 3835 'feBlend', | |
| 3836 'feColorMatrix', | |
| 3837 'feComponentTransfer', | |
| 3838 'feComposite', | |
| 3839 'feConvolveMatrix', | |
| 3840 'feDiffuseLighting', | |
| 3841 'feDisplacementMap', | |
| 3842 'feFlood', | |
| 3843 'feGaussianBlur', | |
| 3844 'feImage', | |
| 3845 'feMerge', | |
| 3846 'feMorphology', | |
| 3847 'feOffset', | |
| 3848 'feSpecularLighting', | |
| 3849 'feTile', | |
| 3850 'feTurbulence', | |
| 3851 'linearGradient', | |
| 3852 'radialGradient', | |
| 3853 'stop', | |
| 3854 'circle', | |
| 3855 'ellipse', | |
| 3856 'image', | |
| 3857 'line', | |
| 3858 'path', | |
| 3859 'polygon', | |
| 3860 'polyline', | |
| 3861 'rect', | |
| 3862 'text', | |
| 3863 'use', | |
| 3864 'textPath', | |
| 3865 'tspan', | |
| 3866 'foreignObject', | |
| 3867 'clipPath' | |
| 3868 ]; | |
| 3869 | |
| 3870 const TAGS = [ | |
| 3871 ...HTML_TAGS, | |
| 3872 ...SVG_TAGS, | |
| 3873 ]; | |
| 3874 | |
| 3875 // Sorting, then reversing makes sure longer attributes/elements like | |
| 3876 // `font-weight` are matched fully instead of getting false positives on say `font` | |
| 3877 | |
| 3878 const MEDIA_FEATURES = [ | |
| 3879 'any-hover', | |
| 3880 'any-pointer', | |
| 3881 'aspect-ratio', | |
| 3882 'color', | |
| 3883 'color-gamut', | |
| 3884 'color-index', | |
| 3885 'device-aspect-ratio', | |
| 3886 'device-height', | |
| 3887 'device-width', | |
| 3888 'display-mode', | |
| 3889 'forced-colors', | |
| 3890 'grid', | |
| 3891 'height', | |
| 3892 'hover', | |
| 3893 'inverted-colors', | |
| 3894 'monochrome', | |
| 3895 'orientation', | |
| 3896 'overflow-block', | |
| 3897 'overflow-inline', | |
| 3898 'pointer', | |
| 3899 'prefers-color-scheme', | |
| 3900 'prefers-contrast', | |
| 3901 'prefers-reduced-motion', | |
| 3902 'prefers-reduced-transparency', | |
| 3903 'resolution', | |
| 3904 'scan', | |
| 3905 'scripting', | |
| 3906 'update', | |
| 3907 'width', | |
| 3908 // TODO: find a better solution? | |
| 3909 'min-width', | |
| 3910 'max-width', | |
| 3911 'min-height', | |
| 3912 'max-height' | |
| 3913 ].sort().reverse(); | |
| 3914 | |
| 3915 // https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-classes | |
| 3916 const PSEUDO_CLASSES = [ | |
| 3917 'active', | |
| 3918 'any-link', | |
| 3919 'blank', | |
| 3920 'checked', | |
| 3921 'current', | |
| 3922 'default', | |
| 3923 'defined', | |
| 3924 'dir', // dir() | |
| 3925 'disabled', | |
| 3926 'drop', | |
| 3927 'empty', | |
| 3928 'enabled', | |
| 3929 'first', | |
| 3930 'first-child', | |
| 3931 'first-of-type', | |
| 3932 'fullscreen', | |
| 3933 'future', | |
| 3934 'focus', | |
| 3935 'focus-visible', | |
| 3936 'focus-within', | |
| 3937 'has', // has() | |
| 3938 'host', // host or host() | |
| 3939 'host-context', // host-context() | |
| 3940 'hover', | |
| 3941 'indeterminate', | |
| 3942 'in-range', | |
| 3943 'invalid', | |
| 3944 'is', // is() | |
| 3945 'lang', // lang() | |
| 3946 'last-child', | |
| 3947 'last-of-type', | |
| 3948 'left', | |
| 3949 'link', | |
| 3950 'local-link', | |
| 3951 'not', // not() | |
| 3952 'nth-child', // nth-child() | |
| 3953 'nth-col', // nth-col() | |
| 3954 'nth-last-child', // nth-last-child() | |
| 3955 'nth-last-col', // nth-last-col() | |
| 3956 'nth-last-of-type', //nth-last-of-type() | |
| 3957 'nth-of-type', //nth-of-type() | |
| 3958 'only-child', | |
| 3959 'only-of-type', | |
| 3960 'optional', | |
| 3961 'out-of-range', | |
| 3962 'past', | |
| 3963 'placeholder-shown', | |
| 3964 'read-only', | |
| 3965 'read-write', | |
| 3966 'required', | |
| 3967 'right', | |
| 3968 'root', | |
| 3969 'scope', | |
| 3970 'target', | |
| 3971 'target-within', | |
| 3972 'user-invalid', | |
| 3973 'valid', | |
| 3974 'visited', | |
| 3975 'where' // where() | |
| 3976 ].sort().reverse(); | |
| 3977 | |
| 3978 // https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-elements | |
| 3979 const PSEUDO_ELEMENTS = [ | |
| 3980 'after', | |
| 3981 'backdrop', | |
| 3982 'before', | |
| 3983 'cue', | |
| 3984 'cue-region', | |
| 3985 'first-letter', | |
| 3986 'first-line', | |
| 3987 'grammar-error', | |
| 3988 'marker', | |
| 3989 'part', | |
| 3990 'placeholder', | |
| 3991 'selection', | |
| 3992 'slotted', | |
| 3993 'spelling-error' | |
| 3994 ].sort().reverse(); | |
| 3995 | |
| 3996 const ATTRIBUTES = [ | |
| 3997 'accent-color', | |
| 3998 'align-content', | |
| 3999 'align-items', | |
| 4000 'align-self', | |
| 4001 'alignment-baseline', | |
| 4002 'all', | |
| 4003 'anchor-name', | |
| 4004 'animation', | |
| 4005 'animation-composition', | |
| 4006 'animation-delay', | |
| 4007 'animation-direction', | |
| 4008 'animation-duration', | |
| 4009 'animation-fill-mode', | |
| 4010 'animation-iteration-count', | |
| 4011 'animation-name', | |
| 4012 'animation-play-state', | |
| 4013 'animation-range', | |
| 4014 'animation-range-end', | |
| 4015 'animation-range-start', | |
| 4016 'animation-timeline', | |
| 4017 'animation-timing-function', | |
| 4018 'appearance', | |
| 4019 'aspect-ratio', | |
| 4020 'backdrop-filter', | |
| 4021 'backface-visibility', | |
| 4022 'background', | |
| 4023 'background-attachment', | |
| 4024 'background-blend-mode', | |
| 4025 'background-clip', | |
| 4026 'background-color', | |
| 4027 'background-image', | |
| 4028 'background-origin', | |
| 4029 'background-position', | |
| 4030 'background-position-x', | |
| 4031 'background-position-y', | |
| 4032 'background-repeat', | |
| 4033 'background-size', | |
| 4034 'baseline-shift', | |
| 4035 'block-size', | |
| 4036 'border', | |
| 4037 'border-block', | |
| 4038 'border-block-color', | |
| 4039 'border-block-end', | |
| 4040 'border-block-end-color', | |
| 4041 'border-block-end-style', | |
| 4042 'border-block-end-width', | |
| 4043 'border-block-start', | |
| 4044 'border-block-start-color', | |
| 4045 'border-block-start-style', | |
| 4046 'border-block-start-width', | |
| 4047 'border-block-style', | |
| 4048 'border-block-width', | |
| 4049 'border-bottom', | |
| 4050 'border-bottom-color', | |
| 4051 'border-bottom-left-radius', | |
| 4052 'border-bottom-right-radius', | |
| 4053 'border-bottom-style', | |
| 4054 'border-bottom-width', | |
| 4055 'border-collapse', | |
| 4056 'border-color', | |
| 4057 'border-end-end-radius', | |
| 4058 'border-end-start-radius', | |
| 4059 'border-image', | |
| 4060 'border-image-outset', | |
| 4061 'border-image-repeat', | |
| 4062 'border-image-slice', | |
| 4063 'border-image-source', | |
| 4064 'border-image-width', | |
| 4065 'border-inline', | |
| 4066 'border-inline-color', | |
| 4067 'border-inline-end', | |
| 4068 'border-inline-end-color', | |
| 4069 'border-inline-end-style', | |
| 4070 'border-inline-end-width', | |
| 4071 'border-inline-start', | |
| 4072 'border-inline-start-color', | |
| 4073 'border-inline-start-style', | |
| 4074 'border-inline-start-width', | |
| 4075 'border-inline-style', | |
| 4076 'border-inline-width', | |
| 4077 'border-left', | |
| 4078 'border-left-color', | |
| 4079 'border-left-style', | |
| 4080 'border-left-width', | |
| 4081 'border-radius', | |
| 4082 'border-right', | |
| 4083 'border-right-color', | |
| 4084 'border-right-style', | |
| 4085 'border-right-width', | |
| 4086 'border-spacing', | |
| 4087 'border-start-end-radius', | |
| 4088 'border-start-start-radius', | |
| 4089 'border-style', | |
| 4090 'border-top', | |
| 4091 'border-top-color', | |
| 4092 'border-top-left-radius', | |
| 4093 'border-top-right-radius', | |
| 4094 'border-top-style', | |
| 4095 'border-top-width', | |
| 4096 'border-width', | |
| 4097 'bottom', | |
| 4098 'box-align', | |
| 4099 'box-decoration-break', | |
| 4100 'box-direction', | |
| 4101 'box-flex', | |
| 4102 'box-flex-group', | |
| 4103 'box-lines', | |
| 4104 'box-ordinal-group', | |
| 4105 'box-orient', | |
| 4106 'box-pack', | |
| 4107 'box-shadow', | |
| 4108 'box-sizing', | |
| 4109 'break-after', | |
| 4110 'break-before', | |
| 4111 'break-inside', | |
| 4112 'caption-side', | |
| 4113 'caret-color', | |
| 4114 'clear', | |
| 4115 'clip', | |
| 4116 'clip-path', | |
| 4117 'clip-rule', | |
| 4118 'color', | |
| 4119 'color-interpolation', | |
| 4120 'color-interpolation-filters', | |
| 4121 'color-profile', | |
| 4122 'color-rendering', | |
| 4123 'color-scheme', | |
| 4124 'column-count', | |
| 4125 'column-fill', | |
| 4126 'column-gap', | |
| 4127 'column-rule', | |
| 4128 'column-rule-color', | |
| 4129 'column-rule-style', | |
| 4130 'column-rule-width', | |
| 4131 'column-span', | |
| 4132 'column-width', | |
| 4133 'columns', | |
| 4134 'contain', | |
| 4135 'contain-intrinsic-block-size', | |
| 4136 'contain-intrinsic-height', | |
| 4137 'contain-intrinsic-inline-size', | |
| 4138 'contain-intrinsic-size', | |
| 4139 'contain-intrinsic-width', | |
| 4140 'container', | |
| 4141 'container-name', | |
| 4142 'container-type', | |
| 4143 'content', | |
| 4144 'content-visibility', | |
| 4145 'counter-increment', | |
| 4146 'counter-reset', | |
| 4147 'counter-set', | |
| 4148 'cue', | |
| 4149 'cue-after', | |
| 4150 'cue-before', | |
| 4151 'cursor', | |
| 4152 'cx', | |
| 4153 'cy', | |
| 4154 'direction', | |
| 4155 'display', | |
| 4156 'dominant-baseline', | |
| 4157 'empty-cells', | |
| 4158 'enable-background', | |
| 4159 'field-sizing', | |
| 4160 'fill', | |
| 4161 'fill-opacity', | |
| 4162 'fill-rule', | |
| 4163 'filter', | |
| 4164 'flex', | |
| 4165 'flex-basis', | |
| 4166 'flex-direction', | |
| 4167 'flex-flow', | |
| 4168 'flex-grow', | |
| 4169 'flex-shrink', | |
| 4170 'flex-wrap', | |
| 4171 'float', | |
| 4172 'flood-color', | |
| 4173 'flood-opacity', | |
| 4174 'flow', | |
| 4175 'font', | |
| 4176 'font-display', | |
| 4177 'font-family', | |
| 4178 'font-feature-settings', | |
| 4179 'font-kerning', | |
| 4180 'font-language-override', | |
| 4181 'font-optical-sizing', | |
| 4182 'font-palette', | |
| 4183 'font-size', | |
| 4184 'font-size-adjust', | |
| 4185 'font-smooth', | |
| 4186 'font-smoothing', | |
| 4187 'font-stretch', | |
| 4188 'font-style', | |
| 4189 'font-synthesis', | |
| 4190 'font-synthesis-position', | |
| 4191 'font-synthesis-small-caps', | |
| 4192 'font-synthesis-style', | |
| 4193 'font-synthesis-weight', | |
| 4194 'font-variant', | |
| 4195 'font-variant-alternates', | |
| 4196 'font-variant-caps', | |
| 4197 'font-variant-east-asian', | |
| 4198 'font-variant-emoji', | |
| 4199 'font-variant-ligatures', | |
| 4200 'font-variant-numeric', | |
| 4201 'font-variant-position', | |
| 4202 'font-variation-settings', | |
| 4203 'font-weight', | |
| 4204 'forced-color-adjust', | |
| 4205 'gap', | |
| 4206 'glyph-orientation-horizontal', | |
| 4207 'glyph-orientation-vertical', | |
| 4208 'grid', | |
| 4209 'grid-area', | |
| 4210 'grid-auto-columns', | |
| 4211 'grid-auto-flow', | |
| 4212 'grid-auto-rows', | |
| 4213 'grid-column', | |
| 4214 'grid-column-end', | |
| 4215 'grid-column-start', | |
| 4216 'grid-gap', | |
| 4217 'grid-row', | |
| 4218 'grid-row-end', | |
| 4219 'grid-row-start', | |
| 4220 'grid-template', | |
| 4221 'grid-template-areas', | |
| 4222 'grid-template-columns', | |
| 4223 'grid-template-rows', | |
| 4224 'hanging-punctuation', | |
| 4225 'height', | |
| 4226 'hyphenate-character', | |
| 4227 'hyphenate-limit-chars', | |
| 4228 'hyphens', | |
| 4229 'icon', | |
| 4230 'image-orientation', | |
| 4231 'image-rendering', | |
| 4232 'image-resolution', | |
| 4233 'ime-mode', | |
| 4234 'initial-letter', | |
| 4235 'initial-letter-align', | |
| 4236 'inline-size', | |
| 4237 'inset', | |
| 4238 'inset-area', | |
| 4239 'inset-block', | |
| 4240 'inset-block-end', | |
| 4241 'inset-block-start', | |
| 4242 'inset-inline', | |
| 4243 'inset-inline-end', | |
| 4244 'inset-inline-start', | |
| 4245 'isolation', | |
| 4246 'justify-content', | |
| 4247 'justify-items', | |
| 4248 'justify-self', | |
| 4249 'kerning', | |
| 4250 'left', | |
| 4251 'letter-spacing', | |
| 4252 'lighting-color', | |
| 4253 'line-break', | |
| 4254 'line-height', | |
| 4255 'line-height-step', | |
| 4256 'list-style', | |
| 4257 'list-style-image', | |
| 4258 'list-style-position', | |
| 4259 'list-style-type', | |
| 4260 'margin', | |
| 4261 'margin-block', | |
| 4262 'margin-block-end', | |
| 4263 'margin-block-start', | |
| 4264 'margin-bottom', | |
| 4265 'margin-inline', | |
| 4266 'margin-inline-end', | |
| 4267 'margin-inline-start', | |
| 4268 'margin-left', | |
| 4269 'margin-right', | |
| 4270 'margin-top', | |
| 4271 'margin-trim', | |
| 4272 'marker', | |
| 4273 'marker-end', | |
| 4274 'marker-mid', | |
| 4275 'marker-start', | |
| 4276 'marks', | |
| 4277 'mask', | |
| 4278 'mask-border', | |
| 4279 'mask-border-mode', | |
| 4280 'mask-border-outset', | |
| 4281 'mask-border-repeat', | |
| 4282 'mask-border-slice', | |
| 4283 'mask-border-source', | |
| 4284 'mask-border-width', | |
| 4285 'mask-clip', | |
| 4286 'mask-composite', | |
| 4287 'mask-image', | |
| 4288 'mask-mode', | |
| 4289 'mask-origin', | |
| 4290 'mask-position', | |
| 4291 'mask-repeat', | |
| 4292 'mask-size', | |
| 4293 'mask-type', | |
| 4294 'masonry-auto-flow', | |
| 4295 'math-depth', | |
| 4296 'math-shift', | |
| 4297 'math-style', | |
| 4298 'max-block-size', | |
| 4299 'max-height', | |
| 4300 'max-inline-size', | |
| 4301 'max-width', | |
| 4302 'min-block-size', | |
| 4303 'min-height', | |
| 4304 'min-inline-size', | |
| 4305 'min-width', | |
| 4306 'mix-blend-mode', | |
| 4307 'nav-down', | |
| 4308 'nav-index', | |
| 4309 'nav-left', | |
| 4310 'nav-right', | |
| 4311 'nav-up', | |
| 4312 'none', | |
| 4313 'normal', | |
| 4314 'object-fit', | |
| 4315 'object-position', | |
| 4316 'offset', | |
| 4317 'offset-anchor', | |
| 4318 'offset-distance', | |
| 4319 'offset-path', | |
| 4320 'offset-position', | |
| 4321 'offset-rotate', | |
| 4322 'opacity', | |
| 4323 'order', | |
| 4324 'orphans', | |
| 4325 'outline', | |
| 4326 'outline-color', | |
| 4327 'outline-offset', | |
| 4328 'outline-style', | |
| 4329 'outline-width', | |
| 4330 'overflow', | |
| 4331 'overflow-anchor', | |
| 4332 'overflow-block', | |
| 4333 'overflow-clip-margin', | |
| 4334 'overflow-inline', | |
| 4335 'overflow-wrap', | |
| 4336 'overflow-x', | |
| 4337 'overflow-y', | |
| 4338 'overlay', | |
| 4339 'overscroll-behavior', | |
| 4340 'overscroll-behavior-block', | |
| 4341 'overscroll-behavior-inline', | |
| 4342 'overscroll-behavior-x', | |
| 4343 'overscroll-behavior-y', | |
| 4344 'padding', | |
| 4345 'padding-block', | |
| 4346 'padding-block-end', | |
| 4347 'padding-block-start', | |
| 4348 'padding-bottom', | |
| 4349 'padding-inline', | |
| 4350 'padding-inline-end', | |
| 4351 'padding-inline-start', | |
| 4352 'padding-left', | |
| 4353 'padding-right', | |
| 4354 'padding-top', | |
| 4355 'page', | |
| 4356 'page-break-after', | |
| 4357 'page-break-before', | |
| 4358 'page-break-inside', | |
| 4359 'paint-order', | |
| 4360 'pause', | |
| 4361 'pause-after', | |
| 4362 'pause-before', | |
| 4363 'perspective', | |
| 4364 'perspective-origin', | |
| 4365 'place-content', | |
| 4366 'place-items', | |
| 4367 'place-self', | |
| 4368 'pointer-events', | |
| 4369 'position', | |
| 4370 'position-anchor', | |
| 4371 'position-visibility', | |
| 4372 'print-color-adjust', | |
| 4373 'quotes', | |
| 4374 'r', | |
| 4375 'resize', | |
| 4376 'rest', | |
| 4377 'rest-after', | |
| 4378 'rest-before', | |
| 4379 'right', | |
| 4380 'rotate', | |
| 4381 'row-gap', | |
| 4382 'ruby-align', | |
| 4383 'ruby-position', | |
| 4384 'scale', | |
| 4385 'scroll-behavior', | |
| 4386 'scroll-margin', | |
| 4387 'scroll-margin-block', | |
| 4388 'scroll-margin-block-end', | |
| 4389 'scroll-margin-block-start', | |
| 4390 'scroll-margin-bottom', | |
| 4391 'scroll-margin-inline', | |
| 4392 'scroll-margin-inline-end', | |
| 4393 'scroll-margin-inline-start', | |
| 4394 'scroll-margin-left', | |
| 4395 'scroll-margin-right', | |
| 4396 'scroll-margin-top', | |
| 4397 'scroll-padding', | |
| 4398 'scroll-padding-block', | |
| 4399 'scroll-padding-block-end', | |
| 4400 'scroll-padding-block-start', | |
| 4401 'scroll-padding-bottom', | |
| 4402 'scroll-padding-inline', | |
| 4403 'scroll-padding-inline-end', | |
| 4404 'scroll-padding-inline-start', | |
| 4405 'scroll-padding-left', | |
| 4406 'scroll-padding-right', | |
| 4407 'scroll-padding-top', | |
| 4408 'scroll-snap-align', | |
| 4409 'scroll-snap-stop', | |
| 4410 'scroll-snap-type', | |
| 4411 'scroll-timeline', | |
| 4412 'scroll-timeline-axis', | |
| 4413 'scroll-timeline-name', | |
| 4414 'scrollbar-color', | |
| 4415 'scrollbar-gutter', | |
| 4416 'scrollbar-width', | |
| 4417 'shape-image-threshold', | |
| 4418 'shape-margin', | |
| 4419 'shape-outside', | |
| 4420 'shape-rendering', | |
| 4421 'speak', | |
| 4422 'speak-as', | |
| 4423 'src', // @font-face | |
| 4424 'stop-color', | |
| 4425 'stop-opacity', | |
| 4426 'stroke', | |
| 4427 'stroke-dasharray', | |
| 4428 'stroke-dashoffset', | |
| 4429 'stroke-linecap', | |
| 4430 'stroke-linejoin', | |
| 4431 'stroke-miterlimit', | |
| 4432 'stroke-opacity', | |
| 4433 'stroke-width', | |
| 4434 'tab-size', | |
| 4435 'table-layout', | |
| 4436 'text-align', | |
| 4437 'text-align-all', | |
| 4438 'text-align-last', | |
| 4439 'text-anchor', | |
| 4440 'text-combine-upright', | |
| 4441 'text-decoration', | |
| 4442 'text-decoration-color', | |
| 4443 'text-decoration-line', | |
| 4444 'text-decoration-skip', | |
| 4445 'text-decoration-skip-ink', | |
| 4446 'text-decoration-style', | |
| 4447 'text-decoration-thickness', | |
| 4448 'text-emphasis', | |
| 4449 'text-emphasis-color', | |
| 4450 'text-emphasis-position', | |
| 4451 'text-emphasis-style', | |
| 4452 'text-indent', | |
| 4453 'text-justify', | |
| 4454 'text-orientation', | |
| 4455 'text-overflow', | |
| 4456 'text-rendering', | |
| 4457 'text-shadow', | |
| 4458 'text-size-adjust', | |
| 4459 'text-transform', | |
| 4460 'text-underline-offset', | |
| 4461 'text-underline-position', | |
| 4462 'text-wrap', | |
| 4463 'text-wrap-mode', | |
| 4464 'text-wrap-style', | |
| 4465 'timeline-scope', | |
| 4466 'top', | |
| 4467 'touch-action', | |
| 4468 'transform', | |
| 4469 'transform-box', | |
| 4470 'transform-origin', | |
| 4471 'transform-style', | |
| 4472 'transition', | |
| 4473 'transition-behavior', | |
| 4474 'transition-delay', | |
| 4475 'transition-duration', | |
| 4476 'transition-property', | |
| 4477 'transition-timing-function', | |
| 4478 'translate', | |
| 4479 'unicode-bidi', | |
| 4480 'user-modify', | |
| 4481 'user-select', | |
| 4482 'vector-effect', | |
| 4483 'vertical-align', | |
| 4484 'view-timeline', | |
| 4485 'view-timeline-axis', | |
| 4486 'view-timeline-inset', | |
| 4487 'view-timeline-name', | |
| 4488 'view-transition-name', | |
| 4489 'visibility', | |
| 4490 'voice-balance', | |
| 4491 'voice-duration', | |
| 4492 'voice-family', | |
| 4493 'voice-pitch', | |
| 4494 'voice-range', | |
| 4495 'voice-rate', | |
| 4496 'voice-stress', | |
| 4497 'voice-volume', | |
| 4498 'white-space', | |
| 4499 'white-space-collapse', | |
| 4500 'widows', | |
| 4501 'width', | |
| 4502 'will-change', | |
| 4503 'word-break', | |
| 4504 'word-spacing', | |
| 4505 'word-wrap', | |
| 4506 'writing-mode', | |
| 4507 'x', | |
| 4508 'y', | |
| 4509 'z-index', | |
| 4510 'zoom' | |
| 4511 ].sort().reverse(); | |
| 4512 | |
| 4513 /* | |
| 4514 Language: CSS | |
| 4515 Category: common, css, web | |
| 4516 Website: https://developer.mozilla.org/en-US/docs/Web/CSS | |
| 4517 */ | |
| 4518 | |
| 4519 | |
| 4520 /** @type LanguageFn */ | |
| 4521 function css(hljs) { | |
| 4522 const regex = hljs.regex; | |
| 4523 const modes = MODES(hljs); | |
| 4524 const VENDOR_PREFIX = { begin: /-(webkit|moz|ms|o)-(?=[a-z])/ }; | |
| 4525 const AT_MODIFIERS = "and or not only"; | |
| 4526 const AT_PROPERTY_RE = /@-?\w[\w]*(-\w+)*/; // @-webkit-keyframes | |
| 4527 const IDENT_RE = '[a-zA-Z-][a-zA-Z0-9_-]*'; | |
| 4528 const STRINGS = [ | |
| 4529 hljs.APOS_STRING_MODE, | |
| 4530 hljs.QUOTE_STRING_MODE | |
| 4531 ]; | |
| 4532 | |
| 4533 return { | |
| 4534 name: 'CSS', | |
| 4535 case_insensitive: true, | |
| 4536 illegal: /[=|'\$]/, | |
| 4537 keywords: { keyframePosition: "from to" }, | |
| 4538 classNameAliases: { | |
| 4539 // for visual continuity with `tag {}` and because we | |
| 4540 // don't have a great class for this? | |
| 4541 keyframePosition: "selector-tag" }, | |
| 4542 contains: [ | |
| 4543 modes.BLOCK_COMMENT, | |
| 4544 VENDOR_PREFIX, | |
| 4545 // to recognize keyframe 40% etc which are outside the scope of our | |
| 4546 // attribute value mode | |
| 4547 modes.CSS_NUMBER_MODE, | |
| 4548 { | |
| 4549 className: 'selector-id', | |
| 4550 begin: /#[A-Za-z0-9_-]+/, | |
| 4551 relevance: 0 | |
| 4552 }, | |
| 4553 { | |
| 4554 className: 'selector-class', | |
| 4555 begin: '\\.' + IDENT_RE, | |
| 4556 relevance: 0 | |
| 4557 }, | |
| 4558 modes.ATTRIBUTE_SELECTOR_MODE, | |
| 4559 { | |
| 4560 className: 'selector-pseudo', | |
| 4561 variants: [ | |
| 4562 { begin: ':(' + PSEUDO_CLASSES.join('|') + ')' }, | |
| 4563 { begin: ':(:)?(' + PSEUDO_ELEMENTS.join('|') + ')' } | |
| 4564 ] | |
| 4565 }, | |
| 4566 // we may actually need this (12/2020) | |
| 4567 // { // pseudo-selector params | |
| 4568 // begin: /\(/, | |
| 4569 // end: /\)/, | |
| 4570 // contains: [ hljs.CSS_NUMBER_MODE ] | |
| 4571 // }, | |
| 4572 modes.CSS_VARIABLE, | |
| 4573 { | |
| 4574 className: 'attribute', | |
| 4575 begin: '\\b(' + ATTRIBUTES.join('|') + ')\\b' | |
| 4576 }, | |
| 4577 // attribute values | |
| 4578 { | |
| 4579 begin: /:/, | |
| 4580 end: /[;}{]/, | |
| 4581 contains: [ | |
| 4582 modes.BLOCK_COMMENT, | |
| 4583 modes.HEXCOLOR, | |
| 4584 modes.IMPORTANT, | |
| 4585 modes.CSS_NUMBER_MODE, | |
| 4586 ...STRINGS, | |
| 4587 // needed to highlight these as strings and to avoid issues with | |
| 4588 // illegal characters that might be inside urls that would tigger the | |
| 4589 // languages illegal stack | |
| 4590 { | |
| 4591 begin: /(url|data-uri)\(/, | |
| 4592 end: /\)/, | |
| 4593 relevance: 0, // from keywords | |
| 4594 keywords: { built_in: "url data-uri" }, | |
| 4595 contains: [ | |
| 4596 ...STRINGS, | |
| 4597 { | |
| 4598 className: "string", | |
| 4599 // any character other than `)` as in `url()` will be the start | |
| 4600 // of a string, which ends with `)` (from the parent mode) | |
| 4601 begin: /[^)]/, | |
| 4602 endsWithParent: true, | |
| 4603 excludeEnd: true | |
| 4604 } | |
| 4605 ] | |
| 4606 }, | |
| 4607 modes.FUNCTION_DISPATCH | |
| 4608 ] | |
| 4609 }, | |
| 4610 { | |
| 4611 begin: regex.lookahead(/@/), | |
| 4612 end: '[{;]', | |
| 4613 relevance: 0, | |
| 4614 illegal: /:/, // break on Less variables @var: ... | |
| 4615 contains: [ | |
| 4616 { | |
| 4617 className: 'keyword', | |
| 4618 begin: AT_PROPERTY_RE | |
| 4619 }, | |
| 4620 { | |
| 4621 begin: /\s/, | |
| 4622 endsWithParent: true, | |
| 4623 excludeEnd: true, | |
| 4624 relevance: 0, | |
| 4625 keywords: { | |
| 4626 $pattern: /[a-z-]+/, | |
| 4627 keyword: AT_MODIFIERS, | |
| 4628 attribute: MEDIA_FEATURES.join(" ") | |
| 4629 }, | |
| 4630 contains: [ | |
| 4631 { | |
| 4632 begin: /[a-z-]+(?=:)/, | |
| 4633 className: "attribute" | |
| 4634 }, | |
| 4635 ...STRINGS, | |
| 4636 modes.CSS_NUMBER_MODE | |
| 4637 ] | |
| 4638 } | |
| 4639 ] | |
| 4640 }, | |
| 4641 { | |
| 4642 className: 'selector-tag', | |
| 4643 begin: '\\b(' + TAGS.join('|') + ')\\b' | |
| 4644 } | |
| 4645 ] | |
| 4646 }; | |
| 4647 } | |
| 4648 | |
| 4649 return css; | |
| 4650 | |
| 4651 })(); | |
| 4652 | |
| 4653 hljs.registerLanguage('css', hljsGrammar); | |
| 4654 })();/*! `diff` grammar compiled for Highlight.js 11.11.1 */ | |
| 4655 (function(){ | |
| 4656 var hljsGrammar = (function () { | |
| 4657 'use strict'; | |
| 4658 | |
| 4659 /* | |
| 4660 Language: Diff | |
| 4661 Description: Unified and context diff | |
| 4662 Author: Vasily Polovnyov <[email protected]> | |
| 4663 Website: https://www.gnu.org/software/diffutils/ | |
| 4664 Category: common | |
| 4665 */ | |
| 4666 | |
| 4667 /** @type LanguageFn */ | |
| 4668 function diff(hljs) { | |
| 4669 const regex = hljs.regex; | |
| 4670 return { | |
| 4671 name: 'Diff', | |
| 4672 aliases: [ 'patch' ], | |
| 4673 contains: [ | |
| 4674 { | |
| 4675 className: 'meta', | |
| 4676 relevance: 10, | |
| 4677 match: regex.either( | |
| 4678 /^@@ +-\d+,\d+ +\+\d+,\d+ +@@/, | |
| 4679 /^\*\*\* +\d+,\d+ +\*\*\*\*$/, | |
| 4680 /^--- +\d+,\d+ +----$/ | |
| 4681 ) | |
| 4682 }, | |
| 4683 { | |
| 4684 className: 'comment', | |
| 4685 variants: [ | |
| 4686 { | |
| 4687 begin: regex.either( | |
| 4688 /Index: /, | |
| 4689 /^index/, | |
| 4690 /={3,}/, | |
| 4691 /^-{3}/, | |
| 4692 /^\*{3} /, | |
| 4693 /^\+{3}/, | |
| 4694 /^diff --git/ | |
| 4695 ), | |
| 4696 end: /$/ | |
| 4697 }, | |
| 4698 { match: /^\*{15}$/ } | |
| 4699 ] | |
| 4700 }, | |
| 4701 { | |
| 4702 className: 'addition', | |
| 4703 begin: /^\+/, | |
| 4704 end: /$/ | |
| 4705 }, | |
| 4706 { | |
| 4707 className: 'deletion', | |
| 4708 begin: /^-/, | |
| 4709 end: /$/ | |
| 4710 }, | |
| 4711 { | |
| 4712 className: 'addition', | |
| 4713 begin: /^!/, | |
| 4714 end: /$/ | |
| 4715 } | |
| 4716 ] | |
| 4717 }; | |
| 4718 } | |
| 4719 | |
| 4720 return diff; | |
| 4721 | |
| 4722 })(); | |
| 4723 | |
| 4724 hljs.registerLanguage('diff', hljsGrammar); | |
| 4725 })();/*! `graphql` grammar compiled for Highlight.js 11.11.1 */ | |
| 4726 (function(){ | |
| 4727 var hljsGrammar = (function () { | |
| 4728 'use strict'; | |
| 4729 | |
| 4730 /* | |
| 4731 Language: GraphQL | |
| 4732 Author: John Foster (GH jf990), and others | |
| 4733 Description: GraphQL is a query language for APIs | |
| 4734 Category: web, common | |
| 4735 */ | |
| 4736 | |
| 4737 /** @type LanguageFn */ | |
| 4738 function graphql(hljs) { | |
| 4739 const regex = hljs.regex; | |
| 4740 const GQL_NAME = /[_A-Za-z][_0-9A-Za-z]*/; | |
| 4741 return { | |
| 4742 name: "GraphQL", | |
| 4743 aliases: [ "gql" ], | |
| 4744 case_insensitive: true, | |
| 4745 disableAutodetect: false, | |
| 4746 keywords: { | |
| 4747 keyword: [ | |
| 4748 "query", | |
| 4749 "mutation", | |
| 4750 "subscription", | |
| 4751 "type", | |
| 4752 "input", | |
| 4753 "schema", | |
| 4754 "directive", | |
| 4755 "interface", | |
| 4756 "union", | |
| 4757 "scalar", | |
| 4758 "fragment", | |
| 4759 "enum", | |
| 4760 "on" | |
| 4761 ], | |
| 4762 literal: [ | |
| 4763 "true", | |
| 4764 "false", | |
| 4765 "null" | |
| 4766 ] | |
| 4767 }, | |
| 4768 contains: [ | |
| 4769 hljs.HASH_COMMENT_MODE, | |
| 4770 hljs.QUOTE_STRING_MODE, | |
| 4771 hljs.NUMBER_MODE, | |
| 4772 { | |
| 4773 scope: "punctuation", | |
| 4774 match: /[.]{3}/, | |
| 4775 relevance: 0 | |
| 4776 }, | |
| 4777 { | |
| 4778 scope: "punctuation", | |
| 4779 begin: /[\!\(\)\:\=\[\]\{\|\}]{1}/, | |
| 4780 relevance: 0 | |
| 4781 }, | |
| 4782 { | |
| 4783 scope: "variable", | |
| 4784 begin: /\$/, | |
| 4785 end: /\W/, | |
| 4786 excludeEnd: true, | |
| 4787 relevance: 0 | |
| 4788 }, | |
| 4789 { | |
| 4790 scope: "meta", | |
| 4791 match: /@\w+/, | |
| 4792 excludeEnd: true | |
| 4793 }, | |
| 4794 { | |
| 4795 scope: "symbol", | |
| 4796 begin: regex.concat(GQL_NAME, regex.lookahead(/\s*:/)), | |
| 4797 relevance: 0 | |
| 4798 } | |
| 4799 ], | |
| 4800 illegal: [ | |
| 4801 /[;<']/, | |
| 4802 /BEGIN/ | |
| 4803 ] | |
| 4804 }; | |
| 4805 } | |
| 4806 | |
| 4807 return graphql; | |
| 4808 | |
| 4809 })(); | |
| 4810 | |
| 4811 hljs.registerLanguage('graphql', hljsGrammar); | |
| 4812 })();/*! `http` grammar compiled for Highlight.js 11.11.1 */ | |
| 4813 (function(){ | |
| 4814 var hljsGrammar = (function () { | |
| 4815 'use strict'; | |
| 4816 | |
| 4817 /* | |
| 4818 Language: HTTP | |
| 4819 Description: HTTP request and response headers with automatic body highlighting | |
| 4820 Author: Ivan Sagalaev <[email protected]> | |
| 4821 Category: protocols, web | |
| 4822 Website: https://developer.mozilla.org/en-US/docs/Web/HTTP/Overview | |
| 4823 */ | |
| 4824 | |
| 4825 function http(hljs) { | |
| 4826 const regex = hljs.regex; | |
| 4827 const VERSION = 'HTTP/([32]|1\\.[01])'; | |
| 4828 const HEADER_NAME = /[A-Za-z][A-Za-z0-9-]*/; | |
| 4829 const HEADER = { | |
| 4830 className: 'attribute', | |
| 4831 begin: regex.concat('^', HEADER_NAME, '(?=\\:\\s)'), | |
| 4832 starts: { contains: [ | |
| 4833 { | |
| 4834 className: "punctuation", | |
| 4835 begin: /: /, | |
| 4836 relevance: 0, | |
| 4837 starts: { | |
| 4838 end: '$', | |
| 4839 relevance: 0 | |
| 4840 } | |
| 4841 } | |
| 4842 ] } | |
| 4843 }; | |
| 4844 const HEADERS_AND_BODY = [ | |
| 4845 HEADER, | |
| 4846 { | |
| 4847 begin: '\\n\\n', | |
| 4848 starts: { | |
| 4849 subLanguage: [], | |
| 4850 endsWithParent: true | |
| 4851 } | |
| 4852 } | |
| 4853 ]; | |
| 4854 | |
| 4855 return { | |
| 4856 name: 'HTTP', | |
| 4857 aliases: [ 'https' ], | |
| 4858 illegal: /\S/, | |
| 4859 contains: [ | |
| 4860 // response | |
| 4861 { | |
| 4862 begin: '^(?=' + VERSION + " \\d{3})", | |
| 4863 end: /$/, | |
| 4864 contains: [ | |
| 4865 { | |
| 4866 className: "meta", | |
| 4867 begin: VERSION | |
| 4868 }, | |
| 4869 { | |
| 4870 className: 'number', | |
| 4871 begin: '\\b\\d{3}\\b' | |
| 4872 } | |
| 4873 ], | |
| 4874 starts: { | |
| 4875 end: /\b\B/, | |
| 4876 illegal: /\S/, | |
| 4877 contains: HEADERS_AND_BODY | |
| 4878 } | |
| 4879 }, | |
| 4880 // request | |
| 4881 { | |
| 4882 begin: '(?=^[A-Z]+ (.*?) ' + VERSION + '$)', | |
| 4883 end: /$/, | |
| 4884 contains: [ | |
| 4885 { | |
| 4886 className: 'string', | |
| 4887 begin: ' ', | |
| 4888 end: ' ', | |
| 4889 excludeBegin: true, | |
| 4890 excludeEnd: true | |
| 4891 }, | |
| 4892 { | |
| 4893 className: "meta", | |
| 4894 begin: VERSION | |
| 4895 }, | |
| 4896 { | |
| 4897 className: 'keyword', | |
| 4898 begin: '[A-Z]+' | |
| 4899 } | |
| 4900 ], | |
| 4901 starts: { | |
| 4902 end: /\b\B/, | |
| 4903 illegal: /\S/, | |
| 4904 contains: HEADERS_AND_BODY | |
| 4905 } | |
| 4906 }, | |
| 4907 // to allow headers to work even without a preamble | |
| 4908 hljs.inherit(HEADER, { relevance: 0 }) | |
| 4909 ] | |
| 4910 }; | |
| 4911 } | |
| 4912 | |
| 4913 return http; | |
| 4914 | |
| 4915 })(); | |
| 4916 | |
| 4917 hljs.registerLanguage('http', hljsGrammar); | |
| 4918 })();/*! `javascript` grammar compiled for Highlight.js 11.11.1 */ | |
| 4919 (function(){ | |
| 4920 var hljsGrammar = (function () { | |
| 4921 'use strict'; | |
| 4922 | |
| 4923 const IDENT_RE = '[A-Za-z$_][0-9A-Za-z$_]*'; | |
| 4924 const KEYWORDS = [ | |
| 4925 "as", // for exports | |
| 4926 "in", | |
| 4927 "of", | |
| 4928 "if", | |
| 4929 "for", | |
| 4930 "while", | |
| 4931 "finally", | |
| 4932 "var", | |
| 4933 "new", | |
| 4934 "function", | |
| 4935 "do", | |
| 4936 "return", | |
| 4937 "void", | |
| 4938 "else", | |
| 4939 "break", | |
| 4940 "catch", | |
| 4941 "instanceof", | |
| 4942 "with", | |
| 4943 "throw", | |
| 4944 "case", | |
| 4945 "default", | |
| 4946 "try", | |
| 4947 "switch", | |
| 4948 "continue", | |
| 4949 "typeof", | |
| 4950 "delete", | |
| 4951 "let", | |
| 4952 "yield", | |
| 4953 "const", | |
| 4954 "class", | |
| 4955 // JS handles these with a special rule | |
| 4956 // "get", | |
| 4957 // "set", | |
| 4958 "debugger", | |
| 4959 "async", | |
| 4960 "await", | |
| 4961 "static", | |
| 4962 "import", | |
| 4963 "from", | |
| 4964 "export", | |
| 4965 "extends", | |
| 4966 // It's reached stage 3, which is "recommended for implementation": | |
| 4967 "using" | |
| 4968 ]; | |
| 4969 const LITERALS = [ | |
| 4970 "true", | |
| 4971 "false", | |
| 4972 "null", | |
| 4973 "undefined", | |
| 4974 "NaN", | |
| 4975 "Infinity" | |
| 4976 ]; | |
| 4977 | |
| 4978 // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects | |
| 4979 const TYPES = [ | |
| 4980 // Fundamental objects | |
| 4981 "Object", | |
| 4982 "Function", | |
| 4983 "Boolean", | |
| 4984 "Symbol", | |
| 4985 // numbers and dates | |
| 4986 "Math", | |
| 4987 "Date", | |
| 4988 "Number", | |
| 4989 "BigInt", | |
| 4990 // text | |
| 4991 "String", | |
| 4992 "RegExp", | |
| 4993 // Indexed collections | |
| 4994 "Array", | |
| 4995 "Float32Array", | |
| 4996 "Float64Array", | |
| 4997 "Int8Array", | |
| 4998 "Uint8Array", | |
| 4999 "Uint8ClampedArray", | |
| 5000 "Int16Array", | |
| 5001 "Int32Array", | |
| 5002 "Uint16Array", | |
| 5003 "Uint32Array", | |
| 5004 "BigInt64Array", | |
| 5005 "BigUint64Array", | |
| 5006 // Keyed collections | |
| 5007 "Set", | |
| 5008 "Map", | |
| 5009 "WeakSet", | |
| 5010 "WeakMap", | |
| 5011 // Structured data | |
| 5012 "ArrayBuffer", | |
| 5013 "SharedArrayBuffer", | |
| 5014 "Atomics", | |
| 5015 "DataView", | |
| 5016 "JSON", | |
| 5017 // Control abstraction objects | |
| 5018 "Promise", | |
| 5019 "Generator", | |
| 5020 "GeneratorFunction", | |
| 5021 "AsyncFunction", | |
| 5022 // Reflection | |
| 5023 "Reflect", | |
| 5024 "Proxy", | |
| 5025 // Internationalization | |
| 5026 "Intl", | |
| 5027 // WebAssembly | |
| 5028 "WebAssembly" | |
| 5029 ]; | |
| 5030 | |
| 5031 const ERROR_TYPES = [ | |
| 5032 "Error", | |
| 5033 "EvalError", | |
| 5034 "InternalError", | |
| 5035 "RangeError", | |
| 5036 "ReferenceError", | |
| 5037 "SyntaxError", | |
| 5038 "TypeError", | |
| 5039 "URIError" | |
| 5040 ]; | |
| 5041 | |
| 5042 const BUILT_IN_GLOBALS = [ | |
| 5043 "setInterval", | |
| 5044 "setTimeout", | |
| 5045 "clearInterval", | |
| 5046 "clearTimeout", | |
| 5047 | |
| 5048 "require", | |
| 5049 "exports", | |
| 5050 | |
| 5051 "eval", | |
| 5052 "isFinite", | |
| 5053 "isNaN", | |
| 5054 "parseFloat", | |
| 5055 "parseInt", | |
| 5056 "decodeURI", | |
| 5057 "decodeURIComponent", | |
| 5058 "encodeURI", | |
| 5059 "encodeURIComponent", | |
| 5060 "escape", | |
| 5061 "unescape" | |
| 5062 ]; | |
| 5063 | |
| 5064 const BUILT_IN_VARIABLES = [ | |
| 5065 "arguments", | |
| 5066 "this", | |
| 5067 "super", | |
| 5068 "console", | |
| 5069 "window", | |
| 5070 "document", | |
| 5071 "localStorage", | |
| 5072 "sessionStorage", | |
| 5073 "module", | |
| 5074 "global" // Node.js | |
| 5075 ]; | |
| 5076 | |
| 5077 const BUILT_INS = [].concat( | |
| 5078 BUILT_IN_GLOBALS, | |
| 5079 TYPES, | |
| 5080 ERROR_TYPES | |
| 5081 ); | |
| 5082 | |
| 5083 /* | |
| 5084 Language: JavaScript | |
| 5085 Description: JavaScript (JS) is a lightweight, interpreted, or just-in-time compiled programming language with first-class functions. | |
| 5086 Category: common, scripting, web | |
| 5087 Website: https://developer.mozilla.org/en-US/docs/Web/JavaScript | |
| 5088 */ | |
| 5089 | |
| 5090 | |
| 5091 /** @type LanguageFn */ | |
| 5092 function javascript(hljs) { | |
| 5093 const regex = hljs.regex; | |
| 5094 /** | |
| 5095 * Takes a string like "<Booger" and checks to see | |
| 5096 * if we can find a matching "</Booger" later in the | |
| 5097 * content. | |
| 5098 * @param {RegExpMatchArray} match | |
| 5099 * @param {{after:number}} param1 | |
| 5100 */ | |
| 5101 const hasClosingTag = (match, { after }) => { | |
| 5102 const tag = "</" + match[0].slice(1); | |
| 5103 const pos = match.input.indexOf(tag, after); | |
| 5104 return pos !== -1; | |
| 5105 }; | |
| 5106 | |
| 5107 const IDENT_RE$1 = IDENT_RE; | |
| 5108 const FRAGMENT = { | |
| 5109 begin: '<>', | |
| 5110 end: '</>' | |
| 5111 }; | |
| 5112 // to avoid some special cases inside isTrulyOpeningTag | |
| 5113 const XML_SELF_CLOSING = /<[A-Za-z0-9\\._:-]+\s*\/>/; | |
| 5114 const XML_TAG = { | |
| 5115 begin: /<[A-Za-z0-9\\._:-]+/, | |
| 5116 end: /\/[A-Za-z0-9\\._:-]+>|\/>/, | |
| 5117 /** | |
| 5118 * @param {RegExpMatchArray} match | |
| 5119 * @param {CallbackResponse} response | |
| 5120 */ | |
| 5121 isTrulyOpeningTag: (match, response) => { | |
| 5122 const afterMatchIndex = match[0].length + match.index; | |
| 5123 const nextChar = match.input[afterMatchIndex]; | |
| 5124 if ( | |
| 5125 // HTML should not include another raw `<` inside a tag | |
| 5126 // nested type? | |
| 5127 // `<Array<Array<number>>`, etc. | |
| 5128 nextChar === "<" || | |
| 5129 // the , gives away that this is not HTML | |
| 5130 // `<T, A extends keyof T, V>` | |
| 5131 nextChar === "," | |
| 5132 ) { | |
| 5133 response.ignoreMatch(); | |
| 5134 return; | |
| 5135 } | |
| 5136 | |
| 5137 // `<something>` | |
| 5138 // Quite possibly a tag, lets look for a matching closing tag... | |
| 5139 if (nextChar === ">") { | |
| 5140 // if we cannot find a matching closing tag, then we | |
| 5141 // will ignore it | |
| 5142 if (!hasClosingTag(match, { after: afterMatchIndex })) { | |
| 5143 response.ignoreMatch(); | |
| 5144 } | |
| 5145 } | |
| 5146 | |
| 5147 // `<blah />` (self-closing) | |
| 5148 // handled by simpleSelfClosing rule | |
| 5149 | |
| 5150 let m; | |
| 5151 const afterMatch = match.input.substring(afterMatchIndex); | |
| 5152 | |
| 5153 // some more template typing stuff | |
| 5154 // <T = any>(key?: string) => Modify< | |
| 5155 if ((m = afterMatch.match(/^\s*=/))) { | |
| 5156 response.ignoreMatch(); | |
| 5157 return; | |
| 5158 } | |
| 5159 | |
| 5160 // `<From extends string>` | |
| 5161 // technically this could be HTML, but it smells like a type | |
| 5162 // NOTE: This is ugh, but added specifically for https://github.com/highlightjs/highlight.js/issues/3276 | |
| 5163 if ((m = afterMatch.match(/^\s+extends\s+/))) { | |
| 5164 if (m.index === 0) { | |
| 5165 response.ignoreMatch(); | |
| 5166 // eslint-disable-next-line no-useless-return | |
| 5167 return; | |
| 5168 } | |
| 5169 } | |
| 5170 } | |
| 5171 }; | |
| 5172 const KEYWORDS$1 = { | |
| 5173 $pattern: IDENT_RE, | |
| 5174 keyword: KEYWORDS, | |
| 5175 literal: LITERALS, | |
| 5176 built_in: BUILT_INS, | |
| 5177 "variable.language": BUILT_IN_VARIABLES | |
| 5178 }; | |
| 5179 | |
| 5180 // https://tc39.es/ecma262/#sec-literals-numeric-literals | |
| 5181 const decimalDigits = '[0-9](_?[0-9])*'; | |
| 5182 const frac = `\\.(${decimalDigits})`; | |
| 5183 // DecimalIntegerLiteral, including Annex B NonOctalDecimalIntegerLiteral | |
| 5184 // https://tc39.es/ecma262/#sec-additional-syntax-numeric-literals | |
| 5185 const decimalInteger = `0|[1-9](_?[0-9])*|0[0-7]*[89][0-9]*`; | |
| 5186 const NUMBER = { | |
| 5187 className: 'number', | |
| 5188 variants: [ | |
| 5189 // DecimalLiteral | |
| 5190 { begin: `(\\b(${decimalInteger})((${frac})|\\.)?|(${frac}))` + | |
| 5191 `[eE][+-]?(${decimalDigits})\\b` }, | |
| 5192 { begin: `\\b(${decimalInteger})\\b((${frac})\\b|\\.)?|(${frac})\\b` }, | |
| 5193 | |
| 5194 // DecimalBigIntegerLiteral | |
| 5195 { begin: `\\b(0|[1-9](_?[0-9])*)n\\b` }, | |
| 5196 | |
| 5197 // NonDecimalIntegerLiteral | |
| 5198 { begin: "\\b0[xX][0-9a-fA-F](_?[0-9a-fA-F])*n?\\b" }, | |
| 5199 { begin: "\\b0[bB][0-1](_?[0-1])*n?\\b" }, | |
| 5200 { begin: "\\b0[oO][0-7](_?[0-7])*n?\\b" }, | |
| 5201 | |
| 5202 // LegacyOctalIntegerLiteral (does not include underscore separators) | |
| 5203 // https://tc39.es/ecma262/#sec-additional-syntax-numeric-literals | |
| 5204 { begin: "\\b0[0-7]+n?\\b" }, | |
| 5205 ], | |
| 5206 relevance: 0 | |
| 5207 }; | |
| 5208 | |
| 5209 const SUBST = { | |
| 5210 className: 'subst', | |
| 5211 begin: '\\$\\{', | |
| 5212 end: '\\}', | |
| 5213 keywords: KEYWORDS$1, | |
| 5214 contains: [] // defined later | |
| 5215 }; | |
| 5216 const HTML_TEMPLATE = { | |
| 5217 begin: '\.?html`', | |
| 5218 end: '', | |
| 5219 starts: { | |
| 5220 end: '`', | |
| 5221 returnEnd: false, | |
| 5222 contains: [ | |
| 5223 hljs.BACKSLASH_ESCAPE, | |
| 5224 SUBST | |
| 5225 ], | |
| 5226 subLanguage: 'xml' | |
| 5227 } | |
| 5228 }; | |
| 5229 const CSS_TEMPLATE = { | |
| 5230 begin: '\.?css`', | |
| 5231 end: '', | |
| 5232 starts: { | |
| 5233 end: '`', | |
| 5234 returnEnd: false, | |
| 5235 contains: [ | |
| 5236 hljs.BACKSLASH_ESCAPE, | |
| 5237 SUBST | |
| 5238 ], | |
| 5239 subLanguage: 'css' | |
| 5240 } | |
| 5241 }; | |
| 5242 const GRAPHQL_TEMPLATE = { | |
| 5243 begin: '\.?gql`', | |
| 5244 end: '', | |
| 5245 starts: { | |
| 5246 end: '`', | |
| 5247 returnEnd: false, | |
| 5248 contains: [ | |
| 5249 hljs.BACKSLASH_ESCAPE, | |
| 5250 SUBST | |
| 5251 ], | |
| 5252 subLanguage: 'graphql' | |
| 5253 } | |
| 5254 }; | |
| 5255 const TEMPLATE_STRING = { | |
| 5256 className: 'string', | |
| 5257 begin: '`', | |
| 5258 end: '`', | |
| 5259 contains: [ | |
| 5260 hljs.BACKSLASH_ESCAPE, | |
| 5261 SUBST | |
| 5262 ] | |
| 5263 }; | |
| 5264 const JSDOC_COMMENT = hljs.COMMENT( | |
| 5265 /\/\*\*(?!\/)/, | |
| 5266 '\\*/', | |
| 5267 { | |
| 5268 relevance: 0, | |
| 5269 contains: [ | |
| 5270 { | |
| 5271 begin: '(?=@[A-Za-z]+)', | |
| 5272 relevance: 0, | |
| 5273 contains: [ | |
| 5274 { | |
| 5275 className: 'doctag', | |
| 5276 begin: '@[A-Za-z]+' | |
| 5277 }, | |
| 5278 { | |
| 5279 className: 'type', | |
| 5280 begin: '\\{', | |
| 5281 end: '\\}', | |
| 5282 excludeEnd: true, | |
| 5283 excludeBegin: true, | |
| 5284 relevance: 0 | |
| 5285 }, | |
| 5286 { | |
| 5287 className: 'variable', | |
| 5288 begin: IDENT_RE$1 + '(?=\\s*(-)|$)', | |
| 5289 endsParent: true, | |
| 5290 relevance: 0 | |
| 5291 }, | |
| 5292 // eat spaces (not newlines) so we can find | |
| 5293 // types or variables | |
| 5294 { | |
| 5295 begin: /(?=[^\n])\s/, | |
| 5296 relevance: 0 | |
| 5297 } | |
| 5298 ] | |
| 5299 } | |
| 5300 ] | |
| 5301 } | |
| 5302 ); | |
| 5303 const COMMENT = { | |
| 5304 className: "comment", | |
| 5305 variants: [ | |
| 5306 JSDOC_COMMENT, | |
| 5307 hljs.C_BLOCK_COMMENT_MODE, | |
| 5308 hljs.C_LINE_COMMENT_MODE | |
| 5309 ] | |
| 5310 }; | |
| 5311 const SUBST_INTERNALS = [ | |
| 5312 hljs.APOS_STRING_MODE, | |
| 5313 hljs.QUOTE_STRING_MODE, | |
| 5314 HTML_TEMPLATE, | |
| 5315 CSS_TEMPLATE, | |
| 5316 GRAPHQL_TEMPLATE, | |
| 5317 TEMPLATE_STRING, | |
| 5318 // Skip numbers when they are part of a variable name | |
| 5319 { match: /\$\d+/ }, | |
| 5320 NUMBER, | |
| 5321 // This is intentional: | |
| 5322 // See https://github.com/highlightjs/highlight.js/issues/3288 | |
| 5323 // hljs.REGEXP_MODE | |
| 5324 ]; | |
| 5325 SUBST.contains = SUBST_INTERNALS | |
| 5326 .concat({ | |
| 5327 // we need to pair up {} inside our subst to prevent | |
| 5328 // it from ending too early by matching another } | |
| 5329 begin: /\{/, | |
| 5330 end: /\}/, | |
| 5331 keywords: KEYWORDS$1, | |
| 5332 contains: [ | |
| 5333 "self" | |
| 5334 ].concat(SUBST_INTERNALS) | |
| 5335 }); | |
| 5336 const SUBST_AND_COMMENTS = [].concat(COMMENT, SUBST.contains); | |
| 5337 const PARAMS_CONTAINS = SUBST_AND_COMMENTS.concat([ | |
| 5338 // eat recursive parens in sub expressions | |
| 5339 { | |
| 5340 begin: /(\s*)\(/, | |
| 5341 end: /\)/, | |
| 5342 keywords: KEYWORDS$1, | |
| 5343 contains: ["self"].concat(SUBST_AND_COMMENTS) | |
| 5344 } | |
| 5345 ]); | |
| 5346 const PARAMS = { | |
| 5347 className: 'params', | |
| 5348 // convert this to negative lookbehind in v12 | |
| 5349 begin: /(\s*)\(/, // to match the parms with | |
| 5350 end: /\)/, | |
| 5351 excludeBegin: true, | |
| 5352 excludeEnd: true, | |
| 5353 keywords: KEYWORDS$1, | |
| 5354 contains: PARAMS_CONTAINS | |
| 5355 }; | |
| 5356 | |
| 5357 // ES6 classes | |
| 5358 const CLASS_OR_EXTENDS = { | |
| 5359 variants: [ | |
| 5360 // class Car extends vehicle | |
| 5361 { | |
| 5362 match: [ | |
| 5363 /class/, | |
| 5364 /\s+/, | |
| 5365 IDENT_RE$1, | |
| 5366 /\s+/, | |
| 5367 /extends/, | |
| 5368 /\s+/, | |
| 5369 regex.concat(IDENT_RE$1, "(", regex.concat(/\./, IDENT_RE$1), ")*") | |
| 5370 ], | |
| 5371 scope: { | |
| 5372 1: "keyword", | |
| 5373 3: "title.class", | |
| 5374 5: "keyword", | |
| 5375 7: "title.class.inherited" | |
| 5376 } | |
| 5377 }, | |
| 5378 // class Car | |
| 5379 { | |
| 5380 match: [ | |
| 5381 /class/, | |
| 5382 /\s+/, | |
| 5383 IDENT_RE$1 | |
| 5384 ], | |
| 5385 scope: { | |
| 5386 1: "keyword", | |
| 5387 3: "title.class" | |
| 5388 } | |
| 5389 }, | |
| 5390 | |
| 5391 ] | |
| 5392 }; | |
| 5393 | |
| 5394 const CLASS_REFERENCE = { | |
| 5395 relevance: 0, | |
| 5396 match: | |
| 5397 regex.either( | |
| 5398 // Hard coded exceptions | |
| 5399 /\bJSON/, | |
| 5400 // Float32Array, OutT | |
| 5401 /\b[A-Z][a-z]+([A-Z][a-z]*|\d)*/, | |
| 5402 // CSSFactory, CSSFactoryT | |
| 5403 /\b[A-Z]{2,}([A-Z][a-z]+|\d)+([A-Z][a-z]*)*/, | |
| 5404 // FPs, FPsT | |
| 5405 /\b[A-Z]{2,}[a-z]+([A-Z][a-z]+|\d)*([A-Z][a-z]*)*/, | |
| 5406 // P | |
| 5407 // single letters are not highlighted | |
| 5408 // BLAH | |
| 5409 // this will be flagged as a UPPER_CASE_CONSTANT instead | |
| 5410 ), | |
| 5411 className: "title.class", | |
| 5412 keywords: { | |
| 5413 _: [ | |
| 5414 // se we still get relevance credit for JS library classes | |
| 5415 ...TYPES, | |
| 5416 ...ERROR_TYPES | |
| 5417 ] | |
| 5418 } | |
| 5419 }; | |
| 5420 | |
| 5421 const USE_STRICT = { | |
| 5422 label: "use_strict", | |
| 5423 className: 'meta', | |
| 5424 relevance: 10, | |
| 5425 begin: /^\s*['"]use (strict|asm)['"]/ | |
| 5426 }; | |
| 5427 | |
| 5428 const FUNCTION_DEFINITION = { | |
| 5429 variants: [ | |
| 5430 { | |
| 5431 match: [ | |
| 5432 /function/, | |
| 5433 /\s+/, | |
| 5434 IDENT_RE$1, | |
| 5435 /(?=\s*\()/ | |
| 5436 ] | |
| 5437 }, | |
| 5438 // anonymous function | |
| 5439 { | |
| 5440 match: [ | |
| 5441 /function/, | |
| 5442 /\s*(?=\()/ | |
| 5443 ] | |
| 5444 } | |
| 5445 ], | |
| 5446 className: { | |
| 5447 1: "keyword", | |
| 5448 3: "title.function" | |
| 5449 }, | |
| 5450 label: "func.def", | |
| 5451 contains: [ PARAMS ], | |
| 5452 illegal: /%/ | |
| 5453 }; | |
| 5454 | |
| 5455 const UPPER_CASE_CONSTANT = { | |
| 5456 relevance: 0, | |
| 5457 match: /\b[A-Z][A-Z_0-9]+\b/, | |
| 5458 className: "variable.constant" | |
| 5459 }; | |
| 5460 | |
| 5461 function noneOf(list) { | |
| 5462 return regex.concat("(?!", list.join("|"), ")"); | |
| 5463 } | |
| 5464 | |
| 5465 const FUNCTION_CALL = { | |
| 5466 match: regex.concat( | |
| 5467 /\b/, | |
| 5468 noneOf([ | |
| 5469 ...BUILT_IN_GLOBALS, | |
| 5470 "super", | |
| 5471 "import" | |
| 5472 ].map(x => `${x}\\s*\\(`)), | |
| 5473 IDENT_RE$1, regex.lookahead(/\s*\(/)), | |
| 5474 className: "title.function", | |
| 5475 relevance: 0 | |
| 5476 }; | |
| 5477 | |
| 5478 const PROPERTY_ACCESS = { | |
| 5479 begin: regex.concat(/\./, regex.lookahead( | |
| 5480 regex.concat(IDENT_RE$1, /(?![0-9A-Za-z$_(])/) | |
| 5481 )), | |
| 5482 end: IDENT_RE$1, | |
| 5483 excludeBegin: true, | |
| 5484 keywords: "prototype", | |
| 5485 className: "property", | |
| 5486 relevance: 0 | |
| 5487 }; | |
| 5488 | |
| 5489 const GETTER_OR_SETTER = { | |
| 5490 match: [ | |
| 5491 /get|set/, | |
| 5492 /\s+/, | |
| 5493 IDENT_RE$1, | |
| 5494 /(?=\()/ | |
| 5495 ], | |
| 5496 className: { | |
| 5497 1: "keyword", | |
| 5498 3: "title.function" | |
| 5499 }, | |
| 5500 contains: [ | |
| 5501 { // eat to avoid empty params | |
| 5502 begin: /\(\)/ | |
| 5503 }, | |
| 5504 PARAMS | |
| 5505 ] | |
| 5506 }; | |
| 5507 | |
| 5508 const FUNC_LEAD_IN_RE = '(\\(' + | |
| 5509 '[^()]*(\\(' + | |
| 5510 '[^()]*(\\(' + | |
| 5511 '[^()]*' + | |
| 5512 '\\)[^()]*)*' + | |
| 5513 '\\)[^()]*)*' + | |
| 5514 '\\)|' + hljs.UNDERSCORE_IDENT_RE + ')\\s*=>'; | |
| 5515 | |
| 5516 const FUNCTION_VARIABLE = { | |
| 5517 match: [ | |
| 5518 /const|var|let/, /\s+/, | |
| 5519 IDENT_RE$1, /\s*/, | |
| 5520 /=\s*/, | |
| 5521 /(async\s*)?/, // async is optional | |
| 5522 regex.lookahead(FUNC_LEAD_IN_RE) | |
| 5523 ], | |
| 5524 keywords: "async", | |
| 5525 className: { | |
| 5526 1: "keyword", | |
| 5527 3: "title.function" | |
| 5528 }, | |
| 5529 contains: [ | |
| 5530 PARAMS | |
| 5531 ] | |
| 5532 }; | |
| 5533 | |
| 5534 return { | |
| 5535 name: 'JavaScript', | |
| 5536 aliases: ['js', 'jsx', 'mjs', 'cjs'], | |
| 5537 keywords: KEYWORDS$1, | |
| 5538 // this will be extended by TypeScript | |
| 5539 exports: { PARAMS_CONTAINS, CLASS_REFERENCE }, | |
| 5540 illegal: /#(?![$_A-z])/, | |
| 5541 contains: [ | |
| 5542 hljs.SHEBANG({ | |
| 5543 label: "shebang", | |
| 5544 binary: "node", | |
| 5545 relevance: 5 | |
| 5546 }), | |
| 5547 USE_STRICT, | |
| 5548 hljs.APOS_STRING_MODE, | |
| 5549 hljs.QUOTE_STRING_MODE, | |
| 5550 HTML_TEMPLATE, | |
| 5551 CSS_TEMPLATE, | |
| 5552 GRAPHQL_TEMPLATE, | |
| 5553 TEMPLATE_STRING, | |
| 5554 COMMENT, | |
| 5555 // Skip numbers when they are part of a variable name | |
| 5556 { match: /\$\d+/ }, | |
| 5557 NUMBER, | |
| 5558 CLASS_REFERENCE, | |
| 5559 { | |
| 5560 scope: 'attr', | |
| 5561 match: IDENT_RE$1 + regex.lookahead(':'), | |
| 5562 relevance: 0 | |
| 5563 }, | |
| 5564 FUNCTION_VARIABLE, | |
| 5565 { // "value" container | |
| 5566 begin: '(' + hljs.RE_STARTERS_RE + '|\\b(case|return|throw)\\b)\\s*', | |
| 5567 keywords: 'return throw case', | |
| 5568 relevance: 0, | |
| 5569 contains: [ | |
| 5570 COMMENT, | |
| 5571 hljs.REGEXP_MODE, | |
| 5572 { | |
| 5573 className: 'function', | |
| 5574 // we have to count the parens to make sure we actually have the | |
| 5575 // correct bounding ( ) before the =>. There could be any number of | |
| 5576 // sub-expressions inside also surrounded by parens. | |
| 5577 begin: FUNC_LEAD_IN_RE, | |
| 5578 returnBegin: true, | |
| 5579 end: '\\s*=>', | |
| 5580 contains: [ | |
| 5581 { | |
| 5582 className: 'params', | |
| 5583 variants: [ | |
| 5584 { | |
| 5585 begin: hljs.UNDERSCORE_IDENT_RE, | |
| 5586 relevance: 0 | |
| 5587 }, | |
| 5588 { | |
| 5589 className: null, | |
| 5590 begin: /\(\s*\)/, | |
| 5591 skip: true | |
| 5592 }, | |
| 5593 { | |
| 5594 begin: /(\s*)\(/, | |
| 5595 end: /\)/, | |
| 5596 excludeBegin: true, | |
| 5597 excludeEnd: true, | |
| 5598 keywords: KEYWORDS$1, | |
| 5599 contains: PARAMS_CONTAINS | |
| 5600 } | |
| 5601 ] | |
| 5602 } | |
| 5603 ] | |
| 5604 }, | |
| 5605 { // could be a comma delimited list of params to a function call | |
| 5606 begin: /,/, | |
| 5607 relevance: 0 | |
| 5608 }, | |
| 5609 { | |
| 5610 match: /\s+/, | |
| 5611 relevance: 0 | |
| 5612 }, | |
| 5613 { // JSX | |
| 5614 variants: [ | |
| 5615 { begin: FRAGMENT.begin, end: FRAGMENT.end }, | |
| 5616 { match: XML_SELF_CLOSING }, | |
| 5617 { | |
| 5618 begin: XML_TAG.begin, | |
| 5619 // we carefully check the opening tag to see if it truly | |
| 5620 // is a tag and not a false positive | |
| 5621 'on:begin': XML_TAG.isTrulyOpeningTag, | |
| 5622 end: XML_TAG.end | |
| 5623 } | |
| 5624 ], | |
| 5625 subLanguage: 'xml', | |
| 5626 contains: [ | |
| 5627 { | |
| 5628 begin: XML_TAG.begin, | |
| 5629 end: XML_TAG.end, | |
| 5630 skip: true, | |
| 5631 contains: ['self'] | |
| 5632 } | |
| 5633 ] | |
| 5634 } | |
| 5635 ], | |
| 5636 }, | |
| 5637 FUNCTION_DEFINITION, | |
| 5638 { | |
| 5639 // prevent this from getting swallowed up by function | |
| 5640 // since they appear "function like" | |
| 5641 beginKeywords: "while if switch catch for" | |
| 5642 }, | |
| 5643 { | |
| 5644 // we have to count the parens to make sure we actually have the correct | |
| 5645 // bounding ( ). There could be any number of sub-expressions inside | |
| 5646 // also surrounded by parens. | |
| 5647 begin: '\\b(?!function)' + hljs.UNDERSCORE_IDENT_RE + | |
| 5648 '\\(' + // first parens | |
| 5649 '[^()]*(\\(' + | |
| 5650 '[^()]*(\\(' + | |
| 5651 '[^()]*' + | |
| 5652 '\\)[^()]*)*' + | |
| 5653 '\\)[^()]*)*' + | |
| 5654 '\\)\\s*\\{', // end parens | |
| 5655 returnBegin:true, | |
| 5656 label: "func.def", | |
| 5657 contains: [ | |
| 5658 PARAMS, | |
| 5659 hljs.inherit(hljs.TITLE_MODE, { begin: IDENT_RE$1, className: "title.function" }) | |
| 5660 ] | |
| 5661 }, | |
| 5662 // catch ... so it won't trigger the property rule below | |
| 5663 { | |
| 5664 match: /\.\.\./, | |
| 5665 relevance: 0 | |
| 5666 }, | |
| 5667 PROPERTY_ACCESS, | |
| 5668 // hack: prevents detection of keywords in some circumstances | |
| 5669 // .keyword() | |
| 5670 // $keyword = x | |
| 5671 { | |
| 5672 match: '\\$' + IDENT_RE$1, | |
| 5673 relevance: 0 | |
| 5674 }, | |
| 5675 { | |
| 5676 match: [ /\bconstructor(?=\s*\()/ ], | |
| 5677 className: { 1: "title.function" }, | |
| 5678 contains: [ PARAMS ] | |
| 5679 }, | |
| 5680 FUNCTION_CALL, | |
| 5681 UPPER_CASE_CONSTANT, | |
| 5682 CLASS_OR_EXTENDS, | |
| 5683 GETTER_OR_SETTER, | |
| 5684 { | |
| 5685 match: /\$[(.]/ // relevance booster for a pattern common to JS libs: `$(something)` and `$.something` | |
| 5686 } | |
| 5687 ] | |
| 5688 }; | |
| 5689 } | |
| 5690 | |
| 5691 return javascript; | |
| 5692 | |
| 5693 })(); | |
| 5694 | |
| 5695 hljs.registerLanguage('javascript', hljsGrammar); | |
| 5696 })();/*! `json` grammar compiled for Highlight.js 11.11.1 */ | |
| 5697 (function(){ | |
| 5698 var hljsGrammar = (function () { | |
| 5699 'use strict'; | |
| 5700 | |
| 5701 /* | |
| 5702 Language: JSON | |
| 5703 Description: JSON (JavaScript Object Notation) is a lightweight data-interchange format. | |
| 5704 Author: Ivan Sagalaev <[email protected]> | |
| 5705 Website: http://www.json.org | |
| 5706 Category: common, protocols, web | |
| 5707 */ | |
| 5708 | |
| 5709 function json(hljs) { | |
| 5710 const ATTRIBUTE = { | |
| 5711 className: 'attr', | |
| 5712 begin: /"(\\.|[^\\"\r\n])*"(?=\s*:)/, | |
| 5713 relevance: 1.01 | |
| 5714 }; | |
| 5715 const PUNCTUATION = { | |
| 5716 match: /[{}[\],:]/, | |
| 5717 className: "punctuation", | |
| 5718 relevance: 0 | |
| 5719 }; | |
| 5720 const LITERALS = [ | |
| 5721 "true", | |
| 5722 "false", | |
| 5723 "null" | |
| 5724 ]; | |
| 5725 // NOTE: normally we would rely on `keywords` for this but using a mode here allows us | |
| 5726 // - to use the very tight `illegal: \S` rule later to flag any other character | |
| 5727 // - as illegal indicating that despite looking like JSON we do not truly have | |
| 5728 // - JSON and thus improve false-positively greatly since JSON will try and claim | |
| 5729 // - all sorts of JSON looking stuff | |
| 5730 const LITERALS_MODE = { | |
| 5731 scope: "literal", | |
| 5732 beginKeywords: LITERALS.join(" "), | |
| 5733 }; | |
| 5734 | |
| 5735 return { | |
| 5736 name: 'JSON', | |
| 5737 aliases: ['jsonc'], | |
| 5738 keywords:{ | |
| 5739 literal: LITERALS, | |
| 5740 }, | |
| 5741 contains: [ | |
| 5742 ATTRIBUTE, | |
| 5743 PUNCTUATION, | |
| 5744 hljs.QUOTE_STRING_MODE, | |
| 5745 LITERALS_MODE, | |
| 5746 hljs.C_NUMBER_MODE, | |
| 5747 hljs.C_LINE_COMMENT_MODE, | |
| 5748 hljs.C_BLOCK_COMMENT_MODE | |
| 5749 ], | |
| 5750 illegal: '\\S' | |
| 5751 }; | |
| 5752 } | |
| 5753 | |
| 5754 return json; | |
| 5755 | |
| 5756 })(); | |
| 5757 | |
| 5758 hljs.registerLanguage('json', hljsGrammar); | |
| 5759 })();/*! `lua` grammar compiled for Highlight.js 11.11.1 */ | |
| 5760 (function(){ | |
| 5761 var hljsGrammar = (function () { | |
| 5762 'use strict'; | |
| 5763 | |
| 5764 /* | |
| 5765 Language: Lua | |
| 5766 Description: Lua is a powerful, efficient, lightweight, embeddable scripting language. | |
| 5767 Author: Andrew Fedorov <[email protected]> | |
| 5768 Category: common, gaming, scripting | |
| 5769 Website: https://www.lua.org | |
| 5770 */ | |
| 5771 | |
| 5772 function lua(hljs) { | |
| 5773 const OPENING_LONG_BRACKET = '\\[=*\\['; | |
| 5774 const CLOSING_LONG_BRACKET = '\\]=*\\]'; | |
| 5775 const LONG_BRACKETS = { | |
| 5776 begin: OPENING_LONG_BRACKET, | |
| 5777 end: CLOSING_LONG_BRACKET, | |
| 5778 contains: [ 'self' ] | |
| 5779 }; | |
| 5780 const COMMENTS = [ | |
| 5781 hljs.COMMENT('--(?!' + OPENING_LONG_BRACKET + ')', '$'), | |
| 5782 hljs.COMMENT( | |
| 5783 '--' + OPENING_LONG_BRACKET, | |
| 5784 CLOSING_LONG_BRACKET, | |
| 5785 { | |
| 5786 contains: [ LONG_BRACKETS ], | |
| 5787 relevance: 10 | |
| 5788 } | |
| 5789 ) | |
| 5790 ]; | |
| 5791 return { | |
| 5792 name: 'Lua', | |
| 5793 aliases: ['pluto'], | |
| 5794 keywords: { | |
| 5795 $pattern: hljs.UNDERSCORE_IDENT_RE, | |
| 5796 literal: "true false nil", | |
| 5797 keyword: "and break do else elseif end for goto if in local not or repeat return then until while", | |
| 5798 built_in: | |
| 5799 // Metatags and globals: | |
| 5800 '_G _ENV _VERSION __index __newindex __mode __call __metatable __tostring __len ' | |
| 5801 + '__gc __add __sub __mul __div __mod __pow __concat __unm __eq __lt __le assert ' | |
| 5802 // Standard methods and properties: | |
| 5803 + 'collectgarbage dofile error getfenv getmetatable ipairs load loadfile loadstring ' | |
| 5804 + 'module next pairs pcall print rawequal rawget rawset require select setfenv ' | |
| 5805 + 'setmetatable tonumber tostring type unpack xpcall arg self ' | |
| 5806 // Library methods and properties (one line per library): | |
| 5807 + 'coroutine resume yield status wrap create running debug getupvalue ' | |
| 5808 + 'debug sethook getmetatable gethook setmetatable setlocal traceback setfenv getinfo setupvalue getlocal getregistry getfenv ' | |
| 5809 + 'io lines write close flush open output type read stderr stdin input stdout popen tmpfile ' | |
| 5810 + '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 ' | |
| 5811 + 'os exit setlocale date getenv difftime remove time clock tmpname rename execute package preload loadlib loaded loaders cpath config path seeall ' | |
| 5812 + 'string sub upper len gfind rep find match char dump gmatch reverse byte format gsub lower ' | |
| 5813 + 'table setn insert getn foreachi maxn foreach concat sort remove' | |
| 5814 }, | |
| 5815 contains: COMMENTS.concat([ | |
| 5816 { | |
| 5817 className: 'function', | |
| 5818 beginKeywords: 'function', | |
| 5819 end: '\\)', | |
| 5820 contains: [ | |
| 5821 hljs.inherit(hljs.TITLE_MODE, { begin: '([_a-zA-Z]\\w*\\.)*([_a-zA-Z]\\w*:)?[_a-zA-Z]\\w*' }), | |
| 5822 { | |
| 5823 className: 'params', | |
| 5824 begin: '\\(', | |
| 5825 endsWithParent: true, | |
| 5826 contains: COMMENTS | |
| 5827 } | |
| 5828 ].concat(COMMENTS) | |
| 5829 }, | |
| 5830 hljs.C_NUMBER_MODE, | |
| 5831 hljs.APOS_STRING_MODE, | |
| 5832 hljs.QUOTE_STRING_MODE, | |
| 5833 { | |
| 5834 className: 'string', | |
| 5835 begin: OPENING_LONG_BRACKET, | |
| 5836 end: CLOSING_LONG_BRACKET, | |
| 5837 contains: [ LONG_BRACKETS ], | |
| 5838 relevance: 5 | |
| 5839 } | |
| 5840 ]) | |
| 5841 }; | |
| 5842 } | |
| 5843 | |
| 5844 return lua; | |
| 5845 | |
| 5846 })(); | |
| 5847 | |
| 5848 hljs.registerLanguage('lua', hljsGrammar); | |
| 5849 })();/*! `python` grammar compiled for Highlight.js 11.11.1 */ | |
| 5850 (function(){ | |
| 5851 var hljsGrammar = (function () { | |
| 5852 'use strict'; | |
| 5853 | |
| 5854 /* | |
| 5855 Language: Python | |
| 5856 Description: Python is an interpreted, object-oriented, high-level programming language with dynamic semantics. | |
| 5857 Website: https://www.python.org | |
| 5858 Category: common | |
| 5859 */ | |
| 5860 | |
| 5861 function python(hljs) { | |
| 5862 const regex = hljs.regex; | |
| 5863 const IDENT_RE = /[\p{XID_Start}_]\p{XID_Continue}*/u; | |
| 5864 const RESERVED_WORDS = [ | |
| 5865 'and', | |
| 5866 'as', | |
| 5867 'assert', | |
| 5868 'async', | |
| 5869 'await', | |
| 5870 'break', | |
| 5871 'case', | |
| 5872 'class', | |
| 5873 'continue', | |
| 5874 'def', | |
| 5875 'del', | |
| 5876 'elif', | |
| 5877 'else', | |
| 5878 'except', | |
| 5879 'finally', | |
| 5880 'for', | |
| 5881 'from', | |
| 5882 'global', | |
| 5883 'if', | |
| 5884 'import', | |
| 5885 'in', | |
| 5886 'is', | |
| 5887 'lambda', | |
| 5888 'match', | |
| 5889 'nonlocal|10', | |
| 5890 'not', | |
| 5891 'or', | |
| 5892 'pass', | |
| 5893 'raise', | |
| 5894 'return', | |
| 5895 'try', | |
| 5896 'while', | |
| 5897 'with', | |
| 5898 'yield' | |
| 5899 ]; | |
| 5900 | |
| 5901 const BUILT_INS = [ | |
| 5902 '__import__', | |
| 5903 'abs', | |
| 5904 'all', | |
| 5905 'any', | |
| 5906 'ascii', | |
| 5907 'bin', | |
| 5908 'bool', | |
| 5909 'breakpoint', | |
| 5910 'bytearray', | |
| 5911 'bytes', | |
| 5912 'callable', | |
| 5913 'chr', | |
| 5914 'classmethod', | |
| 5915 'compile', | |
| 5916 'complex', | |
| 5917 'delattr', | |
| 5918 'dict', | |
| 5919 'dir', | |
| 5920 'divmod', | |
| 5921 'enumerate', | |
| 5922 'eval', | |
| 5923 'exec', | |
| 5924 'filter', | |
| 5925 'float', | |
| 5926 'format', | |
| 5927 'frozenset', | |
| 5928 'getattr', | |
| 5929 'globals', | |
| 5930 'hasattr', | |
| 5931 'hash', | |
| 5932 'help', | |
| 5933 'hex', | |
| 5934 'id', | |
| 5935 'input', | |
| 5936 'int', | |
| 5937 'isinstance', | |
| 5938 'issubclass', | |
| 5939 'iter', | |
| 5940 'len', | |
| 5941 'list', | |
| 5942 'locals', | |
| 5943 'map', | |
| 5944 'max', | |
| 5945 'memoryview', | |
| 5946 'min', | |
| 5947 'next', | |
| 5948 'object', | |
| 5949 'oct', | |
| 5950 'open', | |
| 5951 'ord', | |
| 5952 'pow', | |
| 5953 'print', | |
| 5954 'property', | |
| 5955 'range', | |
| 5956 'repr', | |
| 5957 'reversed', | |
| 5958 'round', | |
| 5959 'set', | |
| 5960 'setattr', | |
| 5961 'slice', | |
| 5962 'sorted', | |
| 5963 'staticmethod', | |
| 5964 'str', | |
| 5965 'sum', | |
| 5966 'super', | |
| 5967 'tuple', | |
| 5968 'type', | |
| 5969 'vars', | |
| 5970 'zip' | |
| 5971 ]; | |
| 5972 | |
| 5973 const LITERALS = [ | |
| 5974 '__debug__', | |
| 5975 'Ellipsis', | |
| 5976 'False', | |
| 5977 'None', | |
| 5978 'NotImplemented', | |
| 5979 'True' | |
| 5980 ]; | |
| 5981 | |
| 5982 // https://docs.python.org/3/library/typing.html | |
| 5983 // TODO: Could these be supplemented by a CamelCase matcher in certain | |
| 5984 // contexts, leaving these remaining only for relevance hinting? | |
| 5985 const TYPES = [ | |
| 5986 "Any", | |
| 5987 "Callable", | |
| 5988 "Coroutine", | |
| 5989 "Dict", | |
| 5990 "List", | |
| 5991 "Literal", | |
| 5992 "Generic", | |
| 5993 "Optional", | |
| 5994 "Sequence", | |
| 5995 "Set", | |
| 5996 "Tuple", | |
| 5997 "Type", | |
| 5998 "Union" | |
| 5999 ]; | |
| 6000 | |
| 6001 const KEYWORDS = { | |
| 6002 $pattern: /[A-Za-z]\w+|__\w+__/, | |
| 6003 keyword: RESERVED_WORDS, | |
| 6004 built_in: BUILT_INS, | |
| 6005 literal: LITERALS, | |
| 6006 type: TYPES | |
| 6007 }; | |
| 6008 | |
| 6009 const PROMPT = { | |
| 6010 className: 'meta', | |
| 6011 begin: /^(>>>|\.\.\.) / | |
| 6012 }; | |
| 6013 | |
| 6014 const SUBST = { | |
| 6015 className: 'subst', | |
| 6016 begin: /\{/, | |
| 6017 end: /\}/, | |
| 6018 keywords: KEYWORDS, | |
| 6019 illegal: /#/ | |
| 6020 }; | |
| 6021 | |
| 6022 const LITERAL_BRACKET = { | |
| 6023 begin: /\{\{/, | |
| 6024 relevance: 0 | |
| 6025 }; | |
| 6026 | |
| 6027 const STRING = { | |
| 6028 className: 'string', | |
| 6029 contains: [ hljs.BACKSLASH_ESCAPE ], | |
| 6030 variants: [ | |
| 6031 { | |
| 6032 begin: /([uU]|[bB]|[rR]|[bB][rR]|[rR][bB])?'''/, | |
| 6033 end: /'''/, | |
| 6034 contains: [ | |
| 6035 hljs.BACKSLASH_ESCAPE, | |
| 6036 PROMPT | |
| 6037 ], | |
| 6038 relevance: 10 | |
| 6039 }, | |
| 6040 { | |
| 6041 begin: /([uU]|[bB]|[rR]|[bB][rR]|[rR][bB])?"""/, | |
| 6042 end: /"""/, | |
| 6043 contains: [ | |
| 6044 hljs.BACKSLASH_ESCAPE, | |
| 6045 PROMPT | |
| 6046 ], | |
| 6047 relevance: 10 | |
| 6048 }, | |
| 6049 { | |
| 6050 begin: /([fF][rR]|[rR][fF]|[fF])'''/, | |
| 6051 end: /'''/, | |
| 6052 contains: [ | |
| 6053 hljs.BACKSLASH_ESCAPE, | |
| 6054 PROMPT, | |
| 6055 LITERAL_BRACKET, | |
| 6056 SUBST | |
| 6057 ] | |
| 6058 }, | |
| 6059 { | |
| 6060 begin: /([fF][rR]|[rR][fF]|[fF])"""/, | |
| 6061 end: /"""/, | |
| 6062 contains: [ | |
| 6063 hljs.BACKSLASH_ESCAPE, | |
| 6064 PROMPT, | |
| 6065 LITERAL_BRACKET, | |
| 6066 SUBST | |
| 6067 ] | |
| 6068 }, | |
| 6069 { | |
| 6070 begin: /([uU]|[rR])'/, | |
| 6071 end: /'/, | |
| 6072 relevance: 10 | |
| 6073 }, | |
| 6074 { | |
| 6075 begin: /([uU]|[rR])"/, | |
| 6076 end: /"/, | |
| 6077 relevance: 10 | |
| 6078 }, | |
| 6079 { | |
| 6080 begin: /([bB]|[bB][rR]|[rR][bB])'/, | |
| 6081 end: /'/ | |
| 6082 }, | |
| 6083 { | |
| 6084 begin: /([bB]|[bB][rR]|[rR][bB])"/, | |
| 6085 end: /"/ | |
| 6086 }, | |
| 6087 { | |
| 6088 begin: /([fF][rR]|[rR][fF]|[fF])'/, | |
| 6089 end: /'/, | |
| 6090 contains: [ | |
| 6091 hljs.BACKSLASH_ESCAPE, | |
| 6092 LITERAL_BRACKET, | |
| 6093 SUBST | |
| 6094 ] | |
| 6095 }, | |
| 6096 { | |
| 6097 begin: /([fF][rR]|[rR][fF]|[fF])"/, | |
| 6098 end: /"/, | |
| 6099 contains: [ | |
| 6100 hljs.BACKSLASH_ESCAPE, | |
| 6101 LITERAL_BRACKET, | |
| 6102 SUBST | |
| 6103 ] | |
| 6104 }, | |
| 6105 hljs.APOS_STRING_MODE, | |
| 6106 hljs.QUOTE_STRING_MODE | |
| 6107 ] | |
| 6108 }; | |
| 6109 | |
| 6110 // https://docs.python.org/3.9/reference/lexical_analysis.html#numeric-literals | |
| 6111 const digitpart = '[0-9](_?[0-9])*'; | |
| 6112 const pointfloat = `(\\b(${digitpart}))?\\.(${digitpart})|\\b(${digitpart})\\.`; | |
| 6113 // Whitespace after a number (or any lexical token) is needed only if its absence | |
| 6114 // would change the tokenization | |
| 6115 // https://docs.python.org/3.9/reference/lexical_analysis.html#whitespace-between-tokens | |
| 6116 // We deviate slightly, requiring a word boundary or a keyword | |
| 6117 // to avoid accidentally recognizing *prefixes* (e.g., `0` in `0x41` or `08` or `0__1`) | |
| 6118 const lookahead = `\\b|${RESERVED_WORDS.join('|')}`; | |
| 6119 const NUMBER = { | |
| 6120 className: 'number', | |
| 6121 relevance: 0, | |
| 6122 variants: [ | |
| 6123 // exponentfloat, pointfloat | |
| 6124 // https://docs.python.org/3.9/reference/lexical_analysis.html#floating-point-literals | |
| 6125 // optionally imaginary | |
| 6126 // https://docs.python.org/3.9/reference/lexical_analysis.html#imaginary-literals | |
| 6127 // Note: no leading \b because floats can start with a decimal point | |
| 6128 // and we don't want to mishandle e.g. `fn(.5)`, | |
| 6129 // no trailing \b for pointfloat because it can end with a decimal point | |
| 6130 // and we don't want to mishandle e.g. `0..hex()`; this should be safe | |
| 6131 // because both MUST contain a decimal point and so cannot be confused with | |
| 6132 // the interior part of an identifier | |
| 6133 { | |
| 6134 begin: `(\\b(${digitpart})|(${pointfloat}))[eE][+-]?(${digitpart})[jJ]?(?=${lookahead})` | |
| 6135 }, | |
| 6136 { | |
| 6137 begin: `(${pointfloat})[jJ]?` | |
| 6138 }, | |
| 6139 | |
| 6140 // decinteger, bininteger, octinteger, hexinteger | |
| 6141 // https://docs.python.org/3.9/reference/lexical_analysis.html#integer-literals | |
| 6142 // optionally "long" in Python 2 | |
| 6143 // https://docs.python.org/2.7/reference/lexical_analysis.html#integer-and-long-integer-literals | |
| 6144 // decinteger is optionally imaginary | |
| 6145 // https://docs.python.org/3.9/reference/lexical_analysis.html#imaginary-literals | |
| 6146 { | |
| 6147 begin: `\\b([1-9](_?[0-9])*|0+(_?0)*)[lLjJ]?(?=${lookahead})` | |
| 6148 }, | |
| 6149 { | |
| 6150 begin: `\\b0[bB](_?[01])+[lL]?(?=${lookahead})` | |
| 6151 }, | |
| 6152 { | |
| 6153 begin: `\\b0[oO](_?[0-7])+[lL]?(?=${lookahead})` | |
| 6154 }, | |
| 6155 { | |
| 6156 begin: `\\b0[xX](_?[0-9a-fA-F])+[lL]?(?=${lookahead})` | |
| 6157 }, | |
| 6158 | |
| 6159 // imagnumber (digitpart-based) | |
| 6160 // https://docs.python.org/3.9/reference/lexical_analysis.html#imaginary-literals | |
| 6161 { | |
| 6162 begin: `\\b(${digitpart})[jJ](?=${lookahead})` | |
| 6163 } | |
| 6164 ] | |
| 6165 }; | |
| 6166 const COMMENT_TYPE = { | |
| 6167 className: "comment", | |
| 6168 begin: regex.lookahead(/# type:/), | |
| 6169 end: /$/, | |
| 6170 keywords: KEYWORDS, | |
| 6171 contains: [ | |
| 6172 { // prevent keywords from coloring `type` | |
| 6173 begin: /# type:/ | |
| 6174 }, | |
| 6175 // comment within a datatype comment includes no keywords | |
| 6176 { | |
| 6177 begin: /#/, | |
| 6178 end: /\b\B/, | |
| 6179 endsWithParent: true | |
| 6180 } | |
| 6181 ] | |
| 6182 }; | |
| 6183 const PARAMS = { | |
| 6184 className: 'params', | |
| 6185 variants: [ | |
| 6186 // Exclude params in functions without params | |
| 6187 { | |
| 6188 className: "", | |
| 6189 begin: /\(\s*\)/, | |
| 6190 skip: true | |
| 6191 }, | |
| 6192 { | |
| 6193 begin: /\(/, | |
| 6194 end: /\)/, | |
| 6195 excludeBegin: true, | |
| 6196 excludeEnd: true, | |
| 6197 keywords: KEYWORDS, | |
| 6198 contains: [ | |
| 6199 'self', | |
| 6200 PROMPT, | |
| 6201 NUMBER, | |
| 6202 STRING, | |
| 6203 hljs.HASH_COMMENT_MODE | |
| 6204 ] | |
| 6205 } | |
| 6206 ] | |
| 6207 }; | |
| 6208 SUBST.contains = [ | |
| 6209 STRING, | |
| 6210 NUMBER, | |
| 6211 PROMPT | |
| 6212 ]; | |
| 6213 | |
| 6214 return { | |
| 6215 name: 'Python', | |
| 6216 aliases: [ | |
| 6217 'py', | |
| 6218 'gyp', | |
| 6219 'ipython' | |
| 6220 ], | |
| 6221 unicodeRegex: true, | |
| 6222 keywords: KEYWORDS, | |
| 6223 illegal: /(<\/|\?)|=>/, | |
| 6224 contains: [ | |
| 6225 PROMPT, | |
| 6226 NUMBER, | |
| 6227 { | |
| 6228 // very common convention | |
| 6229 scope: 'variable.language', | |
| 6230 match: /\bself\b/ | |
| 6231 }, | |
| 6232 { | |
| 6233 // eat "if" prior to string so that it won't accidentally be | |
| 6234 // labeled as an f-string | |
| 6235 beginKeywords: "if", | |
| 6236 relevance: 0 | |
| 6237 }, | |
| 6238 { match: /\bor\b/, scope: "keyword" }, | |
| 6239 STRING, | |
| 6240 COMMENT_TYPE, | |
| 6241 hljs.HASH_COMMENT_MODE, | |
| 6242 { | |
| 6243 match: [ | |
| 6244 /\bdef/, /\s+/, | |
| 6245 IDENT_RE, | |
| 6246 ], | |
| 6247 scope: { | |
| 6248 1: "keyword", | |
| 6249 3: "title.function" | |
| 6250 }, | |
| 6251 contains: [ PARAMS ] | |
| 6252 }, | |
| 6253 { | |
| 6254 variants: [ | |
| 6255 { | |
| 6256 match: [ | |
| 6257 /\bclass/, /\s+/, | |
| 6258 IDENT_RE, /\s*/, | |
| 6259 /\(\s*/, IDENT_RE,/\s*\)/ | |
| 6260 ], | |
| 6261 }, | |
| 6262 { | |
| 6263 match: [ | |
| 6264 /\bclass/, /\s+/, | |
| 6265 IDENT_RE | |
| 6266 ], | |
| 6267 } | |
| 6268 ], | |
| 6269 scope: { | |
| 6270 1: "keyword", | |
| 6271 3: "title.class", | |
| 6272 6: "title.class.inherited", | |
| 6273 } | |
| 6274 }, | |
| 6275 { | |
| 6276 className: 'meta', | |
| 6277 begin: /^[\t ]*@/, | |
| 6278 end: /(?=#)|$/, | |
| 6279 contains: [ | |
| 6280 NUMBER, | |
| 6281 PARAMS, | |
| 6282 STRING | |
| 6283 ] | |
| 6284 } | |
| 6285 ] | |
| 6286 }; | |
| 6287 } | |
| 6288 | |
| 6289 return python; | |
| 6290 | |
| 6291 })(); | |
| 6292 | |
| 6293 hljs.registerLanguage('python', hljsGrammar); | |
| 6294 })();/*! `sql` grammar compiled for Highlight.js 11.11.1 */ | |
| 6295 (function(){ | |
| 6296 var hljsGrammar = (function () { | |
| 6297 'use strict'; | |
| 6298 | |
| 6299 /* | |
| 6300 Language: SQL | |
| 6301 Website: https://en.wikipedia.org/wiki/SQL | |
| 6302 Category: common, database | |
| 6303 */ | |
| 6304 | |
| 6305 /* | |
| 6306 | |
| 6307 Goals: | |
| 6308 | |
| 6309 SQL is intended to highlight basic/common SQL keywords and expressions | |
| 6310 | |
| 6311 - If pretty much every single SQL server includes supports, then it's a canidate. | |
| 6312 - It is NOT intended to include tons of vendor specific keywords (Oracle, MySQL, | |
| 6313 PostgreSQL) although the list of data types is purposely a bit more expansive. | |
| 6314 - For more specific SQL grammars please see: | |
| 6315 - PostgreSQL and PL/pgSQL - core | |
| 6316 - T-SQL - https://github.com/highlightjs/highlightjs-tsql | |
| 6317 - sql_more (core) | |
| 6318 | |
| 6319 */ | |
| 6320 | |
| 6321 function sql(hljs) { | |
| 6322 const regex = hljs.regex; | |
| 6323 const COMMENT_MODE = hljs.COMMENT('--', '$'); | |
| 6324 const STRING = { | |
| 6325 scope: 'string', | |
| 6326 variants: [ | |
| 6327 { | |
| 6328 begin: /'/, | |
| 6329 end: /'/, | |
| 6330 contains: [ { match: /''/ } ] | |
| 6331 } | |
| 6332 ] | |
| 6333 }; | |
| 6334 const QUOTED_IDENTIFIER = { | |
| 6335 begin: /"/, | |
| 6336 end: /"/, | |
| 6337 contains: [ { match: /""/ } ] | |
| 6338 }; | |
| 6339 | |
| 6340 const LITERALS = [ | |
| 6341 "true", | |
| 6342 "false", | |
| 6343 // Not sure it's correct to call NULL literal, and clauses like IS [NOT] NULL look strange that way. | |
| 6344 // "null", | |
| 6345 "unknown" | |
| 6346 ]; | |
| 6347 | |
| 6348 const MULTI_WORD_TYPES = [ | |
| 6349 "double precision", | |
| 6350 "large object", | |
| 6351 "with timezone", | |
| 6352 "without timezone" | |
| 6353 ]; | |
| 6354 | |
| 6355 const TYPES = [ | |
| 6356 'bigint', | |
| 6357 'binary', | |
| 6358 'blob', | |
| 6359 'boolean', | |
| 6360 'char', | |
| 6361 'character', | |
| 6362 'clob', | |
| 6363 'date', | |
| 6364 'dec', | |
| 6365 'decfloat', | |
| 6366 'decimal', | |
| 6367 'float', | |
| 6368 'int', | |
| 6369 'integer', | |
| 6370 'interval', | |
| 6371 'nchar', | |
| 6372 'nclob', | |
| 6373 'national', | |
| 6374 'numeric', | |
| 6375 'real', | |
| 6376 'row', | |
| 6377 'smallint', | |
| 6378 'time', | |
| 6379 'timestamp', | |
| 6380 'varchar', | |
| 6381 'varying', // modifier (character varying) | |
| 6382 'varbinary' | |
| 6383 ]; | |
| 6384 | |
| 6385 const NON_RESERVED_WORDS = [ | |
| 6386 "add", | |
| 6387 "asc", | |
| 6388 "collation", | |
| 6389 "desc", | |
| 6390 "final", | |
| 6391 "first", | |
| 6392 "last", | |
| 6393 "view" | |
| 6394 ]; | |
| 6395 | |
| 6396 // https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#reserved-word | |
| 6397 const RESERVED_WORDS = [ | |
| 6398 "abs", | |
| 6399 "acos", | |
| 6400 "all", | |
| 6401 "allocate", | |
| 6402 "alter", | |
| 6403 "and", | |
| 6404 "any", | |
| 6405 "are", | |
| 6406 "array", | |
| 6407 "array_agg", | |
| 6408 "array_max_cardinality", | |
| 6409 "as", | |
| 6410 "asensitive", | |
| 6411 "asin", | |
| 6412 "asymmetric", | |
| 6413 "at", | |
| 6414 "atan", | |
| 6415 "atomic", | |
| 6416 "authorization", | |
| 6417 "avg", | |
| 6418 "begin", | |
| 6419 "begin_frame", | |
| 6420 "begin_partition", | |
| 6421 "between", | |
| 6422 "bigint", | |
| 6423 "binary", | |
| 6424 "blob", | |
| 6425 "boolean", | |
| 6426 "both", | |
| 6427 "by", | |
| 6428 "call", | |
| 6429 "called", | |
| 6430 "cardinality", | |
| 6431 "cascaded", | |
| 6432 "case", | |
| 6433 "cast", | |
| 6434 "ceil", | |
| 6435 "ceiling", | |
| 6436 "char", | |
| 6437 "char_length", | |
| 6438 "character", | |
| 6439 "character_length", | |
| 6440 "check", | |
| 6441 "classifier", | |
| 6442 "clob", | |
| 6443 "close", | |
| 6444 "coalesce", | |
| 6445 "collate", | |
| 6446 "collect", | |
| 6447 "column", | |
| 6448 "commit", | |
| 6449 "condition", | |
| 6450 "connect", | |
| 6451 "constraint", | |
| 6452 "contains", | |
| 6453 "convert", | |
| 6454 "copy", | |
| 6455 "corr", | |
| 6456 "corresponding", | |
| 6457 "cos", | |
| 6458 "cosh", | |
| 6459 "count", | |
| 6460 "covar_pop", | |
| 6461 "covar_samp", | |
| 6462 "create", | |
| 6463 "cross", | |
| 6464 "cube", | |
| 6465 "cume_dist", | |
| 6466 "current", | |
| 6467 "current_catalog", | |
| 6468 "current_date", | |
| 6469 "current_default_transform_group", | |
| 6470 "current_path", | |
| 6471 "current_role", | |
| 6472 "current_row", | |
| 6473 "current_schema", | |
| 6474 "current_time", | |
| 6475 "current_timestamp", | |
| 6476 "current_path", | |
| 6477 "current_role", | |
| 6478 "current_transform_group_for_type", | |
| 6479 "current_user", | |
| 6480 "cursor", | |
| 6481 "cycle", | |
| 6482 "date", | |
| 6483 "day", | |
| 6484 "deallocate", | |
| 6485 "dec", | |
| 6486 "decimal", | |
| 6487 "decfloat", | |
| 6488 "declare", | |
| 6489 "default", | |
| 6490 "define", | |
| 6491 "delete", | |
| 6492 "dense_rank", | |
| 6493 "deref", | |
| 6494 "describe", | |
| 6495 "deterministic", | |
| 6496 "disconnect", | |
| 6497 "distinct", | |
| 6498 "double", | |
| 6499 "drop", | |
| 6500 "dynamic", | |
| 6501 "each", | |
| 6502 "element", | |
| 6503 "else", | |
| 6504 "empty", | |
| 6505 "end", | |
| 6506 "end_frame", | |
| 6507 "end_partition", | |
| 6508 "end-exec", | |
| 6509 "equals", | |
| 6510 "escape", | |
| 6511 "every", | |
| 6512 "except", | |
| 6513 "exec", | |
| 6514 "execute", | |
| 6515 "exists", | |
| 6516 "exp", | |
| 6517 "external", | |
| 6518 "extract", | |
| 6519 "false", | |
| 6520 "fetch", | |
| 6521 "filter", | |
| 6522 "first_value", | |
| 6523 "float", | |
| 6524 "floor", | |
| 6525 "for", | |
| 6526 "foreign", | |
| 6527 "frame_row", | |
| 6528 "free", | |
| 6529 "from", | |
| 6530 "full", | |
| 6531 "function", | |
| 6532 "fusion", | |
| 6533 "get", | |
| 6534 "global", | |
| 6535 "grant", | |
| 6536 "group", | |
| 6537 "grouping", | |
| 6538 "groups", | |
| 6539 "having", | |
| 6540 "hold", | |
| 6541 "hour", | |
| 6542 "identity", | |
| 6543 "in", | |
| 6544 "indicator", | |
| 6545 "initial", | |
| 6546 "inner", | |
| 6547 "inout", | |
| 6548 "insensitive", | |
| 6549 "insert", | |
| 6550 "int", | |
| 6551 "integer", | |
| 6552 "intersect", | |
| 6553 "intersection", | |
| 6554 "interval", | |
| 6555 "into", | |
| 6556 "is", | |
| 6557 "join", | |
| 6558 "json_array", | |
| 6559 "json_arrayagg", | |
| 6560 "json_exists", | |
| 6561 "json_object", | |
| 6562 "json_objectagg", | |
| 6563 "json_query", | |
| 6564 "json_table", | |
| 6565 "json_table_primitive", | |
| 6566 "json_value", | |
| 6567 "lag", | |
| 6568 "language", | |
| 6569 "large", | |
| 6570 "last_value", | |
| 6571 "lateral", | |
| 6572 "lead", | |
| 6573 "leading", | |
| 6574 "left", | |
| 6575 "like", | |
| 6576 "like_regex", | |
| 6577 "listagg", | |
| 6578 "ln", | |
| 6579 "local", | |
| 6580 "localtime", | |
| 6581 "localtimestamp", | |
| 6582 "log", | |
| 6583 "log10", | |
| 6584 "lower", | |
| 6585 "match", | |
| 6586 "match_number", | |
| 6587 "match_recognize", | |
| 6588 "matches", | |
| 6589 "max", | |
| 6590 "member", | |
| 6591 "merge", | |
| 6592 "method", | |
| 6593 "min", | |
| 6594 "minute", | |
| 6595 "mod", | |
| 6596 "modifies", | |
| 6597 "module", | |
| 6598 "month", | |
| 6599 "multiset", | |
| 6600 "national", | |
| 6601 "natural", | |
| 6602 "nchar", | |
| 6603 "nclob", | |
| 6604 "new", | |
| 6605 "no", | |
| 6606 "none", | |
| 6607 "normalize", | |
| 6608 "not", | |
| 6609 "nth_value", | |
| 6610 "ntile", | |
| 6611 "null", | |
| 6612 "nullif", | |
| 6613 "numeric", | |
| 6614 "octet_length", | |
| 6615 "occurrences_regex", | |
| 6616 "of", | |
| 6617 "offset", | |
| 6618 "old", | |
| 6619 "omit", | |
| 6620 "on", | |
| 6621 "one", | |
| 6622 "only", | |
| 6623 "open", | |
| 6624 "or", | |
| 6625 "order", | |
| 6626 "out", | |
| 6627 "outer", | |
| 6628 "over", | |
| 6629 "overlaps", | |
| 6630 "overlay", | |
| 6631 "parameter", | |
| 6632 "partition", | |
| 6633 "pattern", | |
| 6634 "per", | |
| 6635 "percent", | |
| 6636 "percent_rank", | |
| 6637 "percentile_cont", | |
| 6638 "percentile_disc", | |
| 6639 "period", | |
| 6640 "portion", | |
| 6641 "position", | |
| 6642 "position_regex", | |
| 6643 "power", | |
| 6644 "precedes", | |
| 6645 "precision", | |
| 6646 "prepare", | |
| 6647 "primary", | |
| 6648 "procedure", | |
| 6649 "ptf", | |
| 6650 "range", | |
| 6651 "rank", | |
| 6652 "reads", | |
| 6653 "real", | |
| 6654 "recursive", | |
| 6655 "ref", | |
| 6656 "references", | |
| 6657 "referencing", | |
| 6658 "regr_avgx", | |
| 6659 "regr_avgy", | |
| 6660 "regr_count", | |
| 6661 "regr_intercept", | |
| 6662 "regr_r2", | |
| 6663 "regr_slope", | |
| 6664 "regr_sxx", | |
| 6665 "regr_sxy", | |
| 6666 "regr_syy", | |
| 6667 "release", | |
| 6668 "result", | |
| 6669 "return", | |
| 6670 "returns", | |
| 6671 "revoke", | |
| 6672 "right", | |
| 6673 "rollback", | |
| 6674 "rollup", | |
| 6675 "row", | |
| 6676 "row_number", | |
| 6677 "rows", | |
| 6678 "running", | |
| 6679 "savepoint", | |
| 6680 "scope", | |
| 6681 "scroll", | |
| 6682 "search", | |
| 6683 "second", | |
| 6684 "seek", | |
| 6685 "select", | |
| 6686 "sensitive", | |
| 6687 "session_user", | |
| 6688 "set", | |
| 6689 "show", | |
| 6690 "similar", | |
| 6691 "sin", | |
| 6692 "sinh", | |
| 6693 "skip", | |
| 6694 "smallint", | |
| 6695 "some", | |
| 6696 "specific", | |
| 6697 "specifictype", | |
| 6698 "sql", | |
| 6699 "sqlexception", | |
| 6700 "sqlstate", | |
| 6701 "sqlwarning", | |
| 6702 "sqrt", | |
| 6703 "start", | |
| 6704 "static", | |
| 6705 "stddev_pop", | |
| 6706 "stddev_samp", | |
| 6707 "submultiset", | |
| 6708 "subset", | |
| 6709 "substring", | |
| 6710 "substring_regex", | |
| 6711 "succeeds", | |
| 6712 "sum", | |
| 6713 "symmetric", | |
| 6714 "system", | |
| 6715 "system_time", | |
| 6716 "system_user", | |
| 6717 "table", | |
| 6718 "tablesample", | |
| 6719 "tan", | |
| 6720 "tanh", | |
| 6721 "then", | |
| 6722 "time", | |
| 6723 "timestamp", | |
| 6724 "timezone_hour", | |
| 6725 "timezone_minute", | |
| 6726 "to", | |
| 6727 "trailing", | |
| 6728 "translate", | |
| 6729 "translate_regex", | |
| 6730 "translation", | |
| 6731 "treat", | |
| 6732 "trigger", | |
| 6733 "trim", | |
| 6734 "trim_array", | |
| 6735 "true", | |
| 6736 "truncate", | |
| 6737 "uescape", | |
| 6738 "union", | |
| 6739 "unique", | |
| 6740 "unknown", | |
| 6741 "unnest", | |
| 6742 "update", | |
| 6743 "upper", | |
| 6744 "user", | |
| 6745 "using", | |
| 6746 "value", | |
| 6747 "values", | |
| 6748 "value_of", | |
| 6749 "var_pop", | |
| 6750 "var_samp", | |
| 6751 "varbinary", | |
| 6752 "varchar", | |
| 6753 "varying", | |
| 6754 "versioning", | |
| 6755 "when", | |
| 6756 "whenever", | |
| 6757 "where", | |
| 6758 "width_bucket", | |
| 6759 "window", | |
| 6760 "with", | |
| 6761 "within", | |
| 6762 "without", | |
| 6763 "year", | |
| 6764 ]; | |
| 6765 | |
| 6766 // these are reserved words we have identified to be functions | |
| 6767 // and should only be highlighted in a dispatch-like context | |
| 6768 // ie, array_agg(...), etc. | |
| 6769 const RESERVED_FUNCTIONS = [ | |
| 6770 "abs", | |
| 6771 "acos", | |
| 6772 "array_agg", | |
| 6773 "asin", | |
| 6774 "atan", | |
| 6775 "avg", | |
| 6776 "cast", | |
| 6777 "ceil", | |
| 6778 "ceiling", | |
| 6779 "coalesce", | |
| 6780 "corr", | |
| 6781 "cos", | |
| 6782 "cosh", | |
| 6783 "count", | |
| 6784 "covar_pop", | |
| 6785 "covar_samp", | |
| 6786 "cume_dist", | |
| 6787 "dense_rank", | |
| 6788 "deref", | |
| 6789 "element", | |
| 6790 "exp", | |
| 6791 "extract", | |
| 6792 "first_value", | |
| 6793 "floor", | |
| 6794 "json_array", | |
| 6795 "json_arrayagg", | |
| 6796 "json_exists", | |
| 6797 "json_object", | |
| 6798 "json_objectagg", | |
| 6799 "json_query", | |
| 6800 "json_table", | |
| 6801 "json_table_primitive", | |
| 6802 "json_value", | |
| 6803 "lag", | |
| 6804 "last_value", | |
| 6805 "lead", | |
| 6806 "listagg", | |
| 6807 "ln", | |
| 6808 "log", | |
| 6809 "log10", | |
| 6810 "lower", | |
| 6811 "max", | |
| 6812 "min", | |
| 6813 "mod", | |
| 6814 "nth_value", | |
| 6815 "ntile", | |
| 6816 "nullif", | |
| 6817 "percent_rank", | |
| 6818 "percentile_cont", | |
| 6819 "percentile_disc", | |
| 6820 "position", | |
| 6821 "position_regex", | |
| 6822 "power", | |
| 6823 "rank", | |
| 6824 "regr_avgx", | |
| 6825 "regr_avgy", | |
| 6826 "regr_count", | |
| 6827 "regr_intercept", | |
| 6828 "regr_r2", | |
| 6829 "regr_slope", | |
| 6830 "regr_sxx", | |
| 6831 "regr_sxy", | |
| 6832 "regr_syy", | |
| 6833 "row_number", | |
| 6834 "sin", | |
| 6835 "sinh", | |
| 6836 "sqrt", | |
| 6837 "stddev_pop", | |
| 6838 "stddev_samp", | |
| 6839 "substring", | |
| 6840 "substring_regex", | |
| 6841 "sum", | |
| 6842 "tan", | |
| 6843 "tanh", | |
| 6844 "translate", | |
| 6845 "translate_regex", | |
| 6846 "treat", | |
| 6847 "trim", | |
| 6848 "trim_array", | |
| 6849 "unnest", | |
| 6850 "upper", | |
| 6851 "value_of", | |
| 6852 "var_pop", | |
| 6853 "var_samp", | |
| 6854 "width_bucket", | |
| 6855 ]; | |
| 6856 | |
| 6857 // these functions can | |
| 6858 const POSSIBLE_WITHOUT_PARENS = [ | |
| 6859 "current_catalog", | |
| 6860 "current_date", | |
| 6861 "current_default_transform_group", | |
| 6862 "current_path", | |
| 6863 "current_role", | |
| 6864 "current_schema", | |
| 6865 "current_transform_group_for_type", | |
| 6866 "current_user", | |
| 6867 "session_user", | |
| 6868 "system_time", | |
| 6869 "system_user", | |
| 6870 "current_time", | |
| 6871 "localtime", | |
| 6872 "current_timestamp", | |
| 6873 "localtimestamp" | |
| 6874 ]; | |
| 6875 | |
| 6876 // those exist to boost relevance making these very | |
| 6877 // "SQL like" keyword combos worth +1 extra relevance | |
| 6878 const COMBOS = [ | |
| 6879 "create table", | |
| 6880 "insert into", | |
| 6881 "primary key", | |
| 6882 "foreign key", | |
| 6883 "not null", | |
| 6884 "alter table", | |
| 6885 "add constraint", | |
| 6886 "grouping sets", | |
| 6887 "on overflow", | |
| 6888 "character set", | |
| 6889 "respect nulls", | |
| 6890 "ignore nulls", | |
| 6891 "nulls first", | |
| 6892 "nulls last", | |
| 6893 "depth first", | |
| 6894 "breadth first" | |
| 6895 ]; | |
| 6896 | |
| 6897 const FUNCTIONS = RESERVED_FUNCTIONS; | |
| 6898 | |
| 6899 const KEYWORDS = [ | |
| 6900 ...RESERVED_WORDS, | |
| 6901 ...NON_RESERVED_WORDS | |
| 6902 ].filter((keyword) => { | |
| 6903 return !RESERVED_FUNCTIONS.includes(keyword); | |
| 6904 }); | |
| 6905 | |
| 6906 const VARIABLE = { | |
| 6907 scope: "variable", | |
| 6908 match: /@[a-z0-9][a-z0-9_]*/, | |
| 6909 }; | |
| 6910 | |
| 6911 const OPERATOR = { | |
| 6912 scope: "operator", | |
| 6913 match: /[-+*/=%^~]|&&?|\|\|?|!=?|<(?:=>?|<|>)?|>[>=]?/, | |
| 6914 relevance: 0, | |
| 6915 }; | |
| 6916 | |
| 6917 const FUNCTION_CALL = { | |
| 6918 match: regex.concat(/\b/, regex.either(...FUNCTIONS), /\s*\(/), | |
| 6919 relevance: 0, | |
| 6920 keywords: { built_in: FUNCTIONS } | |
| 6921 }; | |
| 6922 | |
| 6923 // turns a multi-word keyword combo into a regex that doesn't | |
| 6924 // care about extra whitespace etc. | |
| 6925 // input: "START QUERY" | |
| 6926 // output: /\bSTART\s+QUERY\b/ | |
| 6927 function kws_to_regex(list) { | |
| 6928 return regex.concat( | |
| 6929 /\b/, | |
| 6930 regex.either(...list.map((kw) => { | |
| 6931 return kw.replace(/\s+/, "\\s+") | |
| 6932 })), | |
| 6933 /\b/ | |
| 6934 ) | |
| 6935 } | |
| 6936 | |
| 6937 const MULTI_WORD_KEYWORDS = { | |
| 6938 scope: "keyword", | |
| 6939 match: kws_to_regex(COMBOS), | |
| 6940 relevance: 0, | |
| 6941 }; | |
| 6942 | |
| 6943 // keywords with less than 3 letters are reduced in relevancy | |
| 6944 function reduceRelevancy(list, { | |
| 6945 exceptions, when | |
| 6946 } = {}) { | |
| 6947 const qualifyFn = when; | |
| 6948 exceptions = exceptions || []; | |
| 6949 return list.map((item) => { | |
| 6950 if (item.match(/\|\d+$/) || exceptions.includes(item)) { | |
| 6951 return item; | |
| 6952 } else if (qualifyFn(item)) { | |
| 6953 return `${item}|0`; | |
| 6954 } else { | |
| 6955 return item; | |
| 6956 } | |
| 6957 }); | |
| 6958 } | |
| 6959 | |
| 6960 return { | |
| 6961 name: 'SQL', | |
| 6962 case_insensitive: true, | |
| 6963 // does not include {} or HTML tags `</` | |
| 6964 illegal: /[{}]|<\//, | |
| 6965 keywords: { | |
| 6966 $pattern: /\b[\w\.]+/, | |
| 6967 keyword: | |
| 6968 reduceRelevancy(KEYWORDS, { when: (x) => x.length < 3 }), | |
| 6969 literal: LITERALS, | |
| 6970 type: TYPES, | |
| 6971 built_in: POSSIBLE_WITHOUT_PARENS | |
| 6972 }, | |
| 6973 contains: [ | |
| 6974 { | |
| 6975 scope: "type", | |
| 6976 match: kws_to_regex(MULTI_WORD_TYPES) | |
| 6977 }, | |
| 6978 MULTI_WORD_KEYWORDS, | |
| 6979 FUNCTION_CALL, | |
| 6980 VARIABLE, | |
| 6981 STRING, | |
| 6982 QUOTED_IDENTIFIER, | |
| 6983 hljs.C_NUMBER_MODE, | |
| 6984 hljs.C_BLOCK_COMMENT_MODE, | |
| 6985 COMMENT_MODE, | |
| 6986 OPERATOR | |
| 6987 ] | |
| 6988 }; | |
| 6989 } | |
| 6990 | |
| 6991 return sql; | |
| 6992 | |
| 6993 })(); | |
| 6994 | |
| 6995 hljs.registerLanguage('sql', hljsGrammar); | |
| 6996 })();/*! `thrift` grammar compiled for Highlight.js 11.11.1 */ | |
| 6997 (function(){ | |
| 6998 var hljsGrammar = (function () { | |
| 6999 'use strict'; | |
| 7000 | |
| 7001 /* | |
| 7002 Language: Thrift | |
| 7003 Author: Oleg Efimov <[email protected]> | |
| 7004 Description: Thrift message definition format | |
| 7005 Website: https://thrift.apache.org | |
| 7006 Category: protocols | |
| 7007 */ | |
| 7008 | |
| 7009 function thrift(hljs) { | |
| 7010 const TYPES = [ | |
| 7011 "bool", | |
| 7012 "byte", | |
| 7013 "i16", | |
| 7014 "i32", | |
| 7015 "i64", | |
| 7016 "double", | |
| 7017 "string", | |
| 7018 "binary" | |
| 7019 ]; | |
| 7020 const KEYWORDS = [ | |
| 7021 "namespace", | |
| 7022 "const", | |
| 7023 "typedef", | |
| 7024 "struct", | |
| 7025 "enum", | |
| 7026 "service", | |
| 7027 "exception", | |
| 7028 "void", | |
| 7029 "oneway", | |
| 7030 "set", | |
| 7031 "list", | |
| 7032 "map", | |
| 7033 "required", | |
| 7034 "optional" | |
| 7035 ]; | |
| 7036 return { | |
| 7037 name: 'Thrift', | |
| 7038 keywords: { | |
| 7039 keyword: KEYWORDS, | |
| 7040 type: TYPES, | |
| 7041 literal: 'true false' | |
| 7042 }, | |
| 7043 contains: [ | |
| 7044 hljs.QUOTE_STRING_MODE, | |
| 7045 hljs.NUMBER_MODE, | |
| 7046 hljs.C_LINE_COMMENT_MODE, | |
| 7047 hljs.C_BLOCK_COMMENT_MODE, | |
| 7048 { | |
| 7049 className: 'class', | |
| 7050 beginKeywords: 'struct enum service exception', | |
| 7051 end: /\{/, | |
| 7052 illegal: /\n/, | |
| 7053 contains: [ | |
| 7054 hljs.inherit(hljs.TITLE_MODE, { | |
| 7055 // hack: eating everything after the first title | |
| 7056 starts: { | |
| 7057 endsWithParent: true, | |
| 7058 excludeEnd: true | |
| 7059 } }) | |
| 7060 ] | |
| 7061 }, | |
| 7062 { | |
| 7063 begin: '\\b(set|list|map)\\s*<', | |
| 7064 keywords: { type: [ | |
| 7065 ...TYPES, | |
| 7066 "set", | |
| 7067 "list", | |
| 7068 "map" | |
| 7069 ] }, | |
| 7070 end: '>', | |
| 7071 contains: [ 'self' ] | |
| 7072 } | |
| 7073 ] | |
| 7074 }; | |
| 7075 } | |
| 7076 | |
| 7077 return thrift; | |
| 7078 | |
| 7079 })(); | |
| 7080 | |
| 7081 hljs.registerLanguage('thrift', hljsGrammar); | |
| 7082 })();/*! `typescript` grammar compiled for Highlight.js 11.11.1 */ | |
| 7083 (function(){ | |
| 7084 var hljsGrammar = (function () { | |
| 7085 'use strict'; | |
| 7086 | |
| 7087 const IDENT_RE = '[A-Za-z$_][0-9A-Za-z$_]*'; | |
| 7088 const KEYWORDS = [ | |
| 7089 "as", // for exports | |
| 7090 "in", | |
| 7091 "of", | |
| 7092 "if", | |
| 7093 "for", | |
| 7094 "while", | |
| 7095 "finally", | |
| 7096 "var", | |
| 7097 "new", | |
| 7098 "function", | |
| 7099 "do", | |
| 7100 "return", | |
| 7101 "void", | |
| 7102 "else", | |
| 7103 "break", | |
| 7104 "catch", | |
| 7105 "instanceof", | |
| 7106 "with", | |
| 7107 "throw", | |
| 7108 "case", | |
| 7109 "default", | |
| 7110 "try", | |
| 7111 "switch", | |
| 7112 "continue", | |
| 7113 "typeof", | |
| 7114 "delete", | |
| 7115 "let", | |
| 7116 "yield", | |
| 7117 "const", | |
| 7118 "class", | |
| 7119 // JS handles these with a special rule | |
| 7120 // "get", | |
| 7121 // "set", | |
| 7122 "debugger", | |
| 7123 "async", | |
| 7124 "await", | |
| 7125 "static", | |
| 7126 "import", | |
| 7127 "from", | |
| 7128 "export", | |
| 7129 "extends", | |
| 7130 // It's reached stage 3, which is "recommended for implementation": | |
| 7131 "using" | |
| 7132 ]; | |
| 7133 const LITERALS = [ | |
| 7134 "true", | |
| 7135 "false", | |
| 7136 "null", | |
| 7137 "undefined", | |
| 7138 "NaN", | |
| 7139 "Infinity" | |
| 7140 ]; | |
| 7141 | |
| 7142 // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects | |
| 7143 const TYPES = [ | |
| 7144 // Fundamental objects | |
| 7145 "Object", | |
| 7146 "Function", | |
| 7147 "Boolean", | |
| 7148 "Symbol", | |
| 7149 // numbers and dates | |
| 7150 "Math", | |
| 7151 "Date", | |
| 7152 "Number", | |
| 7153 "BigInt", | |
| 7154 // text | |
| 7155 "String", | |
| 7156 "RegExp", | |
| 7157 // Indexed collections | |
| 7158 "Array", | |
| 7159 "Float32Array", | |
| 7160 "Float64Array", | |
| 7161 "Int8Array", | |
| 7162 "Uint8Array", | |
| 7163 "Uint8ClampedArray", | |
| 7164 "Int16Array", | |
| 7165 "Int32Array", | |
| 7166 "Uint16Array", | |
| 7167 "Uint32Array", | |
| 7168 "BigInt64Array", | |
| 7169 "BigUint64Array", | |
| 7170 // Keyed collections | |
| 7171 "Set", | |
| 7172 "Map", | |
| 7173 "WeakSet", | |
| 7174 "WeakMap", | |
| 7175 // Structured data | |
| 7176 "ArrayBuffer", | |
| 7177 "SharedArrayBuffer", | |
| 7178 "Atomics", | |
| 7179 "DataView", | |
| 7180 "JSON", | |
| 7181 // Control abstraction objects | |
| 7182 "Promise", | |
| 7183 "Generator", | |
| 7184 "GeneratorFunction", | |
| 7185 "AsyncFunction", | |
| 7186 // Reflection | |
| 7187 "Reflect", | |
| 7188 "Proxy", | |
| 7189 // Internationalization | |
| 7190 "Intl", | |
| 7191 // WebAssembly | |
| 7192 "WebAssembly" | |
| 7193 ]; | |
| 7194 | |
| 7195 const ERROR_TYPES = [ | |
| 7196 "Error", | |
| 7197 "EvalError", | |
| 7198 "InternalError", | |
| 7199 "RangeError", | |
| 7200 "ReferenceError", | |
| 7201 "SyntaxError", | |
| 7202 "TypeError", | |
| 7203 "URIError" | |
| 7204 ]; | |
| 7205 | |
| 7206 const BUILT_IN_GLOBALS = [ | |
| 7207 "setInterval", | |
| 7208 "setTimeout", | |
| 7209 "clearInterval", | |
| 7210 "clearTimeout", | |
| 7211 | |
| 7212 "require", | |
| 7213 "exports", | |
| 7214 | |
| 7215 "eval", | |
| 7216 "isFinite", | |
| 7217 "isNaN", | |
| 7218 "parseFloat", | |
| 7219 "parseInt", | |
| 7220 "decodeURI", | |
| 7221 "decodeURIComponent", | |
| 7222 "encodeURI", | |
| 7223 "encodeURIComponent", | |
| 7224 "escape", | |
| 7225 "unescape" | |
| 7226 ]; | |
| 7227 | |
| 7228 const BUILT_IN_VARIABLES = [ | |
| 7229 "arguments", | |
| 7230 "this", | |
| 7231 "super", | |
| 7232 "console", | |
| 7233 "window", | |
| 7234 "document", | |
| 7235 "localStorage", | |
| 7236 "sessionStorage", | |
| 7237 "module", | |
| 7238 "global" // Node.js | |
| 7239 ]; | |
| 7240 | |
| 7241 const BUILT_INS = [].concat( | |
| 7242 BUILT_IN_GLOBALS, | |
| 7243 TYPES, | |
| 7244 ERROR_TYPES | |
| 7245 ); | |
| 7246 | |
| 7247 /* | |
| 7248 Language: JavaScript | |
| 7249 Description: JavaScript (JS) is a lightweight, interpreted, or just-in-time compiled programming language with first-class functions. | |
| 7250 Category: common, scripting, web | |
| 7251 Website: https://developer.mozilla.org/en-US/docs/Web/JavaScript | |
| 7252 */ | |
| 7253 | |
| 7254 | |
| 7255 /** @type LanguageFn */ | |
| 7256 function javascript(hljs) { | |
| 7257 const regex = hljs.regex; | |
| 7258 /** | |
| 7259 * Takes a string like "<Booger" and checks to see | |
| 7260 * if we can find a matching "</Booger" later in the | |
| 7261 * content. | |
| 7262 * @param {RegExpMatchArray} match | |
| 7263 * @param {{after:number}} param1 | |
| 7264 */ | |
| 7265 const hasClosingTag = (match, { after }) => { | |
| 7266 const tag = "</" + match[0].slice(1); | |
| 7267 const pos = match.input.indexOf(tag, after); | |
| 7268 return pos !== -1; | |
| 7269 }; | |
| 7270 | |
| 7271 const IDENT_RE$1 = IDENT_RE; | |
| 7272 const FRAGMENT = { | |
| 7273 begin: '<>', | |
| 7274 end: '</>' | |
| 7275 }; | |
| 7276 // to avoid some special cases inside isTrulyOpeningTag | |
| 7277 const XML_SELF_CLOSING = /<[A-Za-z0-9\\._:-]+\s*\/>/; | |
| 7278 const XML_TAG = { | |
| 7279 begin: /<[A-Za-z0-9\\._:-]+/, | |
| 7280 end: /\/[A-Za-z0-9\\._:-]+>|\/>/, | |
| 7281 /** | |
| 7282 * @param {RegExpMatchArray} match | |
| 7283 * @param {CallbackResponse} response | |
| 7284 */ | |
| 7285 isTrulyOpeningTag: (match, response) => { | |
| 7286 const afterMatchIndex = match[0].length + match.index; | |
| 7287 const nextChar = match.input[afterMatchIndex]; | |
| 7288 if ( | |
| 7289 // HTML should not include another raw `<` inside a tag | |
| 7290 // nested type? | |
| 7291 // `<Array<Array<number>>`, etc. | |
| 7292 nextChar === "<" || | |
| 7293 // the , gives away that this is not HTML | |
| 7294 // `<T, A extends keyof T, V>` | |
| 7295 nextChar === "," | |
| 7296 ) { | |
| 7297 response.ignoreMatch(); | |
| 7298 return; | |
| 7299 } | |
| 7300 | |
| 7301 // `<something>` | |
| 7302 // Quite possibly a tag, lets look for a matching closing tag... | |
| 7303 if (nextChar === ">") { | |
| 7304 // if we cannot find a matching closing tag, then we | |
| 7305 // will ignore it | |
| 7306 if (!hasClosingTag(match, { after: afterMatchIndex })) { | |
| 7307 response.ignoreMatch(); | |
| 7308 } | |
| 7309 } | |
| 7310 | |
| 7311 // `<blah />` (self-closing) | |
| 7312 // handled by simpleSelfClosing rule | |
| 7313 | |
| 7314 let m; | |
| 7315 const afterMatch = match.input.substring(afterMatchIndex); | |
| 7316 | |
| 7317 // some more template typing stuff | |
| 7318 // <T = any>(key?: string) => Modify< | |
| 7319 if ((m = afterMatch.match(/^\s*=/))) { | |
| 7320 response.ignoreMatch(); | |
| 7321 return; | |
| 7322 } | |
| 7323 | |
| 7324 // `<From extends string>` | |
| 7325 // technically this could be HTML, but it smells like a type | |
| 7326 // NOTE: This is ugh, but added specifically for https://github.com/highlightjs/highlight.js/issues/3276 | |
| 7327 if ((m = afterMatch.match(/^\s+extends\s+/))) { | |
| 7328 if (m.index === 0) { | |
| 7329 response.ignoreMatch(); | |
| 7330 // eslint-disable-next-line no-useless-return | |
| 7331 return; | |
| 7332 } | |
| 7333 } | |
| 7334 } | |
| 7335 }; | |
| 7336 const KEYWORDS$1 = { | |
| 7337 $pattern: IDENT_RE, | |
| 7338 keyword: KEYWORDS, | |
| 7339 literal: LITERALS, | |
| 7340 built_in: BUILT_INS, | |
| 7341 "variable.language": BUILT_IN_VARIABLES | |
| 7342 }; | |
| 7343 | |
| 7344 // https://tc39.es/ecma262/#sec-literals-numeric-literals | |
| 7345 const decimalDigits = '[0-9](_?[0-9])*'; | |
| 7346 const frac = `\\.(${decimalDigits})`; | |
| 7347 // DecimalIntegerLiteral, including Annex B NonOctalDecimalIntegerLiteral | |
| 7348 // https://tc39.es/ecma262/#sec-additional-syntax-numeric-literals | |
| 7349 const decimalInteger = `0|[1-9](_?[0-9])*|0[0-7]*[89][0-9]*`; | |
| 7350 const NUMBER = { | |
| 7351 className: 'number', | |
| 7352 variants: [ | |
| 7353 // DecimalLiteral | |
| 7354 { begin: `(\\b(${decimalInteger})((${frac})|\\.)?|(${frac}))` + | |
| 7355 `[eE][+-]?(${decimalDigits})\\b` }, | |
| 7356 { begin: `\\b(${decimalInteger})\\b((${frac})\\b|\\.)?|(${frac})\\b` }, | |
| 7357 | |
| 7358 // DecimalBigIntegerLiteral | |
| 7359 { begin: `\\b(0|[1-9](_?[0-9])*)n\\b` }, | |
| 7360 | |
| 7361 // NonDecimalIntegerLiteral | |
| 7362 { begin: "\\b0[xX][0-9a-fA-F](_?[0-9a-fA-F])*n?\\b" }, | |
| 7363 { begin: "\\b0[bB][0-1](_?[0-1])*n?\\b" }, | |
| 7364 { begin: "\\b0[oO][0-7](_?[0-7])*n?\\b" }, | |
| 7365 | |
| 7366 // LegacyOctalIntegerLiteral (does not include underscore separators) | |
| 7367 // https://tc39.es/ecma262/#sec-additional-syntax-numeric-literals | |
| 7368 { begin: "\\b0[0-7]+n?\\b" }, | |
| 7369 ], | |
| 7370 relevance: 0 | |
| 7371 }; | |
| 7372 | |
| 7373 const SUBST = { | |
| 7374 className: 'subst', | |
| 7375 begin: '\\$\\{', | |
| 7376 end: '\\}', | |
| 7377 keywords: KEYWORDS$1, | |
| 7378 contains: [] // defined later | |
| 7379 }; | |
| 7380 const HTML_TEMPLATE = { | |
| 7381 begin: '\.?html`', | |
| 7382 end: '', | |
| 7383 starts: { | |
| 7384 end: '`', | |
| 7385 returnEnd: false, | |
| 7386 contains: [ | |
| 7387 hljs.BACKSLASH_ESCAPE, | |
| 7388 SUBST | |
| 7389 ], | |
| 7390 subLanguage: 'xml' | |
| 7391 } | |
| 7392 }; | |
| 7393 const CSS_TEMPLATE = { | |
| 7394 begin: '\.?css`', | |
| 7395 end: '', | |
| 7396 starts: { | |
| 7397 end: '`', | |
| 7398 returnEnd: false, | |
| 7399 contains: [ | |
| 7400 hljs.BACKSLASH_ESCAPE, | |
| 7401 SUBST | |
| 7402 ], | |
| 7403 subLanguage: 'css' | |
| 7404 } | |
| 7405 }; | |
| 7406 const GRAPHQL_TEMPLATE = { | |
| 7407 begin: '\.?gql`', | |
| 7408 end: '', | |
| 7409 starts: { | |
| 7410 end: '`', | |
| 7411 returnEnd: false, | |
| 7412 contains: [ | |
| 7413 hljs.BACKSLASH_ESCAPE, | |
| 7414 SUBST | |
| 7415 ], | |
| 7416 subLanguage: 'graphql' | |
| 7417 } | |
| 7418 }; | |
| 7419 const TEMPLATE_STRING = { | |
| 7420 className: 'string', | |
| 7421 begin: '`', | |
| 7422 end: '`', | |
| 7423 contains: [ | |
| 7424 hljs.BACKSLASH_ESCAPE, | |
| 7425 SUBST | |
| 7426 ] | |
| 7427 }; | |
| 7428 const JSDOC_COMMENT = hljs.COMMENT( | |
| 7429 /\/\*\*(?!\/)/, | |
| 7430 '\\*/', | |
| 7431 { | |
| 7432 relevance: 0, | |
| 7433 contains: [ | |
| 7434 { | |
| 7435 begin: '(?=@[A-Za-z]+)', | |
| 7436 relevance: 0, | |
| 7437 contains: [ | |
| 7438 { | |
| 7439 className: 'doctag', | |
| 7440 begin: '@[A-Za-z]+' | |
| 7441 }, | |
| 7442 { | |
| 7443 className: 'type', | |
| 7444 begin: '\\{', | |
| 7445 end: '\\}', | |
| 7446 excludeEnd: true, | |
| 7447 excludeBegin: true, | |
| 7448 relevance: 0 | |
| 7449 }, | |
| 7450 { | |
| 7451 className: 'variable', | |
| 7452 begin: IDENT_RE$1 + '(?=\\s*(-)|$)', | |
| 7453 endsParent: true, | |
| 7454 relevance: 0 | |
| 7455 }, | |
| 7456 // eat spaces (not newlines) so we can find | |
| 7457 // types or variables | |
| 7458 { | |
| 7459 begin: /(?=[^\n])\s/, | |
| 7460 relevance: 0 | |
| 7461 } | |
| 7462 ] | |
| 7463 } | |
| 7464 ] | |
| 7465 } | |
| 7466 ); | |
| 7467 const COMMENT = { | |
| 7468 className: "comment", | |
| 7469 variants: [ | |
| 7470 JSDOC_COMMENT, | |
| 7471 hljs.C_BLOCK_COMMENT_MODE, | |
| 7472 hljs.C_LINE_COMMENT_MODE | |
| 7473 ] | |
| 7474 }; | |
| 7475 const SUBST_INTERNALS = [ | |
| 7476 hljs.APOS_STRING_MODE, | |
| 7477 hljs.QUOTE_STRING_MODE, | |
| 7478 HTML_TEMPLATE, | |
| 7479 CSS_TEMPLATE, | |
| 7480 GRAPHQL_TEMPLATE, | |
| 7481 TEMPLATE_STRING, | |
| 7482 // Skip numbers when they are part of a variable name | |
| 7483 { match: /\$\d+/ }, | |
| 7484 NUMBER, | |
| 7485 // This is intentional: | |
| 7486 // See https://github.com/highlightjs/highlight.js/issues/3288 | |
| 7487 // hljs.REGEXP_MODE | |
| 7488 ]; | |
| 7489 SUBST.contains = SUBST_INTERNALS | |
| 7490 .concat({ | |
| 7491 // we need to pair up {} inside our subst to prevent | |
| 7492 // it from ending too early by matching another } | |
| 7493 begin: /\{/, | |
| 7494 end: /\}/, | |
| 7495 keywords: KEYWORDS$1, | |
| 7496 contains: [ | |
| 7497 "self" | |
| 7498 ].concat(SUBST_INTERNALS) | |
| 7499 }); | |
| 7500 const SUBST_AND_COMMENTS = [].concat(COMMENT, SUBST.contains); | |
| 7501 const PARAMS_CONTAINS = SUBST_AND_COMMENTS.concat([ | |
| 7502 // eat recursive parens in sub expressions | |
| 7503 { | |
| 7504 begin: /(\s*)\(/, | |
| 7505 end: /\)/, | |
| 7506 keywords: KEYWORDS$1, | |
| 7507 contains: ["self"].concat(SUBST_AND_COMMENTS) | |
| 7508 } | |
| 7509 ]); | |
| 7510 const PARAMS = { | |
| 7511 className: 'params', | |
| 7512 // convert this to negative lookbehind in v12 | |
| 7513 begin: /(\s*)\(/, // to match the parms with | |
| 7514 end: /\)/, | |
| 7515 excludeBegin: true, | |
| 7516 excludeEnd: true, | |
| 7517 keywords: KEYWORDS$1, | |
| 7518 contains: PARAMS_CONTAINS | |
| 7519 }; | |
| 7520 | |
| 7521 // ES6 classes | |
| 7522 const CLASS_OR_EXTENDS = { | |
| 7523 variants: [ | |
| 7524 // class Car extends vehicle | |
| 7525 { | |
| 7526 match: [ | |
| 7527 /class/, | |
| 7528 /\s+/, | |
| 7529 IDENT_RE$1, | |
| 7530 /\s+/, | |
| 7531 /extends/, | |
| 7532 /\s+/, | |
| 7533 regex.concat(IDENT_RE$1, "(", regex.concat(/\./, IDENT_RE$1), ")*") | |
| 7534 ], | |
| 7535 scope: { | |
| 7536 1: "keyword", | |
| 7537 3: "title.class", | |
| 7538 5: "keyword", | |
| 7539 7: "title.class.inherited" | |
| 7540 } | |
| 7541 }, | |
| 7542 // class Car | |
| 7543 { | |
| 7544 match: [ | |
| 7545 /class/, | |
| 7546 /\s+/, | |
| 7547 IDENT_RE$1 | |
| 7548 ], | |
| 7549 scope: { | |
| 7550 1: "keyword", | |
| 7551 3: "title.class" | |
| 7552 } | |
| 7553 }, | |
| 7554 | |
| 7555 ] | |
| 7556 }; | |
| 7557 | |
| 7558 const CLASS_REFERENCE = { | |
| 7559 relevance: 0, | |
| 7560 match: | |
| 7561 regex.either( | |
| 7562 // Hard coded exceptions | |
| 7563 /\bJSON/, | |
| 7564 // Float32Array, OutT | |
| 7565 /\b[A-Z][a-z]+([A-Z][a-z]*|\d)*/, | |
| 7566 // CSSFactory, CSSFactoryT | |
| 7567 /\b[A-Z]{2,}([A-Z][a-z]+|\d)+([A-Z][a-z]*)*/, | |
| 7568 // FPs, FPsT | |
| 7569 /\b[A-Z]{2,}[a-z]+([A-Z][a-z]+|\d)*([A-Z][a-z]*)*/, | |
| 7570 // P | |
| 7571 // single letters are not highlighted | |
| 7572 // BLAH | |
| 7573 // this will be flagged as a UPPER_CASE_CONSTANT instead | |
| 7574 ), | |
| 7575 className: "title.class", | |
| 7576 keywords: { | |
| 7577 _: [ | |
| 7578 // se we still get relevance credit for JS library classes | |
| 7579 ...TYPES, | |
| 7580 ...ERROR_TYPES | |
| 7581 ] | |
| 7582 } | |
| 7583 }; | |
| 7584 | |
| 7585 const USE_STRICT = { | |
| 7586 label: "use_strict", | |
| 7587 className: 'meta', | |
| 7588 relevance: 10, | |
| 7589 begin: /^\s*['"]use (strict|asm)['"]/ | |
| 7590 }; | |
| 7591 | |
| 7592 const FUNCTION_DEFINITION = { | |
| 7593 variants: [ | |
| 7594 { | |
| 7595 match: [ | |
| 7596 /function/, | |
| 7597 /\s+/, | |
| 7598 IDENT_RE$1, | |
| 7599 /(?=\s*\()/ | |
| 7600 ] | |
| 7601 }, | |
| 7602 // anonymous function | |
| 7603 { | |
| 7604 match: [ | |
| 7605 /function/, | |
| 7606 /\s*(?=\()/ | |
| 7607 ] | |
| 7608 } | |
| 7609 ], | |
| 7610 className: { | |
| 7611 1: "keyword", | |
| 7612 3: "title.function" | |
| 7613 }, | |
| 7614 label: "func.def", | |
| 7615 contains: [ PARAMS ], | |
| 7616 illegal: /%/ | |
| 7617 }; | |
| 7618 | |
| 7619 const UPPER_CASE_CONSTANT = { | |
| 7620 relevance: 0, | |
| 7621 match: /\b[A-Z][A-Z_0-9]+\b/, | |
| 7622 className: "variable.constant" | |
| 7623 }; | |
| 7624 | |
| 7625 function noneOf(list) { | |
| 7626 return regex.concat("(?!", list.join("|"), ")"); | |
| 7627 } | |
| 7628 | |
| 7629 const FUNCTION_CALL = { | |
| 7630 match: regex.concat( | |
| 7631 /\b/, | |
| 7632 noneOf([ | |
| 7633 ...BUILT_IN_GLOBALS, | |
| 7634 "super", | |
| 7635 "import" | |
| 7636 ].map(x => `${x}\\s*\\(`)), | |
| 7637 IDENT_RE$1, regex.lookahead(/\s*\(/)), | |
| 7638 className: "title.function", | |
| 7639 relevance: 0 | |
| 7640 }; | |
| 7641 | |
| 7642 const PROPERTY_ACCESS = { | |
| 7643 begin: regex.concat(/\./, regex.lookahead( | |
| 7644 regex.concat(IDENT_RE$1, /(?![0-9A-Za-z$_(])/) | |
| 7645 )), | |
| 7646 end: IDENT_RE$1, | |
| 7647 excludeBegin: true, | |
| 7648 keywords: "prototype", | |
| 7649 className: "property", | |
| 7650 relevance: 0 | |
| 7651 }; | |
| 7652 | |
| 7653 const GETTER_OR_SETTER = { | |
| 7654 match: [ | |
| 7655 /get|set/, | |
| 7656 /\s+/, | |
| 7657 IDENT_RE$1, | |
| 7658 /(?=\()/ | |
| 7659 ], | |
| 7660 className: { | |
| 7661 1: "keyword", | |
| 7662 3: "title.function" | |
| 7663 }, | |
| 7664 contains: [ | |
| 7665 { // eat to avoid empty params | |
| 7666 begin: /\(\)/ | |
| 7667 }, | |
| 7668 PARAMS | |
| 7669 ] | |
| 7670 }; | |
| 7671 | |
| 7672 const FUNC_LEAD_IN_RE = '(\\(' + | |
| 7673 '[^()]*(\\(' + | |
| 7674 '[^()]*(\\(' + | |
| 7675 '[^()]*' + | |
| 7676 '\\)[^()]*)*' + | |
| 7677 '\\)[^()]*)*' + | |
| 7678 '\\)|' + hljs.UNDERSCORE_IDENT_RE + ')\\s*=>'; | |
| 7679 | |
| 7680 const FUNCTION_VARIABLE = { | |
| 7681 match: [ | |
| 7682 /const|var|let/, /\s+/, | |
| 7683 IDENT_RE$1, /\s*/, | |
| 7684 /=\s*/, | |
| 7685 /(async\s*)?/, // async is optional | |
| 7686 regex.lookahead(FUNC_LEAD_IN_RE) | |
| 7687 ], | |
| 7688 keywords: "async", | |
| 7689 className: { | |
| 7690 1: "keyword", | |
| 7691 3: "title.function" | |
| 7692 }, | |
| 7693 contains: [ | |
| 7694 PARAMS | |
| 7695 ] | |
| 7696 }; | |
| 7697 | |
| 7698 return { | |
| 7699 name: 'JavaScript', | |
| 7700 aliases: ['js', 'jsx', 'mjs', 'cjs'], | |
| 7701 keywords: KEYWORDS$1, | |
| 7702 // this will be extended by TypeScript | |
| 7703 exports: { PARAMS_CONTAINS, CLASS_REFERENCE }, | |
| 7704 illegal: /#(?![$_A-z])/, | |
| 7705 contains: [ | |
| 7706 hljs.SHEBANG({ | |
| 7707 label: "shebang", | |
| 7708 binary: "node", | |
| 7709 relevance: 5 | |
| 7710 }), | |
| 7711 USE_STRICT, | |
| 7712 hljs.APOS_STRING_MODE, | |
| 7713 hljs.QUOTE_STRING_MODE, | |
| 7714 HTML_TEMPLATE, | |
| 7715 CSS_TEMPLATE, | |
| 7716 GRAPHQL_TEMPLATE, | |
| 7717 TEMPLATE_STRING, | |
| 7718 COMMENT, | |
| 7719 // Skip numbers when they are part of a variable name | |
| 7720 { match: /\$\d+/ }, | |
| 7721 NUMBER, | |
| 7722 CLASS_REFERENCE, | |
| 7723 { | |
| 7724 scope: 'attr', | |
| 7725 match: IDENT_RE$1 + regex.lookahead(':'), | |
| 7726 relevance: 0 | |
| 7727 }, | |
| 7728 FUNCTION_VARIABLE, | |
| 7729 { // "value" container | |
| 7730 begin: '(' + hljs.RE_STARTERS_RE + '|\\b(case|return|throw)\\b)\\s*', | |
| 7731 keywords: 'return throw case', | |
| 7732 relevance: 0, | |
| 7733 contains: [ | |
| 7734 COMMENT, | |
| 7735 hljs.REGEXP_MODE, | |
| 7736 { | |
| 7737 className: 'function', | |
| 7738 // we have to count the parens to make sure we actually have the | |
| 7739 // correct bounding ( ) before the =>. There could be any number of | |
| 7740 // sub-expressions inside also surrounded by parens. | |
| 7741 begin: FUNC_LEAD_IN_RE, | |
| 7742 returnBegin: true, | |
| 7743 end: '\\s*=>', | |
| 7744 contains: [ | |
| 7745 { | |
| 7746 className: 'params', | |
| 7747 variants: [ | |
| 7748 { | |
| 7749 begin: hljs.UNDERSCORE_IDENT_RE, | |
| 7750 relevance: 0 | |
| 7751 }, | |
| 7752 { | |
| 7753 className: null, | |
| 7754 begin: /\(\s*\)/, | |
| 7755 skip: true | |
| 7756 }, | |
| 7757 { | |
| 7758 begin: /(\s*)\(/, | |
| 7759 end: /\)/, | |
| 7760 excludeBegin: true, | |
| 7761 excludeEnd: true, | |
| 7762 keywords: KEYWORDS$1, | |
| 7763 contains: PARAMS_CONTAINS | |
| 7764 } | |
| 7765 ] | |
| 7766 } | |
| 7767 ] | |
| 7768 }, | |
| 7769 { // could be a comma delimited list of params to a function call | |
| 7770 begin: /,/, | |
| 7771 relevance: 0 | |
| 7772 }, | |
| 7773 { | |
| 7774 match: /\s+/, | |
| 7775 relevance: 0 | |
| 7776 }, | |
| 7777 { // JSX | |
| 7778 variants: [ | |
| 7779 { begin: FRAGMENT.begin, end: FRAGMENT.end }, | |
| 7780 { match: XML_SELF_CLOSING }, | |
| 7781 { | |
| 7782 begin: XML_TAG.begin, | |
| 7783 // we carefully check the opening tag to see if it truly | |
| 7784 // is a tag and not a false positive | |
| 7785 'on:begin': XML_TAG.isTrulyOpeningTag, | |
| 7786 end: XML_TAG.end | |
| 7787 } | |
| 7788 ], | |
| 7789 subLanguage: 'xml', | |
| 7790 contains: [ | |
| 7791 { | |
| 7792 begin: XML_TAG.begin, | |
| 7793 end: XML_TAG.end, | |
| 7794 skip: true, | |
| 7795 contains: ['self'] | |
| 7796 } | |
| 7797 ] | |
| 7798 } | |
| 7799 ], | |
| 7800 }, | |
| 7801 FUNCTION_DEFINITION, | |
| 7802 { | |
| 7803 // prevent this from getting swallowed up by function | |
| 7804 // since they appear "function like" | |
| 7805 beginKeywords: "while if switch catch for" | |
| 7806 }, | |
| 7807 { | |
| 7808 // we have to count the parens to make sure we actually have the correct | |
| 7809 // bounding ( ). There could be any number of sub-expressions inside | |
| 7810 // also surrounded by parens. | |
| 7811 begin: '\\b(?!function)' + hljs.UNDERSCORE_IDENT_RE + | |
| 7812 '\\(' + // first parens | |
| 7813 '[^()]*(\\(' + | |
| 7814 '[^()]*(\\(' + | |
| 7815 '[^()]*' + | |
| 7816 '\\)[^()]*)*' + | |
| 7817 '\\)[^()]*)*' + | |
| 7818 '\\)\\s*\\{', // end parens | |
| 7819 returnBegin:true, | |
| 7820 label: "func.def", | |
| 7821 contains: [ | |
| 7822 PARAMS, | |
| 7823 hljs.inherit(hljs.TITLE_MODE, { begin: IDENT_RE$1, className: "title.function" }) | |
| 7824 ] | |
| 7825 }, | |
| 7826 // catch ... so it won't trigger the property rule below | |
| 7827 { | |
| 7828 match: /\.\.\./, | |
| 7829 relevance: 0 | |
| 7830 }, | |
| 7831 PROPERTY_ACCESS, | |
| 7832 // hack: prevents detection of keywords in some circumstances | |
| 7833 // .keyword() | |
| 7834 // $keyword = x | |
| 7835 { | |
| 7836 match: '\\$' + IDENT_RE$1, | |
| 7837 relevance: 0 | |
| 7838 }, | |
| 7839 { | |
| 7840 match: [ /\bconstructor(?=\s*\()/ ], | |
| 7841 className: { 1: "title.function" }, | |
| 7842 contains: [ PARAMS ] | |
| 7843 }, | |
| 7844 FUNCTION_CALL, | |
| 7845 UPPER_CASE_CONSTANT, | |
| 7846 CLASS_OR_EXTENDS, | |
| 7847 GETTER_OR_SETTER, | |
| 7848 { | |
| 7849 match: /\$[(.]/ // relevance booster for a pattern common to JS libs: `$(something)` and `$.something` | |
| 7850 } | |
| 7851 ] | |
| 7852 }; | |
| 7853 } | |
| 7854 | |
| 7855 /* | |
| 7856 Language: TypeScript | |
| 7857 Author: Panu Horsmalahti <[email protected]> | |
| 7858 Contributors: Ike Ku <[email protected]> | |
| 7859 Description: TypeScript is a strict superset of JavaScript | |
| 7860 Website: https://www.typescriptlang.org | |
| 7861 Category: common, scripting | |
| 7862 */ | |
| 7863 | |
| 7864 | |
| 7865 /** @type LanguageFn */ | |
| 7866 function typescript(hljs) { | |
| 7867 const regex = hljs.regex; | |
| 7868 const tsLanguage = javascript(hljs); | |
| 7869 | |
| 7870 const IDENT_RE$1 = IDENT_RE; | |
| 7871 const TYPES = [ | |
| 7872 "any", | |
| 7873 "void", | |
| 7874 "number", | |
| 7875 "boolean", | |
| 7876 "string", | |
| 7877 "object", | |
| 7878 "never", | |
| 7879 "symbol", | |
| 7880 "bigint", | |
| 7881 "unknown" | |
| 7882 ]; | |
| 7883 const NAMESPACE = { | |
| 7884 begin: [ | |
| 7885 /namespace/, | |
| 7886 /\s+/, | |
| 7887 hljs.IDENT_RE | |
| 7888 ], | |
| 7889 beginScope: { | |
| 7890 1: "keyword", | |
| 7891 3: "title.class" | |
| 7892 } | |
| 7893 }; | |
| 7894 const INTERFACE = { | |
| 7895 beginKeywords: 'interface', | |
| 7896 end: /\{/, | |
| 7897 excludeEnd: true, | |
| 7898 keywords: { | |
| 7899 keyword: 'interface extends', | |
| 7900 built_in: TYPES | |
| 7901 }, | |
| 7902 contains: [ tsLanguage.exports.CLASS_REFERENCE ] | |
| 7903 }; | |
| 7904 const USE_STRICT = { | |
| 7905 className: 'meta', | |
| 7906 relevance: 10, | |
| 7907 begin: /^\s*['"]use strict['"]/ | |
| 7908 }; | |
| 7909 const TS_SPECIFIC_KEYWORDS = [ | |
| 7910 "type", | |
| 7911 // "namespace", | |
| 7912 "interface", | |
| 7913 "public", | |
| 7914 "private", | |
| 7915 "protected", | |
| 7916 "implements", | |
| 7917 "declare", | |
| 7918 "abstract", | |
| 7919 "readonly", | |
| 7920 "enum", | |
| 7921 "override", | |
| 7922 "satisfies" | |
| 7923 ]; | |
| 7924 /* | |
| 7925 namespace is a TS keyword but it's fine to use it as a variable name too. | |
| 7926 const message = 'foo'; | |
| 7927 const namespace = 'bar'; | |
| 7928 */ | |
| 7929 const KEYWORDS$1 = { | |
| 7930 $pattern: IDENT_RE, | |
| 7931 keyword: KEYWORDS.concat(TS_SPECIFIC_KEYWORDS), | |
| 7932 literal: LITERALS, | |
| 7933 built_in: BUILT_INS.concat(TYPES), | |
| 7934 "variable.language": BUILT_IN_VARIABLES | |
| 7935 }; | |
| 7936 | |
| 7937 const DECORATOR = { | |
| 7938 className: 'meta', | |
| 7939 begin: '@' + IDENT_RE$1, | |
| 7940 }; | |
| 7941 | |
| 7942 const swapMode = (mode, label, replacement) => { | |
| 7943 const indx = mode.contains.findIndex(m => m.label === label); | |
| 7944 if (indx === -1) { throw new Error("can not find mode to replace"); } | |
| 7945 | |
| 7946 mode.contains.splice(indx, 1, replacement); | |
| 7947 }; | |
| 7948 | |
| 7949 | |
| 7950 // this should update anywhere keywords is used since | |
| 7951 // it will be the same actual JS object | |
| 7952 Object.assign(tsLanguage.keywords, KEYWORDS$1); | |
| 7953 | |
| 7954 tsLanguage.exports.PARAMS_CONTAINS.push(DECORATOR); | |
| 7955 | |
| 7956 // highlight the function params | |
| 7957 const ATTRIBUTE_HIGHLIGHT = tsLanguage.contains.find(c => c.scope === "attr"); | |
| 7958 | |
| 7959 // take default attr rule and extend it to support optionals | |
| 7960 const OPTIONAL_KEY_OR_ARGUMENT = Object.assign({}, | |
| 7961 ATTRIBUTE_HIGHLIGHT, | |
| 7962 { match: regex.concat(IDENT_RE$1, regex.lookahead(/\s*\?:/)) } | |
| 7963 ); | |
| 7964 tsLanguage.exports.PARAMS_CONTAINS.push([ | |
| 7965 tsLanguage.exports.CLASS_REFERENCE, // class reference for highlighting the params types | |
| 7966 ATTRIBUTE_HIGHLIGHT, // highlight the params key | |
| 7967 OPTIONAL_KEY_OR_ARGUMENT, // Added for optional property assignment highlighting | |
| 7968 ]); | |
| 7969 | |
| 7970 // Add the optional property assignment highlighting for objects or classes | |
| 7971 tsLanguage.contains = tsLanguage.contains.concat([ | |
| 7972 DECORATOR, | |
| 7973 NAMESPACE, | |
| 7974 INTERFACE, | |
| 7975 OPTIONAL_KEY_OR_ARGUMENT, // Added for optional property assignment highlighting | |
| 7976 ]); | |
| 7977 | |
| 7978 // TS gets a simpler shebang rule than JS | |
| 7979 swapMode(tsLanguage, "shebang", hljs.SHEBANG()); | |
| 7980 // JS use strict rule purposely excludes `asm` which makes no sense | |
| 7981 swapMode(tsLanguage, "use_strict", USE_STRICT); | |
| 7982 | |
| 7983 const functionDeclaration = tsLanguage.contains.find(m => m.label === "func.def"); | |
| 7984 functionDeclaration.relevance = 0; // () => {} is more typical in TypeScript | |
| 7985 | |
| 7986 Object.assign(tsLanguage, { | |
| 7987 name: 'TypeScript', | |
| 7988 aliases: [ | |
| 7989 'ts', | |
| 7990 'tsx', | |
| 7991 'mts', | |
| 7992 'cts' | |
| 7993 ] | |
| 7994 }); | |
| 7995 | |
| 7996 return tsLanguage; | |
| 7997 } | |
| 7998 | |
| 7999 return typescript; | |
| 8000 | |
| 8001 })(); | |
| 8002 | |
| 8003 hljs.registerLanguage('typescript', hljsGrammar); | |
| 8004 })();/*! `x86asm` grammar compiled for Highlight.js 11.11.1 */ | |
| 8005 (function(){ | |
| 8006 var hljsGrammar = (function () { | |
| 8007 'use strict'; | |
| 8008 | |
| 8009 /* | |
| 8010 Language: Intel x86 Assembly | |
| 8011 Author: innocenat <[email protected]> | |
| 8012 Description: x86 assembly language using Intel's mnemonic and NASM syntax | |
| 8013 Website: https://en.wikipedia.org/wiki/X86_assembly_language | |
| 8014 Category: assembler | |
| 8015 */ | |
| 8016 | |
| 8017 function x86asm(hljs) { | |
| 8018 return { | |
| 8019 name: 'Intel x86 Assembly', | |
| 8020 case_insensitive: true, | |
| 8021 keywords: { | |
| 8022 $pattern: '[.%]?' + hljs.IDENT_RE, | |
| 8023 keyword: | |
| 8024 'lock rep repe repz repne repnz xaquire xrelease bnd nobnd ' | |
| 8025 + 'aaa aad aam aas adc add and arpl bb0_reset bb1_reset bound bsf bsr bswap bt btc btr bts call cbw cdq cdqe clc cld cli clts cmc cmp cmpsb cmpsd cmpsq cmpsw cmpxchg cmpxchg486 cmpxchg8b cmpxchg16b cpuid cpu_read cpu_write cqo cwd cwde daa das dec div dmint emms enter equ f2xm1 fabs fadd faddp fbld fbstp fchs fclex fcmovb fcmovbe fcmove fcmovnb fcmovnbe fcmovne fcmovnu fcmovu fcom fcomi fcomip fcomp fcompp fcos fdecstp fdisi fdiv fdivp fdivr fdivrp femms feni ffree ffreep fiadd ficom ficomp fidiv fidivr fild fimul fincstp finit fist fistp fisttp fisub fisubr fld fld1 fldcw fldenv fldl2e fldl2t fldlg2 fldln2 fldpi fldz fmul fmulp fnclex fndisi fneni fninit fnop fnsave fnstcw fnstenv fnstsw fpatan fprem fprem1 fptan frndint frstor fsave fscale fsetpm fsin fsincos fsqrt fst fstcw fstenv fstp fstsw fsub fsubp fsubr fsubrp ftst fucom fucomi fucomip fucomp fucompp fxam fxch fxtract fyl2x fyl2xp1 hlt ibts icebp idiv imul in inc incbin insb insd insw int int01 int1 int03 int3 into invd invpcid invlpg invlpga iret iretd iretq iretw jcxz jecxz jrcxz jmp jmpe lahf lar lds lea leave les lfence lfs lgdt lgs lidt lldt lmsw loadall loadall286 lodsb lodsd lodsq lodsw loop loope loopne loopnz loopz lsl lss ltr mfence monitor mov movd movq movsb movsd movsq movsw movsx movsxd movzx mul mwait neg nop not or out outsb outsd outsw packssdw packsswb packuswb paddb paddd paddsb paddsiw paddsw paddusb paddusw paddw pand pandn pause paveb pavgusb pcmpeqb pcmpeqd pcmpeqw pcmpgtb pcmpgtd pcmpgtw pdistib pf2id pfacc pfadd pfcmpeq pfcmpge pfcmpgt pfmax pfmin pfmul pfrcp pfrcpit1 pfrcpit2 pfrsqit1 pfrsqrt pfsub pfsubr pi2fd pmachriw pmaddwd pmagw pmulhriw pmulhrwa pmulhrwc pmulhw pmullw pmvgezb pmvlzb pmvnzb pmvzb pop popa popad popaw popf popfd popfq popfw por prefetch prefetchw pslld psllq psllw psrad psraw psrld psrlq psrlw psubb psubd psubsb psubsiw psubsw psubusb psubusw psubw punpckhbw punpckhdq punpckhwd punpcklbw punpckldq punpcklwd push pusha pushad pushaw pushf pushfd pushfq pushfw pxor rcl rcr rdshr rdmsr rdpmc rdtsc rdtscp ret retf retn rol ror rdm rsdc rsldt rsm rsts sahf sal salc sar sbb scasb scasd scasq scasw sfence sgdt shl shld shr shrd sidt sldt skinit smi smint smintold smsw stc std sti stosb stosd stosq stosw str sub svdc svldt svts swapgs syscall sysenter sysexit sysret test ud0 ud1 ud2b ud2 ud2a umov verr verw fwait wbinvd wrshr wrmsr xadd xbts xchg xlatb xlat xor cmove cmovz cmovne cmovnz cmova cmovnbe cmovae cmovnb cmovb cmovnae cmovbe cmovna cmovg cmovnle cmovge cmovnl cmovl cmovnge cmovle cmovng cmovc cmovnc cmovo cmovno cmovs cmovns cmovp cmovpe cmovnp cmovpo je jz jne jnz ja jnbe jae jnb jb jnae jbe jna jg jnle jge jnl jl jnge jle jng jc jnc jo jno js jns jpo jnp jpe jp sete setz setne setnz seta setnbe setae setnb setnc setb setnae setcset setbe setna setg setnle setge setnl setl setnge setle setng sets setns seto setno setpe setp setpo setnp addps addss andnps andps cmpeqps cmpeqss cmpleps cmpless cmpltps cmpltss cmpneqps cmpneqss cmpnleps cmpnless cmpnltps cmpnltss cmpordps cmpordss cmpunordps cmpunordss cmpps cmpss comiss cvtpi2ps cvtps2pi cvtsi2ss cvtss2si cvttps2pi cvttss2si divps divss ldmxcsr maxps maxss minps minss movaps movhps movlhps movlps movhlps movmskps movntps movss movups mulps mulss orps rcpps rcpss rsqrtps rsqrtss shufps sqrtps sqrtss stmxcsr subps subss ucomiss unpckhps unpcklps xorps fxrstor fxrstor64 fxsave fxsave64 xgetbv xsetbv xsave xsave64 xsaveopt xsaveopt64 xrstor xrstor64 prefetchnta prefetcht0 prefetcht1 prefetcht2 maskmovq movntq pavgb pavgw pextrw pinsrw pmaxsw pmaxub pminsw pminub pmovmskb pmulhuw psadbw pshufw pf2iw pfnacc pfpnacc pi2fw pswapd maskmovdqu clflush movntdq movnti movntpd movdqa movdqu movdq2q movq2dq paddq pmuludq pshufd pshufhw pshuflw pslldq psrldq psubq punpckhqdq punpcklqdq addpd addsd andnpd andpd cmpeqpd cmpeqsd cmplepd cmplesd cmpltpd cmpltsd cmpneqpd cmpneqsd cmpnlepd cmpnlesd cmpnltpd cmpnltsd cmpordpd cmpordsd cmpunordpd cmpunordsd cmppd comisd cvtdq2pd cvtdq2ps cvtpd2dq cvtpd2pi cvtpd2ps cvtpi2pd cvtps2dq cvtps2pd cvtsd2si cvtsd2ss cvtsi2sd cvtss2sd cvttpd2pi cvttpd2dq cvttps2dq cvttsd2si divpd divsd maxpd maxsd minpd minsd movapd movhpd movlpd movmskpd movupd mulpd mulsd orpd shufpd sqrtpd sqrtsd subpd subsd ucomisd unpckhpd unpcklpd xorpd addsubpd addsubps haddpd haddps hsubpd hsubps lddqu movddup movshdup movsldup clgi stgi vmcall vmclear vmfunc vmlaunch vmload vmmcall vmptrld vmptrst vmread vmresume vmrun vmsave vmwrite vmxoff vmxon invept invvpid pabsb pabsw pabsd palignr phaddw phaddd phaddsw phsubw phsubd phsubsw pmaddubsw pmulhrsw pshufb psignb psignw psignd extrq insertq movntsd movntss lzcnt blendpd blendps blendvpd blendvps dppd dpps extractps insertps movntdqa mpsadbw packusdw pblendvb pblendw pcmpeqq pextrb pextrd pextrq phminposuw pinsrb pinsrd pinsrq pmaxsb pmaxsd pmaxud pmaxuw pminsb pminsd pminud pminuw pmovsxbw pmovsxbd pmovsxbq pmovsxwd pmovsxwq pmovsxdq pmovzxbw pmovzxbd pmovzxbq pmovzxwd pmovzxwq pmovzxdq pmuldq pmulld ptest roundpd roundps roundsd roundss crc32 pcmpestri pcmpestrm pcmpistri pcmpistrm pcmpgtq popcnt getsec pfrcpv pfrsqrtv movbe aesenc aesenclast aesdec aesdeclast aesimc aeskeygenassist vaesenc vaesenclast vaesdec vaesdeclast vaesimc vaeskeygenassist vaddpd vaddps vaddsd vaddss vaddsubpd vaddsubps vandpd vandps vandnpd vandnps vblendpd vblendps vblendvpd vblendvps vbroadcastss vbroadcastsd vbroadcastf128 vcmpeq_ospd vcmpeqpd vcmplt_ospd vcmpltpd vcmple_ospd vcmplepd vcmpunord_qpd vcmpunordpd vcmpneq_uqpd vcmpneqpd vcmpnlt_uspd vcmpnltpd vcmpnle_uspd vcmpnlepd vcmpord_qpd vcmpordpd vcmpeq_uqpd vcmpnge_uspd vcmpngepd vcmpngt_uspd vcmpngtpd vcmpfalse_oqpd vcmpfalsepd vcmpneq_oqpd vcmpge_ospd vcmpgepd vcmpgt_ospd vcmpgtpd vcmptrue_uqpd vcmptruepd vcmplt_oqpd vcmple_oqpd vcmpunord_spd vcmpneq_uspd vcmpnlt_uqpd vcmpnle_uqpd vcmpord_spd vcmpeq_uspd vcmpnge_uqpd vcmpngt_uqpd vcmpfalse_ospd vcmpneq_ospd vcmpge_oqpd vcmpgt_oqpd vcmptrue_uspd vcmppd vcmpeq_osps vcmpeqps vcmplt_osps vcmpltps vcmple_osps vcmpleps vcmpunord_qps vcmpunordps vcmpneq_uqps vcmpneqps vcmpnlt_usps vcmpnltps vcmpnle_usps vcmpnleps vcmpord_qps vcmpordps vcmpeq_uqps vcmpnge_usps vcmpngeps vcmpngt_usps vcmpngtps vcmpfalse_oqps vcmpfalseps vcmpneq_oqps vcmpge_osps vcmpgeps vcmpgt_osps vcmpgtps vcmptrue_uqps vcmptrueps vcmplt_oqps vcmple_oqps vcmpunord_sps vcmpneq_usps vcmpnlt_uqps vcmpnle_uqps vcmpord_sps vcmpeq_usps vcmpnge_uqps vcmpngt_uqps vcmpfalse_osps vcmpneq_osps vcmpge_oqps vcmpgt_oqps vcmptrue_usps vcmpps vcmpeq_ossd vcmpeqsd vcmplt_ossd vcmpltsd vcmple_ossd vcmplesd vcmpunord_qsd vcmpunordsd vcmpneq_uqsd vcmpneqsd vcmpnlt_ussd vcmpnltsd vcmpnle_ussd vcmpnlesd vcmpord_qsd vcmpordsd vcmpeq_uqsd vcmpnge_ussd vcmpngesd vcmpngt_ussd vcmpngtsd vcmpfalse_oqsd vcmpfalsesd vcmpneq_oqsd vcmpge_ossd vcmpgesd vcmpgt_ossd vcmpgtsd vcmptrue_uqsd vcmptruesd vcmplt_oqsd vcmple_oqsd vcmpunord_ssd vcmpneq_ussd vcmpnlt_uqsd vcmpnle_uqsd vcmpord_ssd vcmpeq_ussd vcmpnge_uqsd vcmpngt_uqsd vcmpfalse_ossd vcmpneq_ossd vcmpge_oqsd vcmpgt_oqsd vcmptrue_ussd vcmpsd vcmpeq_osss vcmpeqss vcmplt_osss vcmpltss vcmple_osss vcmpless vcmpunord_qss vcmpunordss vcmpneq_uqss vcmpneqss vcmpnlt_usss vcmpnltss vcmpnle_usss vcmpnless vcmpord_qss vcmpordss vcmpeq_uqss vcmpnge_usss vcmpngess vcmpngt_usss vcmpngtss vcmpfalse_oqss vcmpfalsess vcmpneq_oqss vcmpge_osss vcmpgess vcmpgt_osss vcmpgtss vcmptrue_uqss vcmptruess vcmplt_oqss vcmple_oqss vcmpunord_sss vcmpneq_usss vcmpnlt_uqss vcmpnle_uqss vcmpord_sss vcmpeq_usss vcmpnge_uqss vcmpngt_uqss vcmpfalse_osss vcmpneq_osss vcmpge_oqss vcmpgt_oqss vcmptrue_usss vcmpss vcomisd vcomiss vcvtdq2pd vcvtdq2ps vcvtpd2dq vcvtpd2ps vcvtps2dq vcvtps2pd vcvtsd2si vcvtsd2ss vcvtsi2sd vcvtsi2ss vcvtss2sd vcvtss2si vcvttpd2dq vcvttps2dq vcvttsd2si vcvttss2si vdivpd vdivps vdivsd vdivss vdppd vdpps vextractf128 vextractps vhaddpd vhaddps vhsubpd vhsubps vinsertf128 vinsertps vlddqu vldqqu vldmxcsr vmaskmovdqu vmaskmovps vmaskmovpd vmaxpd vmaxps vmaxsd vmaxss vminpd vminps vminsd vminss vmovapd vmovaps vmovd vmovq vmovddup vmovdqa vmovqqa vmovdqu vmovqqu vmovhlps vmovhpd vmovhps vmovlhps vmovlpd vmovlps vmovmskpd vmovmskps vmovntdq vmovntqq vmovntdqa vmovntpd vmovntps vmovsd vmovshdup vmovsldup vmovss vmovupd vmovups vmpsadbw vmulpd vmulps vmulsd vmulss vorpd vorps vpabsb vpabsw vpabsd vpacksswb vpackssdw vpackuswb vpackusdw vpaddb vpaddw vpaddd vpaddq vpaddsb vpaddsw vpaddusb vpaddusw vpalignr vpand vpandn vpavgb vpavgw vpblendvb vpblendw vpcmpestri vpcmpestrm vpcmpistri vpcmpistrm vpcmpeqb vpcmpeqw vpcmpeqd vpcmpeqq vpcmpgtb vpcmpgtw vpcmpgtd vpcmpgtq vpermilpd vpermilps vperm2f128 vpextrb vpextrw vpextrd vpextrq vphaddw vphaddd vphaddsw vphminposuw vphsubw vphsubd vphsubsw vpinsrb vpinsrw vpinsrd vpinsrq vpmaddwd vpmaddubsw vpmaxsb vpmaxsw vpmaxsd vpmaxub vpmaxuw vpmaxud vpminsb vpminsw vpminsd vpminub vpminuw vpminud vpmovmskb vpmovsxbw vpmovsxbd vpmovsxbq vpmovsxwd vpmovsxwq vpmovsxdq vpmovzxbw vpmovzxbd vpmovzxbq vpmovzxwd vpmovzxwq vpmovzxdq vpmulhuw vpmulhrsw vpmulhw vpmullw vpmulld vpmuludq vpmuldq vpor vpsadbw vpshufb vpshufd vpshufhw vpshuflw vpsignb vpsignw vpsignd vpslldq vpsrldq vpsllw vpslld vpsllq vpsraw vpsrad vpsrlw vpsrld vpsrlq vptest vpsubb vpsubw vpsubd vpsubq vpsubsb vpsubsw vpsubusb vpsubusw vpunpckhbw vpunpckhwd vpunpckhdq vpunpckhqdq vpunpcklbw vpunpcklwd vpunpckldq vpunpcklqdq vpxor vrcpps vrcpss vrsqrtps vrsqrtss vroundpd vroundps vroundsd vroundss vshufpd vshufps vsqrtpd vsqrtps vsqrtsd vsqrtss vstmxcsr vsubpd vsubps vsubsd vsubss vtestps vtestpd vucomisd vucomiss vunpckhpd vunpckhps vunpcklpd vunpcklps vxorpd vxorps vzeroall vzeroupper pclmullqlqdq pclmulhqlqdq pclmullqhqdq pclmulhqhqdq pclmulqdq vpclmullqlqdq vpclmulhqlqdq vpclmullqhqdq vpclmulhqhqdq vpclmulqdq vfmadd132ps vfmadd132pd vfmadd312ps vfmadd312pd vfmadd213ps vfmadd213pd vfmadd123ps vfmadd123pd vfmadd231ps vfmadd231pd vfmadd321ps vfmadd321pd vfmaddsub132ps vfmaddsub132pd vfmaddsub312ps vfmaddsub312pd vfmaddsub213ps vfmaddsub213pd vfmaddsub123ps vfmaddsub123pd vfmaddsub231ps vfmaddsub231pd vfmaddsub321ps vfmaddsub321pd vfmsub132ps vfmsub132pd vfmsub312ps vfmsub312pd vfmsub213ps vfmsub213pd vfmsub123ps vfmsub123pd vfmsub231ps vfmsub231pd vfmsub321ps vfmsub321pd vfmsubadd132ps vfmsubadd132pd vfmsubadd312ps vfmsubadd312pd vfmsubadd213ps vfmsubadd213pd vfmsubadd123ps vfmsubadd123pd vfmsubadd231ps vfmsubadd231pd vfmsubadd321ps vfmsubadd321pd vfnmadd132ps vfnmadd132pd vfnmadd312ps vfnmadd312pd vfnmadd213ps vfnmadd213pd vfnmadd123ps vfnmadd123pd vfnmadd231ps vfnmadd231pd vfnmadd321ps vfnmadd321pd vfnmsub132ps vfnmsub132pd vfnmsub312ps vfnmsub312pd vfnmsub213ps vfnmsub213pd vfnmsub123ps vfnmsub123pd vfnmsub231ps vfnmsub231pd vfnmsub321ps vfnmsub321pd vfmadd132ss vfmadd132sd vfmadd312ss vfmadd312sd vfmadd213ss vfmadd213sd vfmadd123ss vfmadd123sd vfmadd231ss vfmadd231sd vfmadd321ss vfmadd321sd vfmsub132ss vfmsub132sd vfmsub312ss vfmsub312sd vfmsub213ss vfmsub213sd vfmsub123ss vfmsub123sd vfmsub231ss vfmsub231sd vfmsub321ss vfmsub321sd vfnmadd132ss vfnmadd132sd vfnmadd312ss vfnmadd312sd vfnmadd213ss vfnmadd213sd vfnmadd123ss vfnmadd123sd vfnmadd231ss vfnmadd231sd vfnmadd321ss vfnmadd321sd vfnmsub132ss vfnmsub132sd vfnmsub312ss vfnmsub312sd vfnmsub213ss vfnmsub213sd vfnmsub123ss vfnmsub123sd vfnmsub231ss vfnmsub231sd vfnmsub321ss vfnmsub321sd rdfsbase rdgsbase rdrand wrfsbase wrgsbase vcvtph2ps vcvtps2ph adcx adox rdseed clac stac xstore xcryptecb xcryptcbc xcryptctr xcryptcfb xcryptofb montmul xsha1 xsha256 llwpcb slwpcb lwpval lwpins vfmaddpd vfmaddps vfmaddsd vfmaddss vfmaddsubpd vfmaddsubps vfmsubaddpd vfmsubaddps vfmsubpd vfmsubps vfmsubsd vfmsubss vfnmaddpd vfnmaddps vfnmaddsd vfnmaddss vfnmsubpd vfnmsubps vfnmsubsd vfnmsubss vfrczpd vfrczps vfrczsd vfrczss vpcmov vpcomb vpcomd vpcomq vpcomub vpcomud vpcomuq vpcomuw vpcomw vphaddbd vphaddbq vphaddbw vphadddq vphaddubd vphaddubq vphaddubw vphaddudq vphadduwd vphadduwq vphaddwd vphaddwq vphsubbw vphsubdq vphsubwd vpmacsdd vpmacsdqh vpmacsdql vpmacssdd vpmacssdqh vpmacssdql vpmacsswd vpmacssww vpmacswd vpmacsww vpmadcsswd vpmadcswd vpperm vprotb vprotd vprotq vprotw vpshab vpshad vpshaq vpshaw vpshlb vpshld vpshlq vpshlw vbroadcasti128 vpblendd vpbroadcastb vpbroadcastw vpbroadcastd vpbroadcastq vpermd vpermpd vpermps vpermq vperm2i128 vextracti128 vinserti128 vpmaskmovd vpmaskmovq vpsllvd vpsllvq vpsravd vpsrlvd vpsrlvq vgatherdpd vgatherqpd vgatherdps vgatherqps vpgatherdd vpgatherqd vpgatherdq vpgatherqq xabort xbegin xend xtest andn bextr blci blcic blsi blsic blcfill blsfill blcmsk blsmsk blsr blcs bzhi mulx pdep pext rorx sarx shlx shrx tzcnt tzmsk t1mskc valignd valignq vblendmpd vblendmps vbroadcastf32x4 vbroadcastf64x4 vbroadcasti32x4 vbroadcasti64x4 vcompresspd vcompressps vcvtpd2udq vcvtps2udq vcvtsd2usi vcvtss2usi vcvttpd2udq vcvttps2udq vcvttsd2usi vcvttss2usi vcvtudq2pd vcvtudq2ps vcvtusi2sd vcvtusi2ss vexpandpd vexpandps vextractf32x4 vextractf64x4 vextracti32x4 vextracti64x4 vfixupimmpd vfixupimmps vfixupimmsd vfixupimmss vgetexppd vgetexpps vgetexpsd vgetexpss vgetmantpd vgetmantps vgetmantsd vgetmantss vinsertf32x4 vinsertf64x4 vinserti32x4 vinserti64x4 vmovdqa32 vmovdqa64 vmovdqu32 vmovdqu64 vpabsq vpandd vpandnd vpandnq vpandq vpblendmd vpblendmq vpcmpltd vpcmpled vpcmpneqd vpcmpnltd vpcmpnled vpcmpd vpcmpltq vpcmpleq vpcmpneqq vpcmpnltq vpcmpnleq vpcmpq vpcmpequd vpcmpltud vpcmpleud vpcmpnequd vpcmpnltud vpcmpnleud vpcmpud vpcmpequq vpcmpltuq vpcmpleuq vpcmpnequq vpcmpnltuq vpcmpnleuq vpcmpuq vpcompressd vpcompressq vpermi2d vpermi2pd vpermi2ps vpermi2q vpermt2d vpermt2pd vpermt2ps vpermt2q vpexpandd vpexpandq vpmaxsq vpmaxuq vpminsq vpminuq vpmovdb vpmovdw vpmovqb vpmovqd vpmovqw vpmovsdb vpmovsdw vpmovsqb vpmovsqd vpmovsqw vpmovusdb vpmovusdw vpmovusqb vpmovusqd vpmovusqw vpord vporq vprold vprolq vprolvd vprolvq vprord vprorq vprorvd vprorvq vpscatterdd vpscatterdq vpscatterqd vpscatterqq vpsraq vpsravq vpternlogd vpternlogq vptestmd vptestmq vptestnmd vptestnmq vpxord vpxorq vrcp14pd vrcp14ps vrcp14sd vrcp14ss vrndscalepd vrndscaleps vrndscalesd vrndscaless vrsqrt14pd vrsqrt14ps vrsqrt14sd vrsqrt14ss vscalefpd vscalefps vscalefsd vscalefss vscatterdpd vscatterdps vscatterqpd vscatterqps vshuff32x4 vshuff64x2 vshufi32x4 vshufi64x2 kandnw kandw kmovw knotw kortestw korw kshiftlw kshiftrw kunpckbw kxnorw kxorw vpbroadcastmb2q vpbroadcastmw2d vpconflictd vpconflictq vplzcntd vplzcntq vexp2pd vexp2ps vrcp28pd vrcp28ps vrcp28sd vrcp28ss vrsqrt28pd vrsqrt28ps vrsqrt28sd vrsqrt28ss vgatherpf0dpd vgatherpf0dps vgatherpf0qpd vgatherpf0qps vgatherpf1dpd vgatherpf1dps vgatherpf1qpd vgatherpf1qps vscatterpf0dpd vscatterpf0dps vscatterpf0qpd vscatterpf0qps vscatterpf1dpd vscatterpf1dps vscatterpf1qpd vscatterpf1qps prefetchwt1 bndmk bndcl bndcu bndcn bndmov bndldx bndstx sha1rnds4 sha1nexte sha1msg1 sha1msg2 sha256rnds2 sha256msg1 sha256msg2 hint_nop0 hint_nop1 hint_nop2 hint_nop3 hint_nop4 hint_nop5 hint_nop6 hint_nop7 hint_nop8 hint_nop9 hint_nop10 hint_nop11 hint_nop12 hint_nop13 hint_nop14 hint_nop15 hint_nop16 hint_nop17 hint_nop18 hint_nop19 hint_nop20 hint_nop21 hint_nop22 hint_nop23 hint_nop24 hint_nop25 hint_nop26 hint_nop27 hint_nop28 hint_nop29 hint_nop30 hint_nop31 hint_nop32 hint_nop33 hint_nop34 hint_nop35 hint_nop36 hint_nop37 hint_nop38 hint_nop39 hint_nop40 hint_nop41 hint_nop42 hint_nop43 hint_nop44 hint_nop45 hint_nop46 hint_nop47 hint_nop48 hint_nop49 hint_nop50 hint_nop51 hint_nop52 hint_nop53 hint_nop54 hint_nop55 hint_nop56 hint_nop57 hint_nop58 hint_nop59 hint_nop60 hint_nop61 hint_nop62 hint_nop63', | |
| 8026 built_in: | |
| 8027 // Instruction pointer | |
| 8028 'ip eip rip ' | |
| 8029 // 8-bit registers | |
| 8030 + 'al ah bl bh cl ch dl dh sil dil bpl spl r8b r9b r10b r11b r12b r13b r14b r15b ' | |
| 8031 // 16-bit registers | |
| 8032 + 'ax bx cx dx si di bp sp r8w r9w r10w r11w r12w r13w r14w r15w ' | |
| 8033 // 32-bit registers | |
| 8034 + 'eax ebx ecx edx esi edi ebp esp eip r8d r9d r10d r11d r12d r13d r14d r15d ' | |
| 8035 // 64-bit registers | |
| 8036 + 'rax rbx rcx rdx rsi rdi rbp rsp r8 r9 r10 r11 r12 r13 r14 r15 ' | |
| 8037 // Segment registers | |
| 8038 + 'cs ds es fs gs ss ' | |
| 8039 // Floating point stack registers | |
| 8040 + 'st st0 st1 st2 st3 st4 st5 st6 st7 ' | |
| 8041 // MMX Registers | |
| 8042 + 'mm0 mm1 mm2 mm3 mm4 mm5 mm6 mm7 ' | |
| 8043 // SSE registers | |
| 8044 + 'xmm0 xmm1 xmm2 xmm3 xmm4 xmm5 xmm6 xmm7 xmm8 xmm9 xmm10 xmm11 xmm12 xmm13 xmm14 xmm15 ' | |
| 8045 + 'xmm16 xmm17 xmm18 xmm19 xmm20 xmm21 xmm22 xmm23 xmm24 xmm25 xmm26 xmm27 xmm28 xmm29 xmm30 xmm31 ' | |
| 8046 // AVX registers | |
| 8047 + 'ymm0 ymm1 ymm2 ymm3 ymm4 ymm5 ymm6 ymm7 ymm8 ymm9 ymm10 ymm11 ymm12 ymm13 ymm14 ymm15 ' | |
| 8048 + 'ymm16 ymm17 ymm18 ymm19 ymm20 ymm21 ymm22 ymm23 ymm24 ymm25 ymm26 ymm27 ymm28 ymm29 ymm30 ymm31 ' | |
| 8049 // AVX-512F registers | |
| 8050 + 'zmm0 zmm1 zmm2 zmm3 zmm4 zmm5 zmm6 zmm7 zmm8 zmm9 zmm10 zmm11 zmm12 zmm13 zmm14 zmm15 ' | |
| 8051 + 'zmm16 zmm17 zmm18 zmm19 zmm20 zmm21 zmm22 zmm23 zmm24 zmm25 zmm26 zmm27 zmm28 zmm29 zmm30 zmm31 ' | |
| 8052 // AVX-512F mask registers | |
| 8053 + 'k0 k1 k2 k3 k4 k5 k6 k7 ' | |
| 8054 // Bound (MPX) register | |
| 8055 + 'bnd0 bnd1 bnd2 bnd3 ' | |
| 8056 // Special register | |
| 8057 + 'cr0 cr1 cr2 cr3 cr4 cr8 dr0 dr1 dr2 dr3 dr8 tr3 tr4 tr5 tr6 tr7 ' | |
| 8058 // NASM altreg package | |
| 8059 + 'r0 r1 r2 r3 r4 r5 r6 r7 r0b r1b r2b r3b r4b r5b r6b r7b ' | |
| 8060 + 'r0w r1w r2w r3w r4w r5w r6w r7w r0d r1d r2d r3d r4d r5d r6d r7d ' | |
| 8061 + 'r0h r1h r2h r3h ' | |
| 8062 + 'r0l r1l r2l r3l r4l r5l r6l r7l r8l r9l r10l r11l r12l r13l r14l r15l ' | |
| 8063 | |
| 8064 + 'db dw dd dq dt ddq do dy dz ' | |
| 8065 + 'resb resw resd resq rest resdq reso resy resz ' | |
| 8066 + 'incbin equ times ' | |
| 8067 + 'byte word dword qword nosplit rel abs seg wrt strict near far a32 ptr', | |
| 8068 | |
| 8069 meta: | |
| 8070 '%define %xdefine %+ %undef %defstr %deftok %assign %strcat %strlen %substr %rotate %elif %else %endif ' | |
| 8071 + '%if %ifmacro %ifctx %ifidn %ifidni %ifid %ifnum %ifstr %iftoken %ifempty %ifenv %error %warning %fatal %rep ' | |
| 8072 + '%endrep %include %push %pop %repl %pathsearch %depend %use %arg %stacksize %local %line %comment %endcomment ' | |
| 8073 + '.nolist ' | |
| 8074 + '__FILE__ __LINE__ __SECT__ __BITS__ __OUTPUT_FORMAT__ __DATE__ __TIME__ __DATE_NUM__ __TIME_NUM__ ' | |
| 8075 + '__UTC_DATE__ __UTC_TIME__ __UTC_DATE_NUM__ __UTC_TIME_NUM__ __PASS__ struc endstruc istruc at iend ' | |
| 8076 + 'align alignb sectalign daz nodaz up down zero default option assume public ' | |
| 8077 | |
| 8078 + 'bits use16 use32 use64 default section segment absolute extern global common cpu float ' | |
| 8079 + '__utf16__ __utf16le__ __utf16be__ __utf32__ __utf32le__ __utf32be__ ' | |
| 8080 + '__float8__ __float16__ __float32__ __float64__ __float80m__ __float80e__ __float128l__ __float128h__ ' | |
| 8081 + '__Infinity__ __QNaN__ __SNaN__ Inf NaN QNaN SNaN float8 float16 float32 float64 float80m float80e ' | |
| 8082 + 'float128l float128h __FLOAT_DAZ__ __FLOAT_ROUND__ __FLOAT__' | |
| 8083 }, | |
| 8084 contains: [ | |
| 8085 hljs.COMMENT( | |
| 8086 ';', | |
| 8087 '$', | |
| 8088 { relevance: 0 } | |
| 8089 ), | |
| 8090 { | |
| 8091 className: 'number', | |
| 8092 variants: [ | |
| 8093 // Float number and x87 BCD | |
| 8094 { | |
| 8095 begin: '\\b(?:([0-9][0-9_]*)?\\.[0-9_]*(?:[eE][+-]?[0-9_]+)?|' | |
| 8096 + '(0[Xx])?[0-9][0-9_]*(\\.[0-9_]*)?(?:[pP](?:[+-]?[0-9_]+)?)?)\\b', | |
| 8097 relevance: 0 | |
| 8098 }, | |
| 8099 | |
| 8100 // Hex number in $ | |
| 8101 { | |
| 8102 begin: '\\$[0-9][0-9A-Fa-f]*', | |
| 8103 relevance: 0 | |
| 8104 }, | |
| 8105 | |
| 8106 // Number in H,D,T,Q,O,B,Y suffix | |
| 8107 { begin: '\\b(?:[0-9A-Fa-f][0-9A-Fa-f_]*[Hh]|[0-9][0-9_]*[DdTt]?|[0-7][0-7_]*[QqOo]|[0-1][0-1_]*[BbYy])\\b' }, | |
| 8108 | |
| 8109 // Number in X,D,T,Q,O,B,Y prefix | |
| 8110 { begin: '\\b(?:0[Xx][0-9A-Fa-f_]+|0[DdTt][0-9_]+|0[QqOo][0-7_]+|0[BbYy][0-1_]+)\\b' } | |
| 8111 ] | |
| 8112 }, | |
| 8113 // Double quote string | |
| 8114 hljs.QUOTE_STRING_MODE, | |
| 8115 { | |
| 8116 className: 'string', | |
| 8117 variants: [ | |
| 8118 // Single-quoted string | |
| 8119 { | |
| 8120 begin: '\'', | |
| 8121 end: '[^\\\\]\'' | |
| 8122 }, | |
| 8123 // Backquoted string | |
| 8124 { | |
| 8125 begin: '`', | |
| 8126 end: '[^\\\\]`' | |
| 8127 } | |
| 8128 ], | |
| 8129 relevance: 0 | |
| 8130 }, | |
| 8131 { | |
| 8132 className: 'symbol', | |
| 8133 variants: [ | |
| 8134 // Global label and local label | |
| 8135 { begin: '^\\s*[A-Za-z._?][A-Za-z0-9_$#@~.?]*(:|\\s+label)' }, | |
| 8136 // Macro-local label | |
| 8137 { begin: '^\\s*%%[A-Za-z0-9_$#@~.?]*:' } | |
| 8138 ], | |
| 8139 relevance: 0 | |
| 8140 }, | |
| 8141 // Macro parameter | |
| 8142 { | |
| 8143 className: 'subst', | |
| 8144 begin: '%[0-9]+', | |
| 8145 relevance: 0 | |
| 8146 }, | |
| 8147 // Macro parameter | |
| 8148 { | |
| 8149 className: 'subst', | |
| 8150 begin: '%!\S+', | |
| 8151 relevance: 0 | |
| 8152 }, | |
| 8153 { | |
| 8154 className: 'meta', | |
| 8155 begin: /^\s*\.[\w_-]+/ | |
| 8156 } | |
| 8157 ] | |
| 8158 }; | |
| 8159 } | |
| 8160 | |
| 8161 return x86asm; | |
| 8162 | |
| 8163 })(); | |
| 8164 | |
| 8165 hljs.registerLanguage('x86asm', hljsGrammar); | |
| 8166 })(); |