vendor: 36,730 bytes, lines 1-1212
1 2/* ********************************************** 3 Begin prism-core.js 4********************************************** */ 5 6/// <reference lib="WebWorker"/> 7 8var _self = (typeof window !== 'undefined') 9 ? window // if in browser 10 : ( 11 (typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope) 12 ? self // if in worker 13 : {} // if in node js 14 ); 15 16/** 17 * Prism: Lightweight, robust, elegant syntax highlighting 18 * 19 * @license MIT <https://opensource.org/licenses/MIT> 20 * @author Lea Verou <https://lea.verou.me> 21 * @namespace 22 * @public 23 */ 24var Prism = (function (_self) { 25 26 // Private helper vars 27 var lang = /(?:^|\s)lang(?:uage)?-([\w-]+)(?=\s|$)/i; 28 var uniqueId = 0; 29 30 // The grammar object for plaintext 31 var plainTextGrammar = {}; 32 33 34 var _ = { 35 /** 36 * By default, Prism will attempt to highlight all code elements (by calling {@link Prism.highlightAll}) on the 37 * current page after the page finished loading. This might be a problem if e.g. you wanted to asynchronously load 38 * additional languages or plugins yourself. 39 * 40 * By setting this value to `true`, Prism will not automatically highlight all code elements on the page. 41 * 42 * You obviously have to change this value before the automatic highlighting started. To do this, you can add an 43 * empty Prism object into the global scope before loading the Prism script like this: 44 * 45 * ```js 46 * window.Prism = window.Prism || {}; 47 * Prism.manual = true; 48 * // add a new <script> to load Prism's script 49 * ``` 50 * 51 * @default false 52 * @type {boolean} 53 * @memberof Prism 54 * @public 55 */ 56 manual: _self.Prism && _self.Prism.manual, 57 /** 58 * By default, if Prism is in a web worker, it assumes that it is in a worker it created itself, so it uses 59 * `addEventListener` to communicate with its parent instance. However, if you're using Prism manually in your 60 * own worker, you don't want it to do this. 61 * 62 * By setting this value to `true`, Prism will not add its own listeners to the worker. 63 * 64 * You obviously have to change this value before Prism executes. To do this, you can add an 65 * empty Prism object into the global scope before loading the Prism script like this: 66 * 67 * ```js 68 * window.Prism = window.Prism || {}; 69 * Prism.disableWorkerMessageHandler = true; 70 * // Load Prism's script 71 * ``` 72 * 73 * @default false 74 * @type {boolean} 75 * @memberof Prism 76 * @public 77 */ 78 disableWorkerMessageHandler: _self.Prism && _self.Prism.disableWorkerMessageHandler, 79 80 /** 81 * A namespace for utility methods. 82 * 83 * All function in this namespace that are not explicitly marked as _public_ are for __internal use only__ and may 84 * change or disappear at any time. 85 * 86 * @namespace 87 * @memberof Prism 88 */ 89 util: { 90 encode: function encode(tokens) { 91 if (tokens instanceof Token) { 92 return new Token(tokens.type, encode(tokens.content), tokens.alias); 93 } else if (Array.isArray(tokens)) { 94 return tokens.map(encode); 95 } else { 96 return tokens.replace(/&/g, '&').replace(/</g, '<').replace(/\u00a0/g, ' '); 97 } 98 }, 99 100 /** 101 * Returns the name of the type of the given value. 102 * 103 * @param {any} o 104 * @returns {string} 105 * @example 106 * type(null) === 'Null' 107 * type(undefined) === 'Undefined' 108 * type(123) === 'Number' 109 * type('foo') === 'String' 110 * type(true) === 'Boolean' 111 * type([1, 2]) === 'Array' 112 * type({}) === 'Object' 113 * type(String) === 'Function' 114 * type(/abc+/) === 'RegExp' 115 */ 116 type: function (o) { 117 return Object.prototype.toString.call(o).slice(8, -1); 118 }, 119 120 /** 121 * Returns a unique number for the given object. Later calls will still return the same number. 122 * 123 * @param {Object} obj 124 * @returns {number} 125 */ 126 objId: function (obj) { 127 if (!obj['__id']) { 128 Object.defineProperty(obj, '__id', { value: ++uniqueId }); 129 } 130 return obj['__id']; 131 }, 132 133 /** 134 * Creates a deep clone of the given object. 135 * 136 * The main intended use of this function is to clone language definitions. 137 * 138 * @param {T} o 139 * @param {Record<number, any>} [visited] 140 * @returns {T} 141 * @template T 142 */ 143 clone: function deepClone(o, visited) { 144 visited = visited || {}; 145 146 var clone; var id; 147 switch (_.util.type(o)) { 148 case 'Object': 149 id = _.util.objId(o); 150 if (visited[id]) { 151 return visited[id]; 152 } 153 clone = /** @type {Record<string, any>} */ ({}); 154 visited[id] = clone; 155 156 for (var key in o) { 157 if (o.hasOwnProperty(key)) { 158 clone[key] = deepClone(o[key], visited); 159 } 160 } 161 162 return /** @type {any} */ (clone); 163 164 case 'Array': 165 id = _.util.objId(o); 166 if (visited[id]) { 167 return visited[id]; 168 } 169 clone = []; 170 visited[id] = clone; 171 172 (/** @type {Array} */(/** @type {any} */(o))).forEach(function (v, i) { 173 clone[i] = deepClone(v, visited); 174 }); 175 176 return /** @type {any} */ (clone); 177 178 default: 179 return o; 180 } 181 }, 182 183 /** 184 * Returns the Prism language of the given element set by a `language-xxxx` or `lang-xxxx` class. 185 * 186 * If no language is set for the element or the element is `null` or `undefined`, `none` will be returned. 187 * 188 * @param {Element} element 189 * @returns {string} 190 */ 191 getLanguage: function (element) { 192 while (element) { 193 var m = lang.exec(element.className); 194 if (m) { 195 return m[1].toLowerCase(); 196 } 197 element = element.parentElement; 198 } 199 return 'none'; 200 }, 201 202 /** 203 * Sets the Prism `language-xxxx` class of the given element. 204 * 205 * @param {Element} element 206 * @param {string} language 207 * @returns {void} 208 */ 209 setLanguage: function (element, language) { 210 // remove all `language-xxxx` classes 211 // (this might leave behind a leading space) 212 element.className = element.className.replace(RegExp(lang, 'gi'), ''); 213 214 // add the new `language-xxxx` class 215 // (using `classList` will automatically clean up spaces for us) 216 element.classList.add('language-' + language); 217 }, 218 219 /** 220 * Returns the script element that is currently executing. 221 * 222 * This does __not__ work for line script element. 223 * 224 * @returns {HTMLScriptElement | null} 225 */ 226 currentScript: function () { 227 if (typeof document === 'undefined') { 228 return null; 229 } 230 if ('currentScript' in document && 1 < 2 /* hack to trip TS' flow analysis */) { 231 return /** @type {any} */ (document.currentScript); 232 } 233 234 // IE11 workaround 235 // we'll get the src of the current script by parsing IE11's error stack trace 236 // this will not work for inline scripts 237 238 try { 239 throw new Error(); 240 } catch (err) { 241 // Get file src url from stack. Specifically works with the format of stack traces in IE. 242 // A stack will look like this: 243 // 244 // Error 245 // at _.util.currentScript (http://localhost/components/prism-core.js:119:5) 246 // at Global code (http://localhost/components/prism-core.js:606:1) 247 248 var src = (/at [^(\r\n]*\((.*):[^:]+:[^:]+\)$/i.exec(err.stack) || [])[1]; 249 if (src) { 250 var scripts = document.getElementsByTagName('script'); 251 for (var i in scripts) { 252 if (scripts[i].src == src) { 253 return scripts[i]; 254 } 255 } 256 } 257 return null; 258 } 259 }, 260 261 /** 262 * Returns whether a given class is active for `element`. 263 * 264 * The class can be activated if `element` or one of its ancestors has the given class and it can be deactivated 265 * if `element` or one of its ancestors has the negated version of the given class. The _negated version_ of the 266 * given class is just the given class with a `no-` prefix. 267 * 268 * Whether the class is active is determined by the closest ancestor of `element` (where `element` itself is 269 * closest ancestor) that has the given class or the negated version of it. If neither `element` nor any of its 270 * ancestors have the given class or the negated version of it, then the default activation will be returned. 271 * 272 * In the paradoxical situation where the closest ancestor contains __both__ the given class and the negated 273 * version of it, the class is considered active. 274 * 275 * @param {Element} element 276 * @param {string} className 277 * @param {boolean} [defaultActivation=false] 278 * @returns {boolean} 279 */ 280 isActive: function (element, className, defaultActivation) { 281 var no = 'no-' + className; 282 283 while (element) { 284 var classList = element.classList; 285 if (classList.contains(className)) { 286 return true; 287 } 288 if (classList.contains(no)) { 289 return false; 290 } 291 element = element.parentElement; 292 } 293 return !!defaultActivation; 294 } 295 }, 296 297 /** 298 * This namespace contains all currently loaded languages and the some helper functions to create and modify languages. 299 * 300 * @namespace 301 * @memberof Prism 302 * @public 303 */ 304 languages: { 305 /** 306 * The grammar for plain, unformatted text. 307 */ 308 plain: plainTextGrammar, 309 plaintext: plainTextGrammar, 310 text: plainTextGrammar, 311 txt: plainTextGrammar, 312 313 /** 314 * Creates a deep copy of the language with the given id and appends the given tokens. 315 * 316 * If a token in `redef` also appears in the copied language, then the existing token in the copied language 317 * will be overwritten at its original position. 318 * 319 * ## Best practices 320 * 321 * Since the position of overwriting tokens (token in `redef` that overwrite tokens in the copied language) 322 * doesn't matter, they can technically be in any order. However, this can be confusing to others that trying to 323 * understand the language definition because, normally, the order of tokens matters in Prism grammars. 324 * 325 * Therefore, it is encouraged to order overwriting tokens according to the positions of the overwritten tokens. 326 * Furthermore, all non-overwriting tokens should be placed after the overwriting ones. 327 * 328 * @param {string} id The id of the language to extend. This has to be a key in `Prism.languages`. 329 * @param {Grammar} redef The new tokens to append. 330 * @returns {Grammar} The new language created. 331 * @public 332 * @example 333 * Prism.languages['css-with-colors'] = Prism.languages.extend('css', { 334 * // Prism.languages.css already has a 'comment' token, so this token will overwrite CSS' 'comment' token 335 * // at its original position 336 * 'comment': { ... }, 337 * // CSS doesn't have a 'color' token, so this token will be appended 338 * 'color': /\b(?:red|green|blue)\b/ 339 * }); 340 */ 341 extend: function (id, redef) { 342 var lang = _.util.clone(_.languages[id]); 343 344 for (var key in redef) { 345 lang[key] = redef[key]; 346 } 347 348 return lang; 349 }, 350 351 /** 352 * Inserts tokens _before_ another token in a language definition or any other grammar. 353 * 354 * ## Usage 355 * 356 * This helper method makes it easy to modify existing languages. For example, the CSS language definition 357 * not only defines CSS highlighting for CSS documents, but also needs to define highlighting for CSS embedded 358 * in HTML through `<style>` elements. To do this, it needs to modify `Prism.languages.markup` and add the 359 * appropriate tokens. However, `Prism.languages.markup` is a regular JavaScript object literal, so if you do 360 * this: 361 * 362 * ```js 363 * Prism.languages.markup.style = { 364 * // token 365 * }; 366 * ``` 367 * 368 * then the `style` token will be added (and processed) at the end. `insertBefore` allows you to insert tokens 369 * before existing tokens. For the CSS example above, you would use it like this: 370 * 371 * ```js 372 * Prism.languages.insertBefore('markup', 'cdata', { 373 * 'style': { 374 * // token 375 * } 376 * }); 377 * ``` 378 * 379 * ## Special cases 380 * 381 * If the grammars of `inside` and `insert` have tokens with the same name, the tokens in `inside`'s grammar 382 * will be ignored. 383 * 384 * This behavior can be used to insert tokens after `before`: 385 * 386 * ```js 387 * Prism.languages.insertBefore('markup', 'comment', { 388 * 'comment': Prism.languages.markup.comment, 389 * // tokens after 'comment' 390 * }); 391 * ``` 392 * 393 * ## Limitations 394 * 395 * The main problem `insertBefore` has to solve is iteration order. Since ES2015, the iteration order for object 396 * properties is guaranteed to be the insertion order (except for integer keys) but some browsers behave 397 * differently when keys are deleted and re-inserted. So `insertBefore` can't be implemented by temporarily 398 * deleting properties which is necessary to insert at arbitrary positions. 399 * 400 * To solve this problem, `insertBefore` doesn't actually insert the given tokens into the target object. 401 * Instead, it will create a new object and replace all references to the target object with the new one. This 402 * can be done without temporarily deleting properties, so the iteration order is well-defined. 403 * 404 * However, only references that can be reached from `Prism.languages` or `insert` will be replaced. I.e. if 405 * you hold the target object in a variable, then the value of the variable will not change. 406 * 407 * ```js 408 * var oldMarkup = Prism.languages.markup; 409 * var newMarkup = Prism.languages.insertBefore('markup', 'comment', { ... }); 410 * 411 * assert(oldMarkup !== Prism.languages.markup); 412 * assert(newMarkup === Prism.languages.markup); 413 * ``` 414 * 415 * @param {string} inside The property of `root` (e.g. a language id in `Prism.languages`) that contains the 416 * object to be modified. 417 * @param {string} before The key to insert before. 418 * @param {Grammar} insert An object containing the key-value pairs to be inserted. 419 * @param {Object<string, any>} [root] The object containing `inside`, i.e. the object that contains the 420 * object to be modified. 421 * 422 * Defaults to `Prism.languages`. 423 * @returns {Grammar} The new grammar object. 424 * @public 425 */ 426 insertBefore: function (inside, before, insert, root) { 427 root = root || /** @type {any} */ (_.languages); 428 var grammar = root[inside]; 429 /** @type {Grammar} */ 430 var ret = {}; 431 432 for (var token in grammar) { 433 if (grammar.hasOwnProperty(token)) { 434 435 if (token == before) { 436 for (var newToken in insert) { 437 if (insert.hasOwnProperty(newToken)) { 438 ret[newToken] = insert[newToken]; 439 } 440 } 441 } 442 443 // Do not insert token which also occur in insert. See #1525 444 if (!insert.hasOwnProperty(token)) { 445 ret[token] = grammar[token]; 446 } 447 } 448 } 449 450 var old = root[inside]; 451 root[inside] = ret; 452 453 // Update references in other language definitions 454 _.languages.DFS(_.languages, function (key, value) { 455 if (value === old && key != inside) { 456 this[key] = ret; 457 } 458 }); 459 460 return ret; 461 }, 462 463 // Traverse a language definition with Depth First Search 464 DFS: function DFS(o, callback, type, visited) { 465 visited = visited || {}; 466 467 var objId = _.util.objId; 468 469 for (var i in o) { 470 if (o.hasOwnProperty(i)) { 471 callback.call(o, i, o[i], type || i); 472 473 var property = o[i]; 474 var propertyType = _.util.type(property); 475 476 if (propertyType === 'Object' && !visited[objId(property)]) { 477 visited[objId(property)] = true; 478 DFS(property, callback, null, visited); 479 } else if (propertyType === 'Array' && !visited[objId(property)]) { 480 visited[objId(property)] = true; 481 DFS(property, callback, i, visited); 482 } 483 } 484 } 485 } 486 }, 487 488 plugins: {}, 489 490 /** 491 * This is the most high-level function in Prismâs API. 492 * It fetches all the elements that have a `.language-xxxx` class and then calls {@link Prism.highlightElement} on 493 * each one of them. 494 * 495 * This is equivalent to `Prism.highlightAllUnder(document, async, callback)`. 496 * 497 * @param {boolean} [async=false] Same as in {@link Prism.highlightAllUnder}. 498 * @param {HighlightCallback} [callback] Same as in {@link Prism.highlightAllUnder}. 499 * @memberof Prism 500 * @public 501 */ 502 highlightAll: function (async, callback) { 503 _.highlightAllUnder(document, async, callback); 504 }, 505 506 /** 507 * Fetches all the descendants of `container` that have a `.language-xxxx` class and then calls 508 * {@link Prism.highlightElement} on each one of them. 509 * 510 * The following hooks will be run: 511 * 1. `before-highlightall` 512 * 2. `before-all-elements-highlight` 513 * 3. All hooks of {@link Prism.highlightElement} for each element. 514 * 515 * @param {ParentNode} container The root element, whose descendants that have a `.language-xxxx` class will be highlighted. 516 * @param {boolean} [async=false] Whether each element is to be highlighted asynchronously using Web Workers. 517 * @param {HighlightCallback} [callback] An optional callback to be invoked on each element after its highlighting is done. 518 * @memberof Prism 519 * @public 520 */ 521 highlightAllUnder: function (container, async, callback) { 522 var env = { 523 callback: callback, 524 container: container, 525 selector: 'code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code' 526 }; 527 528 _.hooks.run('before-highlightall', env); 529 530 env.elements = Array.prototype.slice.apply(env.container.querySelectorAll(env.selector)); 531 532 _.hooks.run('before-all-elements-highlight', env); 533 534 for (var i = 0, element; (element = env.elements[i++]);) { 535 _.highlightElement(element, async === true, env.callback); 536 } 537 }, 538 539 /** 540 * Highlights the code inside a single element. 541 * 542 * The following hooks will be run: 543 * 1. `before-sanity-check` 544 * 2. `before-highlight` 545 * 3. All hooks of {@link Prism.highlight}. These hooks will be run by an asynchronous worker if `async` is `true`. 546 * 4. `before-insert` 547 * 5. `after-highlight` 548 * 6. `complete` 549 * 550 * Some the above hooks will be skipped if the element doesn't contain any text or there is no grammar loaded for 551 * the element's language. 552 * 553 * @param {Element} element The element containing the code. 554 * It must have a class of `language-xxxx` to be processed, where `xxxx` is a valid language identifier. 555 * @param {boolean} [async=false] Whether the element is to be highlighted asynchronously using Web Workers 556 * to improve performance and avoid blocking the UI when highlighting very large chunks of code. This option is 557 * [disabled by default](https://prismjs.com/faq.html#why-is-asynchronous-highlighting-disabled-by-default). 558 * 559 * Note: All language definitions required to highlight the code must be included in the main `prism.js` file for 560 * asynchronous highlighting to work. You can build your own bundle on the 561 * [Download page](https://prismjs.com/download.html). 562 * @param {HighlightCallback} [callback] An optional callback to be invoked after the highlighting is done. 563 * Mostly useful when `async` is `true`, since in that case, the highlighting is done asynchronously. 564 * @memberof Prism 565 * @public 566 */ 567 highlightElement: function (element, async, callback) { 568 // Find language 569 var language = _.util.getLanguage(element); 570 var grammar = _.languages[language]; 571 572 // Set language on the element, if not present 573 _.util.setLanguage(element, language); 574 575 // Set language on the parent, for styling 576 var parent = element.parentElement; 577 if (parent && parent.nodeName.toLowerCase() === 'pre') { 578 _.util.setLanguage(parent, language); 579 } 580 581 var code = element.textContent; 582 583 var env = { 584 element: element, 585 language: language, 586 grammar: grammar, 587 code: code 588 }; 589 590 function insertHighlightedCode(highlightedCode) { 591 env.highlightedCode = highlightedCode; 592 593 _.hooks.run('before-insert', env); 594 595 env.element.innerHTML = env.highlightedCode; 596 597 _.hooks.run('after-highlight', env); 598 _.hooks.run('complete', env); 599 callback && callback.call(env.element); 600 } 601 602 _.hooks.run('before-sanity-check', env); 603 604 // plugins may change/add the parent/element 605 parent = env.element.parentElement; 606 if (parent && parent.nodeName.toLowerCase() === 'pre' && !parent.hasAttribute('tabindex')) { 607 parent.setAttribute('tabindex', '0'); 608 } 609 610 if (!env.code) { 611 _.hooks.run('complete', env); 612 callback && callback.call(env.element); 613 return; 614 } 615 616 _.hooks.run('before-highlight', env); 617 618 if (!env.grammar) { 619 insertHighlightedCode(_.util.encode(env.code)); 620 return; 621 } 622 623 if (async && _self.Worker) { 624 var worker = new Worker(_.filename); 625 626 worker.onmessage = function (evt) { 627 insertHighlightedCode(evt.data); 628 }; 629 630 worker.postMessage(JSON.stringify({ 631 language: env.language, 632 code: env.code, 633 immediateClose: true 634 })); 635 } else { 636 insertHighlightedCode(_.highlight(env.code, env.grammar, env.language)); 637 } 638 }, 639 640 /** 641 * Low-level function, only use if you know what youâre doing. It accepts a string of text as input 642 * and the language definitions to use, and returns a string with the HTML produced. 643 * 644 * The following hooks will be run: 645 * 1. `before-tokenize` 646 * 2. `after-tokenize` 647 * 3. `wrap`: On each {@link Token}. 648 * 649 * @param {string} text A string with the code to be highlighted. 650 * @param {Grammar} grammar An object containing the tokens to use. 651 * 652 * Usually a language definition like `Prism.languages.markup`. 653 * @param {string} language The name of the language definition passed to `grammar`. 654 * @returns {string} The highlighted HTML. 655 * @memberof Prism 656 * @public 657 * @example 658 * Prism.highlight('var foo = true;', Prism.languages.javascript, 'javascript'); 659 */ 660 highlight: function (text, grammar, language) { 661 var env = { 662 code: text, 663 grammar: grammar, 664 language: language 665 }; 666 _.hooks.run('before-tokenize', env); 667 if (!env.grammar) { 668 throw new Error('The language "' + env.language + '" has no grammar.'); 669 } 670 env.tokens = _.tokenize(env.code, env.grammar); 671 _.hooks.run('after-tokenize', env); 672 return Token.stringify(_.util.encode(env.tokens), env.language); 673 }, 674 675 /** 676 * This is the heart of Prism, and the most low-level function you can use. It accepts a string of text as input 677 * and the language definitions to use, and returns an array with the tokenized code. 678 * 679 * When the language definition includes nested tokens, the function is called recursively on each of these tokens. 680 * 681 * This method could be useful in other contexts as well, as a very crude parser. 682 * 683 * @param {string} text A string with the code to be highlighted. 684 * @param {Grammar} grammar An object containing the tokens to use. 685 * 686 * Usually a language definition like `Prism.languages.markup`. 687 * @returns {TokenStream} An array of strings and tokens, a token stream. 688 * @memberof Prism 689 * @public 690 * @example 691 * let code = `var foo = 0;`; 692 * let tokens = Prism.tokenize(code, Prism.languages.javascript); 693 * tokens.forEach(token => { 694 * if (token instanceof Prism.Token && token.type === 'number') { 695 * console.log(`Found numeric literal: ${token.content}`); 696 * } 697 * }); 698 */ 699 tokenize: function (text, grammar) { 700 var rest = grammar.rest; 701 if (rest) { 702 for (var token in rest) { 703 grammar[token] = rest[token]; 704 } 705 706 delete grammar.rest; 707 } 708 709 var tokenList = new LinkedList(); 710 addAfter(tokenList, tokenList.head, text); 711 712 matchGrammar(text, tokenList, grammar, tokenList.head, 0); 713 714 return toArray(tokenList); 715 }, 716 717 /** 718 * @namespace 719 * @memberof Prism 720 * @public 721 */ 722 hooks: { 723 all: {}, 724 725 /** 726 * Adds the given callback to the list of callbacks for the given hook. 727 * 728 * The callback will be invoked when the hook it is registered for is run. 729 * Hooks are usually directly run by a highlight function but you can also run hooks yourself. 730 * 731 * One callback function can be registered to multiple hooks and the same hook multiple times. 732 * 733 * @param {string} name The name of the hook. 734 * @param {HookCallback} callback The callback function which is given environment variables. 735 * @public 736 */ 737 add: function (name, callback) { 738 var hooks = _.hooks.all; 739 740 hooks[name] = hooks[name] || []; 741 742 hooks[name].push(callback); 743 }, 744 745 /** 746 * Runs a hook invoking all registered callbacks with the given environment variables. 747 * 748 * Callbacks will be invoked synchronously and in the order in which they were registered. 749 * 750 * @param {string} name The name of the hook. 751 * @param {Object<string, any>} env The environment variables of the hook passed to all callbacks registered. 752 * @public 753 */ 754 run: function (name, env) { 755 var callbacks = _.hooks.all[name]; 756 757 if (!callbacks || !callbacks.length) { 758 return; 759 } 760 761 for (var i = 0, callback; (callback = callbacks[i++]);) { 762 callback(env); 763 } 764 } 765 }, 766 767 Token: Token 768 }; 769 _self.Prism = _; 770 771 772 // Typescript note: 773 // The following can be used to import the Token type in JSDoc: 774 // 775 // @typedef {InstanceType<import("./prism-core")["Token"]>} Token 776 777 /** 778 * Creates a new token. 779 * 780 * @param {string} type See {@link Token#type type} 781 * @param {string | TokenStream} content See {@link Token#content content} 782 * @param {string|string[]} [alias] The alias(es) of the token. 783 * @param {string} [matchedStr=""] A copy of the full string this token was created from. 784 * @class 785 * @global 786 * @public 787 */ 788 function Token(type, content, alias, matchedStr) { 789 /** 790 * The type of the token. 791 * 792 * This is usually the key of a pattern in a {@link Grammar}. 793 * 794 * @type {string} 795 * @see GrammarToken 796 * @public 797 */ 798 this.type = type; 799 /** 800 * The strings or tokens contained by this token. 801 * 802 * This will be a token stream if the pattern matched also defined an `inside` grammar. 803 * 804 * @type {string | TokenStream} 805 * @public 806 */ 807 this.content = content; 808 /** 809 * The alias(es) of the token. 810 * 811 * @type {string|string[]} 812 * @see GrammarToken 813 * @public 814 */ 815 this.alias = alias; 816 // Copy of the full string this token was created from 817 this.length = (matchedStr || '').length | 0; 818 } 819 820 /** 821 * A token stream is an array of strings and {@link Token Token} objects. 822 * 823 * Token streams have to fulfill a few properties that are assumed by most functions (mostly internal ones) that process 824 * them. 825 * 826 * 1. No adjacent strings. 827 * 2. No empty strings. 828 * 829 * The only exception here is the token stream that only contains the empty string and nothing else. 830 * 831 * @typedef {Array<string | Token>} TokenStream 832 * @global 833 * @public 834 */ 835 836 /** 837 * Converts the given token or token stream to an HTML representation. 838 * 839 * The following hooks will be run: 840 * 1. `wrap`: On each {@link Token}. 841 * 842 * @param {string | Token | TokenStream} o The token or token stream to be converted. 843 * @param {string} language The name of current language. 844 * @returns {string} The HTML representation of the token or token stream. 845 * @memberof Token 846 * @static 847 */ 848 Token.stringify = function stringify(o, language) { 849 if (typeof o == 'string') { 850 return o; 851 } 852 if (Array.isArray(o)) { 853 var s = ''; 854 o.forEach(function (e) { 855 s += stringify(e, language); 856 }); 857 return s; 858 } 859 860 var env = { 861 type: o.type, 862 content: stringify(o.content, language), 863 tag: 'span', 864 classes: ['token', o.type], 865 attributes: {}, 866 language: language 867 }; 868 869 var aliases = o.alias; 870 if (aliases) { 871 if (Array.isArray(aliases)) { 872 Array.prototype.push.apply(env.classes, aliases); 873 } else { 874 env.classes.push(aliases); 875 } 876 } 877 878 _.hooks.run('wrap', env); 879 880 var attributes = ''; 881 for (var name in env.attributes) { 882 attributes += ' ' + name + '="' + (env.attributes[name] || '').replace(/"/g, '"') + '"'; 883 } 884 885 return '<' + env.tag + ' class="' + env.classes.join(' ') + '"' + attributes + '>' + env.content + '</' + env.tag + '>'; 886 }; 887 888 /** 889 * @param {RegExp} pattern 890 * @param {number} pos 891 * @param {string} text 892 * @param {boolean} lookbehind 893 * @returns {RegExpExecArray | null} 894 */ 895 function matchPattern(pattern, pos, text, lookbehind) { 896 pattern.lastIndex = pos; 897 var match = pattern.exec(text); 898 if (match && lookbehind && match[1]) { 899 // change the match to remove the text matched by the Prism lookbehind group 900 var lookbehindLength = match[1].length; 901 match.index += lookbehindLength; 902 match[0] = match[0].slice(lookbehindLength); 903 } 904 return match; 905 } 906 907 /** 908 * @param {string} text 909 * @param {LinkedList<string | Token>} tokenList 910 * @param {any} grammar 911 * @param {LinkedListNode<string | Token>} startNode 912 * @param {number} startPos 913 * @param {RematchOptions} [rematch] 914 * @returns {void} 915 * @private 916 * 917 * @typedef RematchOptions 918 * @property {string} cause 919 * @property {number} reach 920 */ 921 function matchGrammar(text, tokenList, grammar, startNode, startPos, rematch) { 922 for (var token in grammar) { 923 if (!grammar.hasOwnProperty(token) || !grammar[token]) { 924 continue; 925 } 926 927 var patterns = grammar[token]; 928 patterns = Array.isArray(patterns) ? patterns : [patterns]; 929 930 for (var j = 0; j < patterns.length; ++j) { 931 if (rematch && rematch.cause == token + ',' + j) { 932 return; 933 } 934 935 var patternObj = patterns[j]; 936 var inside = patternObj.inside; 937 var lookbehind = !!patternObj.lookbehind; 938 var greedy = !!patternObj.greedy; 939 var alias = patternObj.alias; 940 941 if (greedy && !patternObj.pattern.global) { 942 // Without the global flag, lastIndex won't work 943 var flags = patternObj.pattern.toString().match(/[imsuy]*$/)[0]; 944 patternObj.pattern = RegExp(patternObj.pattern.source, flags + 'g'); 945 } 946 947 /** @type {RegExp} */ 948 var pattern = patternObj.pattern || patternObj; 949 950 for ( // iterate the token list and keep track of the current token/string position 951 var currentNode = startNode.next, pos = startPos; 952 currentNode !== tokenList.tail; 953 pos += currentNode.value.length, currentNode = currentNode.next 954 ) { 955 956 if (rematch && pos >= rematch.reach) { 957 break; 958 } 959 960 var str = currentNode.value; 961 962 if (tokenList.length > text.length) { 963 // Something went terribly wrong, ABORT, ABORT! 964 return; 965 } 966 967 if (str instanceof Token) { 968 continue; 969 } 970 971 var removeCount = 1; // this is the to parameter of removeBetween 972 var match; 973 974 if (greedy) { 975 match = matchPattern(pattern, pos, text, lookbehind); 976 if (!match || match.index >= text.length) { 977 break; 978 } 979 980 var from = match.index; 981 var to = match.index + match[0].length; 982 var p = pos; 983 984 // find the node that contains the match 985 p += currentNode.value.length; 986 while (from >= p) { 987 currentNode = currentNode.next; 988 p += currentNode.value.length; 989 } 990 // adjust pos (and p) 991 p -= currentNode.value.length; 992 pos = p; 993 994 // the current node is a Token, then the match starts inside another Token, which is invalid 995 if (currentNode.value instanceof Token) { 996 continue; 997 } 998 999 // find the last node which is affected by this match 1000 for ( 1001 var k = currentNode; 1002 k !== tokenList.tail && (p < to || typeof k.value === 'string'); 1003 k = k.next 1004 ) { 1005 removeCount++; 1006 p += k.value.length; 1007 } 1008 removeCount--; 1009 1010 // replace with the new match 1011 str = text.slice(pos, p); 1012 match.index -= pos; 1013 } else { 1014 match = matchPattern(pattern, 0, str, lookbehind); 1015 if (!match) { 1016 continue; 1017 } 1018 } 1019 1020 // eslint-disable-next-line no-redeclare 1021 var from = match.index; 1022 var matchStr = match[0]; 1023 var before = str.slice(0, from); 1024 var after = str.slice(from + matchStr.length); 1025 1026 var reach = pos + str.length; 1027 if (rematch && reach > rematch.reach) { 1028 rematch.reach = reach; 1029 } 1030 1031 var removeFrom = currentNode.prev; 1032 1033 if (before) { 1034 removeFrom = addAfter(tokenList, removeFrom, before); 1035 pos += before.length; 1036 } 1037 1038 removeRange(tokenList, removeFrom, removeCount); 1039 1040 var wrapped = new Token(token, inside ? _.tokenize(matchStr, inside) : matchStr, alias, matchStr); 1041 currentNode = addAfter(tokenList, removeFrom, wrapped); 1042 1043 if (after) { 1044 addAfter(tokenList, currentNode, after); 1045 } 1046 1047 if (removeCount > 1) { 1048 // at least one Token object was removed, so we have to do some rematching 1049 // this can only happen if the current pattern is greedy 1050 1051 /** @type {RematchOptions} */ 1052 var nestedRematch = { 1053 cause: token + ',' + j, 1054 reach: reach 1055 }; 1056 matchGrammar(text, tokenList, grammar, currentNode.prev, pos, nestedRematch); 1057 1058 // the reach might have been extended because of the rematching 1059 if (rematch && nestedRematch.reach > rematch.reach) { 1060 rematch.reach = nestedRematch.reach; 1061 } 1062 } 1063 } 1064 } 1065 } 1066 } 1067 1068 /** 1069 * @typedef LinkedListNode 1070 * @property {T} value 1071 * @property {LinkedListNode<T> | null} prev The previous node. 1072 * @property {LinkedListNode<T> | null} next The next node. 1073 * @template T 1074 * @private 1075 */ 1076 1077 /** 1078 * @template T 1079 * @private 1080 */ 1081 function LinkedList() { 1082 /** @type {LinkedListNode<T>} */ 1083 var head = { value: null, prev: null, next: null }; 1084 /** @type {LinkedListNode<T>} */ 1085 var tail = { value: null, prev: head, next: null }; 1086 head.next = tail; 1087 1088 /** @type {LinkedListNode<T>} */ 1089 this.head = head; 1090 /** @type {LinkedListNode<T>} */ 1091 this.tail = tail; 1092 this.length = 0; 1093 } 1094 1095 /** 1096 * Adds a new node with the given value to the list. 1097 * 1098 * @param {LinkedList<T>} list 1099 * @param {LinkedListNode<T>} node 1100 * @param {T} value 1101 * @returns {LinkedListNode<T>} The added node. 1102 * @template T 1103 */ 1104 function addAfter(list, node, value) { 1105 // assumes that node != list.tail && values.length >= 0 1106 var next = node.next; 1107 1108 var newNode = { value: value, prev: node, next: next }; 1109 node.next = newNode; 1110 next.prev = newNode; 1111 list.length++; 1112 1113 return newNode; 1114 } 1115 /** 1116 * Removes `count` nodes after the given node. The given node will not be removed. 1117 * 1118 * @param {LinkedList<T>} list 1119 * @param {LinkedListNode<T>} node 1120 * @param {number} count 1121 * @template T 1122 */ 1123 function removeRange(list, node, count) { 1124 var next = node.next; 1125 for (var i = 0; i < count && next !== list.tail; i++) { 1126 next = next.next; 1127 } 1128 node.next = next; 1129 next.prev = node; 1130 list.length -= i; 1131 } 1132 /** 1133 * @param {LinkedList<T>} list 1134 * @returns {T[]} 1135 * @template T 1136 */ 1137 function toArray(list) { 1138 var array = []; 1139 var node = list.head.next; 1140 while (node !== list.tail) { 1141 array.push(node.value); 1142 node = node.next; 1143 } 1144 return array; 1145 } 1146 1147 1148 if (!_self.document) { 1149 if (!_self.addEventListener) { 1150 // in Node.js 1151 return _; 1152 } 1153 1154 if (!_.disableWorkerMessageHandler) { 1155 // In worker 1156 _self.addEventListener('message', function (evt) { 1157 var message = JSON.parse(evt.data); 1158 var lang = message.language; 1159 var code = message.code; 1160 var immediateClose = message.immediateClose; 1161 1162 _self.postMessage(_.highlight(code, _.languages[lang], lang)); 1163 if (immediateClose) { 1164 _self.close(); 1165 } 1166 }, false); 1167 } 1168 1169 return _; 1170 } 1171 1172 // Get current script and highlight 1173 var script = _.util.currentScript(); 1174 1175 if (script) { 1176 _.filename = script.src; 1177 1178 if (script.hasAttribute('data-manual')) { 1179 _.manual = true; 1180 } 1181 } 1182 1183 function highlightAutomaticallyCallback() { 1184 if (!_.manual) { 1185 _.highlightAll(); 1186 } 1187 } 1188 1189 if (!_.manual) { 1190 // If the document state is "loading", then we'll use DOMContentLoaded. 1191 // If the document state is "interactive" and the prism.js script is deferred, then we'll also use the 1192 // DOMContentLoaded event because there might be some plugins or languages which have also been deferred and they 1193 // might take longer one animation frame to execute which can create a race condition where only some plugins have 1194 // been loaded when Prism.highlightAll() is executed, depending on how fast resources are loaded. 1195 // See https://github.com/PrismJS/prism/issues/2102 1196 var readyState = document.readyState; 1197 if (readyState === 'loading' || readyState === 'interactive' && script && script.defer) { 1198 document.addEventListener('DOMContentLoaded', highlightAutomaticallyCallback); 1199 } else { 1200 if (window.requestAnimationFrame) { 1201 window.requestAnimationFrame(highlightAutomaticallyCallback); 1202 } else { 1203 window.setTimeout(highlightAutomaticallyCallback, 16); 1204 } 1205 } 1206 } 1207 1208 return _; 1209 1210}(_self)); 1211 1212if (
1212typeof module !== 'undefined' && module.exports) { 1213 module.exports = Prism; 1214} 1215 1216// hack for components to work correctly in node.js 1217if (typeof global !== 'undefined') { 1218 g
vendor: 21,298 bytes, lines 1218-1946
1218lobal.Prism = Prism; 1219} 1220 1221// some additional documentation/types 1222 1223/** 1224 * The expansion of a simple `RegExp` literal to support additional properties. 1225 * 1226 * @typedef GrammarToken 1227 * @property {RegExp} pattern The regular expression of the token. 1228 * @property {boolean} [lookbehind=false] If `true`, then the first capturing group of `pattern` will (effectively) 1229 * behave as a lookbehind group meaning that the captured text will not be part of the matched text of the new token. 1230 * @property {boolean} [greedy=false] Whether the token is greedy. 1231 * @property {string|string[]} [alias] An optional alias or list of aliases. 1232 * @property {Grammar} [inside] The nested grammar of this token. 1233 * 1234 * The `inside` grammar will be used to tokenize the text value of each token of this kind. 1235 * 1236 * This can be used to make nested and even recursive language definitions. 1237 * 1238 * Note: This can cause infinite recursion. Be careful when you embed different languages or even the same language into 1239 * each another. 1240 * @global 1241 * @public 1242 */ 1243 1244/** 1245 * @typedef Grammar 1246 * @type {Object<string, RegExp | GrammarToken | Array<RegExp | GrammarToken>>} 1247 * @property {Grammar} [rest] An optional grammar object that will be appended to this grammar. 1248 * @global 1249 * @public 1250 */ 1251 1252/** 1253 * A function which will invoked after an element was successfully highlighted. 1254 * 1255 * @callback HighlightCallback 1256 * @param {Element} element The element successfully highlighted. 1257 * @returns {void} 1258 * @global 1259 * @public 1260 */ 1261 1262/** 1263 * @callback HookCallback 1264 * @param {Object<string, any>} env The environment variables of the hook. 1265 * @returns {void} 1266 * @global 1267 * @public 1268 */ 1269 1270 1271/* ********************************************** 1272 Begin prism-markup.js 1273********************************************** */ 1274 1275Prism.languages.markup = { 1276 'comment': { 1277 pattern: /<!--(?:(?!<!--)[\s\S])*?-->/, 1278 greedy: true 1279 }, 1280 'prolog': { 1281 pattern: /<\?[\s\S]+?\?>/, 1282 greedy: true 1283 }, 1284 'doctype': { 1285 // https://www.w3.org/TR/xml/#NT-doctypedecl 1286 pattern: /<!DOCTYPE(?:[^>"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|<!--(?:[^-]|-(?!->))*-->)*\]\s*)?>/i, 1287 greedy: true, 1288 inside: { 1289 'internal-subset': { 1290 pattern: /(^[^\[]*\[)[\s\S]+(?=\]>$)/, 1291 lookbehind: true, 1292 greedy: true, 1293 inside: null // see below 1294 }, 1295 'string': { 1296 pattern: /"[^"]*"|'[^']*'/, 1297 greedy: true 1298 }, 1299 'punctuation': /^<!|>$|[[\]]/, 1300 'doctype-tag': /^DOCTYPE/i, 1301 'name': /[^\s<>'"]+/ 1302 } 1303 }, 1304 'cdata': { 1305 pattern: /<!\[CDATA\[[\s\S]*?\]\]>/i, 1306 greedy: true 1307 }, 1308 'tag': { 1309 pattern: /<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/, 1310 greedy: true, 1311 inside: { 1312 'tag': { 1313 pattern: /^<\/?[^\s>\/]+/, 1314 inside: { 1315 'punctuation': /^<\/?/, 1316 'namespace': /^[^\s>\/:]+:/ 1317 } 1318 }, 1319 'special-attr': [], 1320 'attr-value': { 1321 pattern: /=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/, 1322 inside: { 1323 'punctuation': [ 1324 { 1325 pattern: /^=/, 1326 alias: 'attr-equals' 1327 }, 1328 { 1329 pattern: /^(\s*)["']|["']$/, 1330 lookbehind: true 1331 } 1332 ] 1333 } 1334 }, 1335 'punctuation': /\/?>/, 1336 'attr-name': { 1337 pattern: /[^\s>\/]+/, 1338 inside: { 1339 'namespace': /^[^\s>\/:]+:/ 1340 } 1341 } 1342 1343 } 1344 }, 1345 'entity': [ 1346 { 1347 pattern: /&[\da-z]{1,8};/i, 1348 alias: 'named-entity' 1349 }, 1350 /&#x?[\da-f]{1,8};/i 1351 ] 1352}; 1353 1354Prism.languages.markup['tag'].inside['attr-value'].inside['entity'] = 1355 Prism.languages.markup['entity']; 1356Prism.languages.markup['doctype'].inside['internal-subset'].inside = Prism.languages.markup; 1357 1358// Plugin to make entity title show the real entity, idea by Roman Komarov 1359Prism.hooks.add('wrap', function (env) { 1360 1361 if (env.type === 'entity') { 1362 env.attributes['title'] = env.content.replace(/&/, '&'); 1363 } 1364}); 1365 1366Object.defineProperty(Prism.languages.markup.tag, 'addInlined', { 1367 /** 1368 * Adds an inlined language to markup. 1369 * 1370 * An example of an inlined language is CSS with `<style>` tags. 1371 * 1372 * @param {string} tagName The name of the tag that contains the inlined language. This name will be treated as 1373 * case insensitive. 1374 * @param {string} lang The language key. 1375 * @example 1376 * addInlined('style', 'css'); 1377 */ 1378 value: function addInlined(tagName, lang) { 1379 var includedCdataInside = {}; 1380 includedCdataInside['language-' + lang] = { 1381 pattern: /(^<!\[CDATA\[)[\s\S]+?(?=\]\]>$)/i, 1382 lookbehind: true, 1383 inside: Prism.languages[lang] 1384 }; 1385 includedCdataInside['cdata'] = /^<!\[CDATA\[|\]\]>$/i; 1386 1387 var inside = { 1388 'included-cdata': { 1389 pattern: /<!\[CDATA\[[\s\S]*?\]\]>/i, 1390 inside: includedCdataInside 1391 } 1392 }; 1393 inside['language-' + lang] = { 1394 pattern: /[\s\S]+/, 1395 inside: Prism.languages[lang] 1396 }; 1397 1398 var def = {}; 1399 def[tagName] = { 1400 pattern: RegExp(/(<__[^>]*>)(?:<!\[CDATA\[(?:[^\]]|\](?!\]>))*\]\]>|(?!<!\[CDATA\[)[\s\S])*?(?=<\/__>)/.source.replace(/__/g, function () { return tagName; }), 'i'), 1401 lookbehind: true, 1402 greedy: true, 1403 inside: inside 1404 }; 1405 1406 Prism.languages.insertBefore('markup', 'cdata', def); 1407 } 1408}); 1409Object.defineProperty(Prism.languages.markup.tag, 'addAttribute', { 1410 /** 1411 * Adds an pattern to highlight languages embedded in HTML attributes. 1412 * 1413 * An example of an inlined language is CSS with `style` attributes. 1414 * 1415 * @param {string} attrName The name of the tag that contains the inlined language. This name will be treated as 1416 * case insensitive. 1417 * @param {string} lang The language key. 1418 * @example 1419 * addAttribute('style', 'css'); 1420 */ 1421 value: function (attrName, lang) { 1422 Prism.languages.markup.tag.inside['special-attr'].push({ 1423 pattern: RegExp( 1424 /(^|["'\s])/.source + '(?:' + attrName + ')' + /\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))/.source, 1425 'i' 1426 ), 1427 lookbehind: true, 1428 inside: { 1429 'attr-name': /^[^\s=]+/, 1430 'attr-value': { 1431 pattern: /=[\s\S]+/, 1432 inside: { 1433 'value': { 1434 pattern: /(^=\s*(["']|(?!["'])))\S[\s\S]*(?=\2$)/, 1435 lookbehind: true, 1436 alias: [lang, 'language-' + lang], 1437 inside: Prism.languages[lang] 1438 }, 1439 'punctuation': [ 1440 { 1441 pattern: /^=/, 1442 alias: 'attr-equals' 1443 }, 1444 /"|'/ 1445 ] 1446 } 1447 } 1448 } 1449 }); 1450 } 1451}); 1452 1453Prism.languages.html = Prism.languages.markup; 1454Prism.languages.mathml = Prism.languages.markup; 1455Prism.languages.svg = Prism.languages.markup; 1456 1457Prism.languages.xml = Prism.languages.extend('markup', {}); 1458Prism.languages.ssml = Prism.languages.xml; 1459Prism.languages.atom = Prism.languages.xml; 1460Prism.languages.rss = Prism.languages.xml; 1461 1462 1463/* ********************************************** 1464 Begin prism-css.js 1465********************************************** */ 1466 1467(function (Prism) { 1468 1469 var string = /(?:"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n])*')/; 1470 1471 Prism.languages.css = { 1472 'comment': /\/\*[\s\S]*?\*\//, 1473 'atrule': { 1474 pattern: RegExp('@[\\w-](?:' + /[^;{\s"']|\s+(?!\s)/.source + '|' + string.source + ')*?' + /(?:;|(?=\s*\{))/.source), 1475 inside: { 1476 'rule': /^@[\w-]+/, 1477 'selector-function-argument': { 1478 pattern: /(\bselector\s*\(\s*(?![\s)]))(?:[^()\s]|\s+(?![\s)])|\((?:[^()]|\([^()]*\))*\))+(?=\s*\))/, 1479 lookbehind: true, 1480 alias: 'selector' 1481 }, 1482 'keyword': { 1483 pattern: /(^|[^\w-])(?:and|not|only|or)(?![\w-])/, 1484 lookbehind: true 1485 } 1486 // See rest below 1487 } 1488 }, 1489 'url': { 1490 // https://drafts.csswg.org/css-values-3/#urls 1491 pattern: RegExp('\\burl\\((?:' + string.source + '|' + /(?:[^\\\r\n()"']|\\[\s\S])*/.source + ')\\)', 'i'), 1492 greedy: true, 1493 inside: { 1494 'function': /^url/i, 1495 'punctuation': /^\(|\)$/, 1496 'string': { 1497 pattern: RegExp('^' + string.source + '$'), 1498 alias: 'url' 1499 } 1500 } 1501 }, 1502 'selector': { 1503 pattern: RegExp('(^|[{}\\s])[^{}\\s](?:[^{};"\'\\s]|\\s+(?![\\s{])|' + string.source + ')*(?=\\s*\\{)'), 1504 lookbehind: true 1505 }, 1506 'string': { 1507 pattern: string, 1508 greedy: true 1509 }, 1510 'property': { 1511 pattern: /(^|[^-\w\xA0-\uFFFF])(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*(?=\s*:)/i, 1512 lookbehind: true 1513 }, 1514 'important': /!important\b/i, 1515 'function': { 1516 pattern: /(^|[^-a-z0-9])[-a-z0-9]+(?=\()/i, 1517 lookbehind: true 1518 }, 1519 'punctuation': /[(){};:,]/ 1520 }; 1521 1522 Prism.languages.css['atrule'].inside.rest = Prism.languages.css; 1523 1524 var markup = Prism.languages.markup; 1525 if (markup) { 1526 markup.tag.addInlined('style', 'css'); 1527 markup.tag.addAttribute('style', 'css'); 1528 } 1529 1530}(Prism)); 1531 1532 1533/* ********************************************** 1534 Begin prism-clike.js 1535********************************************** */ 1536 1537Prism.languages.clike = { 1538 'comment': [ 1539 { 1540 pattern: /(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/, 1541 lookbehind: true, 1542 greedy: true 1543 }, 1544 { 1545 pattern: /(^|[^\\:])\/\/.*/, 1546 lookbehind: true, 1547 greedy: true 1548 } 1549 ], 1550 'string': { 1551 pattern: /(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/, 1552 greedy: true 1553 }, 1554 'class-name': { 1555 pattern: /(\b(?:class|extends|implements|instanceof|interface|new|trait)\s+|\bcatch\s+\()[\w.\\]+/i, 1556 lookbehind: true, 1557 inside: { 1558 'punctuation': /[.\\]/ 1559 } 1560 }, 1561 'keyword': /\b(?:break|catch|continue|do|else|finally|for|function|if|in|instanceof|new|null|return|throw|try|while)\b/, 1562 'boolean': /\b(?:false|true)\b/, 1563 'function': /\b\w+(?=\()/, 1564 'number': /\b0x[\da-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?/i, 1565 'operator': /[<>]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/, 1566 'punctuation': /[{}[\];(),.:]/ 1567}; 1568 1569 1570/* ********************************************** 1571 Begin prism-javascript.js 1572********************************************** */ 1573 1574Prism.languages.javascript = Prism.languages.extend('clike', { 1575 'class-name': [ 1576 Prism.languages.clike['class-name'], 1577 { 1578 pattern: /(^|[^$\w\xA0-\uFFFF])(?!\s)[_$A-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\.(?:constructor|prototype))/, 1579 lookbehind: true 1580 } 1581 ], 1582 'keyword': [ 1583 { 1584 pattern: /((?:^|\})\s*)catch\b/, 1585 lookbehind: true 1586 }, 1587 { 1588 pattern: /(^|[^.]|\.\.\.\s*)\b(?:as|assert(?=\s*\{)|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally(?=\s*(?:\{|$))|for|from(?=\s*(?:['"]|$))|function|(?:get|set)(?=\s*(?:[#\[$\w\xA0-\uFFFF]|$))|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/, 1589 lookbehind: true 1590 }, 1591 ], 1592 // Allow for all non-ASCII characters (See http://stackoverflow.com/a/2008444) 1593 'function': /#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/, 1594 'number': { 1595 pattern: RegExp( 1596 /(^|[^\w$])/.source + 1597 '(?:' + 1598 ( 1599 // constant 1600 /NaN|Infinity/.source + 1601 '|' + 1602 // binary integer 1603 /0[bB][01]+(?:_[01]+)*n?/.source + 1604 '|' + 1605 // octal integer 1606 /0[oO][0-7]+(?:_[0-7]+)*n?/.source + 1607 '|' + 1608 // hexadecimal integer 1609 /0[xX][\dA-Fa-f]+(?:_[\dA-Fa-f]+)*n?/.source + 1610 '|' + 1611 // decimal bigint 1612 /\d+(?:_\d+)*n/.source + 1613 '|' + 1614 // decimal number (integer or float) but no bigint 1615 /(?:\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\.\d+(?:_\d+)*)(?:[Ee][+-]?\d+(?:_\d+)*)?/.source 1616 ) + 1617 ')' + 1618 /(?![\w$])/.source 1619 ), 1620 lookbehind: true 1621 }, 1622 'operator': /--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/ 1623}); 1624 1625Prism.languages.javascript['class-name'][0].pattern = /(\b(?:class|extends|implements|instanceof|interface|new)\s+)[\w.\\]+/; 1626 1627Prism.languages.insertBefore('javascript', 'keyword', { 1628 'regex': { 1629 pattern: RegExp( 1630 // lookbehind 1631 // eslint-disable-next-line regexp/no-dupe-characters-character-class 1632 /((?:^|[^$\w\xA0-\uFFFF."'\])\s]|\b(?:return|yield))\s*)/.source + 1633 // Regex pattern: 1634 // There are 2 regex patterns here. The RegExp set notation proposal added support for nested character 1635 // classes if the `v` flag is present. Unfortunately, nested CCs are both context-free and incompatible 1636 // with the only syntax, so we have to define 2 different regex patterns. 1637 /\//.source + 1638 '(?:' + 1639 /(?:\[(?:[^\]\\\r\n]|\\.)*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}/.source + 1640 '|' + 1641 // `v` flag syntax. This supports 3 levels of nested character classes. 1642 /(?:\[(?:[^[\]\\\r\n]|\\.|\[(?:[^[\]\\\r\n]|\\.|\[(?:[^[\]\\\r\n]|\\.)*\])*\])*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}v[dgimyus]{0,7}/.source + 1643 ')' + 1644 // lookahead 1645 /(?=(?:\s|\/\*(?:[^*]|\*(?!\/))*\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/.source 1646 ), 1647 lookbehind: true, 1648 greedy: true, 1649 inside: { 1650 'regex-source': { 1651 pattern: /^(\/)[\s\S]+(?=\/[a-z]*$)/, 1652 lookbehind: true, 1653 alias: 'language-regex', 1654 inside: Prism.languages.regex 1655 }, 1656 'regex-delimiter': /^\/|\/$/, 1657 'regex-flags': /^[a-z]+$/, 1658 } 1659 }, 1660 // This must be declared before keyword because we use "function" inside the look-forward 1661 'function-variable': { 1662 pattern: /#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/, 1663 alias: 'function' 1664 }, 1665 'parameter': [ 1666 { 1667 pattern: /(function(?:\s+(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)?\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\))/, 1668 lookbehind: true, 1669 inside: Prism.languages.javascript 1670 }, 1671 { 1672 pattern: /(^|[^$\w\xA0-\uFFFF])(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=>)/i, 1673 lookbehind: true, 1674 inside: Prism.languages.javascript 1675 }, 1676 { 1677 pattern: /(\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*=>)/, 1678 lookbehind: true, 1679 inside: Prism.languages.javascript 1680 }, 1681 { 1682 pattern: /((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*)\(\s*|\]\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*\{)/, 1683 lookbehind: true, 1684 inside: Prism.languages.javascript 1685 } 1686 ], 1687 'constant': /\b[A-Z](?:[A-Z_]|\dx?)*\b/ 1688}); 1689 1690Prism.languages.insertBefore('javascript', 'string', { 1691 'hashbang': { 1692 pattern: /^#!.*/, 1693 greedy: true, 1694 alias: 'comment' 1695 }, 1696 'template-string': { 1697 pattern: /`(?:\\[\s\S]|\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}|(?!\$\{)[^\\`])*`/, 1698 greedy: true, 1699 inside: { 1700 'template-punctuation': { 1701 pattern: /^`|`$/, 1702 alias: 'string' 1703 }, 1704 'interpolation': { 1705 pattern: /((?:^|[^\\])(?:\\{2})*)\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}/, 1706 lookbehind: true, 1707 inside: { 1708 'interpolation-punctuation': { 1709 pattern: /^\$\{|\}$/, 1710 alias: 'punctuation' 1711 }, 1712 rest: Prism.languages.javascript 1713 } 1714 }, 1715 'string': /[\s\S]+/ 1716 } 1717 }, 1718 'string-property': { 1719 pattern: /((?:^|[,{])[ \t]*)(["'])(?:\\(?:\r\n|[\s\S])|(?!\2)[^\\\r\n])*\2(?=\s*:)/m, 1720 lookbehind: true, 1721 greedy: true, 1722 alias: 'property' 1723 } 1724}); 1725 1726Prism.languages.insertBefore('javascript', 'operator', { 1727 'literal-property': { 1728 pattern: /((?:^|[,{])[ \t]*)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*:)/m, 1729 lookbehind: true, 1730 alias: 'property' 1731 }, 1732}); 1733 1734if (Prism.languages.markup) { 1735 Prism.languages.markup.tag.addInlined('script', 'javascript'); 1736 1737 // add attribute support for all DOM events. 1738 // https://developer.mozilla.org/en-US/docs/Web/Events#Standard_events 1739 Prism.languages.markup.tag.addAttribute( 1740 /on(?:abort|blur|change|click|composition(?:end|start|update)|dblclick|error|focus(?:in|out)?|key(?:down|up)|load|mouse(?:down|enter|leave|move|out|over|up)|reset|resize|scroll|select|slotchange|submit|unload|wheel)/.source, 1741 'javascript' 1742 ); 1743} 1744 1745Prism.languages.js = Prism.languages.javascript; 1746 1747 1748/* ********************************************** 1749 Begin prism-file-highlight.js 1750********************************************** */ 1751 1752(function () { 1753 1754 if (typeof Prism === 'undefined' || typeof document === 'undefined') { 1755 return; 1756 } 1757 1758 // https://developer.mozilla.org/en-US/docs/Web/API/Element/matches#Polyfill 1759 if (!Element.prototype.matches) { 1760 Element.prototype.matches = Element.prototype.msMatchesSelector || Element.prototype.webkitMatchesSelector; 1761 } 1762 1763 var LOADING_MESSAGE = 'Loadingâ¦'; 1764 var FAILURE_MESSAGE = function (status, message) { 1765 return 'â Error ' + status + ' while fetching file: ' + message; 1766 }; 1767 var FAILURE_EMPTY_MESSAGE = 'â Error: File does not exist or is empty'; 1768 1769 var EXTENSIONS = { 1770 'js': 'javascript', 1771 'py': 'python', 1772 'rb': 'ruby', 1773 'ps1': 'powershell', 1774 'psm1': 'powershell', 1775 'sh': 'bash', 1776 'bat': 'batch', 1777 'h': 'c', 1778 'tex': 'latex' 1779 }; 1780 1781 var STATUS_ATTR = 'data-src-status'; 1782 var STATUS_LOADING = 'loading'; 1783 var STATUS_LOADED = 'loaded'; 1784 var STATUS_FAILED = 'failed'; 1785 1786 var SELECTOR = 'pre[data-src]:not([' + STATUS_ATTR + '="' + STATUS_LOADED + '"])' 1787 + ':not([' + STATUS_ATTR + '="' + STATUS_LOADING + '"])'; 1788 1789 /** 1790 * Loads the given file. 1791 * 1792 * @param {string} src The URL or path of the source file to load. 1793 * @param {(result: string) => void} success 1794 * @param {(reason: string) => void} error 1795 */ 1796 function loadFile(src, success, error) { 1797 var xhr = new XMLHttpRequest(); 1798 xhr.open('GET', src, true); 1799 xhr.onreadystatechange = function () { 1800 if (xhr.readyState == 4) { 1801 if (xhr.status < 400 && xhr.responseText) { 1802 success(xhr.responseText); 1803 } else { 1804 if (xhr.status >= 400) { 1805 error(FAILURE_MESSAGE(xhr.status, xhr.statusText)); 1806 } else { 1807 error(FAILURE_EMPTY_MESSAGE); 1808 } 1809 } 1810 } 1811 }; 1812 xhr.send(null); 1813 } 1814 1815 /** 1816 * Parses the given range. 1817 * 1818 * This returns a range with inclusive ends. 1819 * 1820 * @param {string | null | undefined} range 1821 * @returns {[number, number | undefined] | undefined} 1822 */ 1823 function parseRange(range) { 1824 var m = /^\s*(\d+)\s*(?:(,)\s*(?:(\d+)\s*)?)?$/.exec(range || ''); 1825 if (m) { 1826 var start = Number(m[1]); 1827 var comma = m[2]; 1828 var end = m[3]; 1829 1830 if (!comma) { 1831 return [start, start]; 1832 } 1833 if (!end) { 1834 return [start, undefined]; 1835 } 1836 return [start, Number(end)]; 1837 } 1838 return undefined; 1839 } 1840 1841 Prism.hooks.add('before-highlightall', function (env) { 1842 env.selector += ', ' + SELECTOR; 1843 }); 1844 1845 Prism.hooks.add('before-sanity-check', function (env) { 1846 var pre = /** @type {HTMLPreElement} */ (env.element); 1847 if (pre.matches(SELECTOR)) { 1848 env.code = ''; // fast-path the whole thing and go to complete 1849 1850 pre.setAttribute(STATUS_ATTR, STATUS_LOADING); // mark as loading 1851 1852 // add code element with loading message 1853 var code = pre.appendChild(document.createElement('CODE')); 1854 code.textContent = LOADING_MESSAGE; 1855 1856 var src = pre.getAttribute('data-src'); 1857 1858 var language = env.language; 1859 if (language === 'none') { 1860 // the language might be 'none' because there is no language set; 1861 // in this case, we want to use the extension as the language 1862 var extension = (/\.(\w+)$/.exec(src) || [, 'none'])[1]; 1863 language = EXTENSIONS[extension] || extension; 1864 } 1865 1866 // set language classes 1867 Prism.util.setLanguage(code, language); 1868 Prism.util.setLanguage(pre, language); 1869 1870 // preload the language 1871 var autoloader = Prism.plugins.autoloader; 1872 if (autoloader) { 1873 autoloader.loadLanguages(language); 1874 } 1875 1876 // load file 1877 loadFile( 1878 src, 1879 function (text) { 1880 // mark as loaded 1881 pre.setAttribute(STATUS_ATTR, STATUS_LOADED); 1882 1883 // handle data-range 1884 var range = parseRange(pre.getAttribute('data-range')); 1885 if (range) { 1886 var lines = text.split(/\r\n?|\n/g); 1887 1888 // the range is one-based and inclusive on both ends 1889 var start = range[0]; 1890 var end = range[1] == null ? lines.length : range[1]; 1891 1892 if (start < 0) { start += lines.length; } 1893 start = Math.max(0, Math.min(start - 1, lines.length)); 1894 if (end < 0) { end += lines.length; } 1895 end = Math.max(0, Math.min(end, lines.length)); 1896 1897 text = lines.slice(start, end).join('\n'); 1898 1899 // add data-start for line numbers 1900 if (!pre.hasAttribute('data-start')) { 1901 pre.setAttribute('data-start', String(start + 1)); 1902 } 1903 } 1904 1905 // highlight code 1906 code.textContent = text; 1907 Prism.highlightElement(code); 1908 }, 1909 function (error) { 1910 // mark as failed 1911 pre.setAttribute(STATUS_ATTR, STATUS_FAILED); 1912 1913 code.textContent = error; 1914 } 1915 ); 1916 } 1917 }); 1918 1919 Prism.plugins.fileHighlight = { 1920 /** 1921 * Executes the File Highlight plugin for all matching `pre` elements under the given container. 1922 * 1923 * Note: Elements which are already loaded or currently loading will not be touched by this method. 1924 * 1925 * @param {ParentNode} [container=document] 1926 */ 1927 highlight: function highlight(container) { 1928 var elements = (container || document).querySelectorAll(SELECTOR); 1929 1930 for (var i = 0, element; (element = elements[i++]);) { 1931 Prism.highlightElement(element); 1932 } 1933 } 1934 }; 1935 1936 var logged = false; 1937 /** @deprecated Use `Prism.plugins.fileHighlight.highlight` instead. */ 1938 Prism.fileHighlight = function () { 1939 if (!logged) { 1940 console.warn('Prism.fileHighlight is deprecated. Use `Prism.plugins.fileHighlight.highlight` instead.'); 1941 logged = true; 1942 } 1943 Prism.plugins.fileHighlight.highlight.apply(this, arguments); 1944 }; 1945 1946}());
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.