UNPKG

29.5 kBJavaScriptView Raw
1
2/* **********************************************
3 Begin prism-core.js
4********************************************** */
5
6var _self = (typeof window !== 'undefined')
7 ? window // if in browser
8 : (
9 (typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope)
10 ? self // if in worker
11 : {} // if in node js
12 );
13
14/**
15 * Prism: Lightweight, robust, elegant syntax highlighting
16 * MIT license http://www.opensource.org/licenses/mit-license.php/
17 * @author Lea Verou http://lea.verou.me
18 */
19
20var Prism = (function (_self){
21
22// Private helper vars
23var lang = /\blang(?:uage)?-([\w-]+)\b/i;
24var uniqueId = 0;
25
26
27var _ = {
28 manual: _self.Prism && _self.Prism.manual,
29 disableWorkerMessageHandler: _self.Prism && _self.Prism.disableWorkerMessageHandler,
30 util: {
31 encode: function encode(tokens) {
32 if (tokens instanceof Token) {
33 return new Token(tokens.type, encode(tokens.content), tokens.alias);
34 } else if (Array.isArray(tokens)) {
35 return tokens.map(encode);
36 } else {
37 return tokens.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/\u00a0/g, ' ');
38 }
39 },
40
41 type: function (o) {
42 return Object.prototype.toString.call(o).slice(8, -1);
43 },
44
45 objId: function (obj) {
46 if (!obj['__id']) {
47 Object.defineProperty(obj, '__id', { value: ++uniqueId });
48 }
49 return obj['__id'];
50 },
51
52 // Deep clone a language definition (e.g. to extend it)
53 clone: function deepClone(o, visited) {
54 var clone, id, type = _.util.type(o);
55 visited = visited || {};
56
57 switch (type) {
58 case 'Object':
59 id = _.util.objId(o);
60 if (visited[id]) {
61 return visited[id];
62 }
63 clone = {};
64 visited[id] = clone;
65
66 for (var key in o) {
67 if (o.hasOwnProperty(key)) {
68 clone[key] = deepClone(o[key], visited);
69 }
70 }
71
72 return clone;
73
74 case 'Array':
75 id = _.util.objId(o);
76 if (visited[id]) {
77 return visited[id];
78 }
79 clone = [];
80 visited[id] = clone;
81
82 o.forEach(function (v, i) {
83 clone[i] = deepClone(v, visited);
84 });
85
86 return clone;
87
88 default:
89 return o;
90 }
91 },
92
93 /**
94 * Returns the Prism language of the given element set by a `language-xxxx` or `lang-xxxx` class.
95 *
96 * If no language is set for the element or the element is `null` or `undefined`, `none` will be returned.
97 *
98 * @param {Element} element
99 * @returns {string}
100 */
101 getLanguage: function (element) {
102 while (element && !lang.test(element.className)) {
103 element = element.parentElement;
104 }
105 if (element) {
106 return (element.className.match(lang) || [, 'none'])[1].toLowerCase();
107 }
108 return 'none';
109 },
110
111 /**
112 * Returns the script element that is currently executing.
113 *
114 * This does __not__ work for line script element.
115 *
116 * @returns {HTMLScriptElement | null}
117 */
118 currentScript: function () {
119 if (typeof document === 'undefined') {
120 return null;
121 }
122 if ('currentScript' in document) {
123 return document.currentScript;
124 }
125
126 // IE11 workaround
127 // we'll get the src of the current script by parsing IE11's error stack trace
128 // this will not work for inline scripts
129
130 try {
131 throw new Error();
132 } catch (err) {
133 // Get file src url from stack. Specifically works with the format of stack traces in IE.
134 // A stack will look like this:
135 //
136 // Error
137 // at _.util.currentScript (http://localhost/components/prism-core.js:119:5)
138 // at Global code (http://localhost/components/prism-core.js:606:1)
139
140 var src = (/at [^(\r\n]*\((.*):.+:.+\)$/i.exec(err.stack) || [])[1];
141 if (src) {
142 var scripts = document.getElementsByTagName('script');
143 for (var i in scripts) {
144 if (scripts[i].src == src) {
145 return scripts[i];
146 }
147 }
148 }
149 return null;
150 }
151 }
152 },
153
154 languages: {
155 extend: function (id, redef) {
156 var lang = _.util.clone(_.languages[id]);
157
158 for (var key in redef) {
159 lang[key] = redef[key];
160 }
161
162 return lang;
163 },
164
165 /**
166 * Insert a token before another token in a language literal
167 * As this needs to recreate the object (we cannot actually insert before keys in object literals),
168 * we cannot just provide an object, we need an object and a key.
169 * @param inside The key (or language id) of the parent
170 * @param before The key to insert before.
171 * @param insert Object with the key/value pairs to insert
172 * @param root The object that contains `inside`. If equal to Prism.languages, it can be omitted.
173 */
174 insertBefore: function (inside, before, insert, root) {
175 root = root || _.languages;
176 var grammar = root[inside];
177 var ret = {};
178
179 for (var token in grammar) {
180 if (grammar.hasOwnProperty(token)) {
181
182 if (token == before) {
183 for (var newToken in insert) {
184 if (insert.hasOwnProperty(newToken)) {
185 ret[newToken] = insert[newToken];
186 }
187 }
188 }
189
190 // Do not insert token which also occur in insert. See #1525
191 if (!insert.hasOwnProperty(token)) {
192 ret[token] = grammar[token];
193 }
194 }
195 }
196
197 var old = root[inside];
198 root[inside] = ret;
199
200 // Update references in other language definitions
201 _.languages.DFS(_.languages, function(key, value) {
202 if (value === old && key != inside) {
203 this[key] = ret;
204 }
205 });
206
207 return ret;
208 },
209
210 // Traverse a language definition with Depth First Search
211 DFS: function DFS(o, callback, type, visited) {
212 visited = visited || {};
213
214 var objId = _.util.objId;
215
216 for (var i in o) {
217 if (o.hasOwnProperty(i)) {
218 callback.call(o, i, o[i], type || i);
219
220 var property = o[i],
221 propertyType = _.util.type(property);
222
223 if (propertyType === 'Object' && !visited[objId(property)]) {
224 visited[objId(property)] = true;
225 DFS(property, callback, null, visited);
226 }
227 else if (propertyType === 'Array' && !visited[objId(property)]) {
228 visited[objId(property)] = true;
229 DFS(property, callback, i, visited);
230 }
231 }
232 }
233 }
234 },
235 plugins: {},
236
237 highlightAll: function(async, callback) {
238 _.highlightAllUnder(document, async, callback);
239 },
240
241 highlightAllUnder: function(container, async, callback) {
242 var env = {
243 callback: callback,
244 container: container,
245 selector: 'code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code'
246 };
247
248 _.hooks.run('before-highlightall', env);
249
250 env.elements = Array.prototype.slice.apply(env.container.querySelectorAll(env.selector));
251
252 _.hooks.run('before-all-elements-highlight', env);
253
254 for (var i = 0, element; element = env.elements[i++];) {
255 _.highlightElement(element, async === true, env.callback);
256 }
257 },
258
259 highlightElement: function(element, async, callback) {
260 // Find language
261 var language = _.util.getLanguage(element);
262 var grammar = _.languages[language];
263
264 // Set language on the element, if not present
265 element.className = element.className.replace(lang, '').replace(/\s+/g, ' ') + ' language-' + language;
266
267 // Set language on the parent, for styling
268 var parent = element.parentNode;
269 if (parent && parent.nodeName.toLowerCase() === 'pre') {
270 parent.className = parent.className.replace(lang, '').replace(/\s+/g, ' ') + ' language-' + language;
271 }
272
273 var code = element.textContent;
274
275 var env = {
276 element: element,
277 language: language,
278 grammar: grammar,
279 code: code
280 };
281
282 function insertHighlightedCode(highlightedCode) {
283 env.highlightedCode = highlightedCode;
284
285 _.hooks.run('before-insert', env);
286
287 env.element.innerHTML = env.highlightedCode;
288
289 _.hooks.run('after-highlight', env);
290 _.hooks.run('complete', env);
291 callback && callback.call(env.element);
292 }
293
294 _.hooks.run('before-sanity-check', env);
295
296 if (!env.code) {
297 _.hooks.run('complete', env);
298 callback && callback.call(env.element);
299 return;
300 }
301
302 _.hooks.run('before-highlight', env);
303
304 if (!env.grammar) {
305 insertHighlightedCode(_.util.encode(env.code));
306 return;
307 }
308
309 if (async && _self.Worker) {
310 var worker = new Worker(_.filename);
311
312 worker.onmessage = function(evt) {
313 insertHighlightedCode(evt.data);
314 };
315
316 worker.postMessage(JSON.stringify({
317 language: env.language,
318 code: env.code,
319 immediateClose: true
320 }));
321 }
322 else {
323 insertHighlightedCode(_.highlight(env.code, env.grammar, env.language));
324 }
325 },
326
327 highlight: function (text, grammar, language) {
328 var env = {
329 code: text,
330 grammar: grammar,
331 language: language
332 };
333 _.hooks.run('before-tokenize', env);
334 env.tokens = _.tokenize(env.code, env.grammar);
335 _.hooks.run('after-tokenize', env);
336 return Token.stringify(_.util.encode(env.tokens), env.language);
337 },
338
339 tokenize: function(text, grammar) {
340 var rest = grammar.rest;
341 if (rest) {
342 for (var token in rest) {
343 grammar[token] = rest[token];
344 }
345
346 delete grammar.rest;
347 }
348
349 var tokenList = new LinkedList();
350 addAfter(tokenList, tokenList.head, text);
351
352 matchGrammar(text, tokenList, grammar, tokenList.head, 0);
353
354 return toArray(tokenList);
355 },
356
357 hooks: {
358 all: {},
359
360 add: function (name, callback) {
361 var hooks = _.hooks.all;
362
363 hooks[name] = hooks[name] || [];
364
365 hooks[name].push(callback);
366 },
367
368 run: function (name, env) {
369 var callbacks = _.hooks.all[name];
370
371 if (!callbacks || !callbacks.length) {
372 return;
373 }
374
375 for (var i=0, callback; callback = callbacks[i++];) {
376 callback(env);
377 }
378 }
379 },
380
381 Token: Token
382};
383
384_self.Prism = _;
385
386function Token(type, content, alias, matchedStr, greedy) {
387 this.type = type;
388 this.content = content;
389 this.alias = alias;
390 // Copy of the full string this token was created from
391 this.length = (matchedStr || '').length|0;
392 this.greedy = !!greedy;
393}
394
395Token.stringify = function stringify(o, language) {
396 if (typeof o == 'string') {
397 return o;
398 }
399 if (Array.isArray(o)) {
400 var s = '';
401 o.forEach(function (e) {
402 s += stringify(e, language);
403 });
404 return s;
405 }
406
407 var env = {
408 type: o.type,
409 content: stringify(o.content, language),
410 tag: 'span',
411 classes: ['token', o.type],
412 attributes: {},
413 language: language
414 };
415
416 var aliases = o.alias;
417 if (aliases) {
418 if (Array.isArray(aliases)) {
419 Array.prototype.push.apply(env.classes, aliases);
420 } else {
421 env.classes.push(aliases);
422 }
423 }
424
425 _.hooks.run('wrap', env);
426
427 var attributes = '';
428 for (var name in env.attributes) {
429 attributes += ' ' + name + '="' + (env.attributes[name] || '').replace(/"/g, '&quot;') + '"';
430 }
431
432 return '<' + env.tag + ' class="' + env.classes.join(' ') + '"' + attributes + '>' + env.content + '</' + env.tag + '>';
433};
434
435/**
436 * @param {string} text
437 * @param {LinkedList<string | Token>} tokenList
438 * @param {any} grammar
439 * @param {LinkedListNode<string | Token>} startNode
440 * @param {number} startPos
441 * @param {boolean} [oneshot=false]
442 * @param {string} [target]
443 */
444function matchGrammar(text, tokenList, grammar, startNode, startPos, oneshot, target) {
445 for (var token in grammar) {
446 if (!grammar.hasOwnProperty(token) || !grammar[token]) {
447 continue;
448 }
449
450 var patterns = grammar[token];
451 patterns = Array.isArray(patterns) ? patterns : [patterns];
452
453 for (var j = 0; j < patterns.length; ++j) {
454 if (target && target == token + ',' + j) {
455 return;
456 }
457
458 var pattern = patterns[j],
459 inside = pattern.inside,
460 lookbehind = !!pattern.lookbehind,
461 greedy = !!pattern.greedy,
462 lookbehindLength = 0,
463 alias = pattern.alias;
464
465 if (greedy && !pattern.pattern.global) {
466 // Without the global flag, lastIndex won't work
467 var flags = pattern.pattern.toString().match(/[imsuy]*$/)[0];
468 pattern.pattern = RegExp(pattern.pattern.source, flags + 'g');
469 }
470
471 pattern = pattern.pattern || pattern;
472
473 for ( // iterate the token list and keep track of the current token/string position
474 var currentNode = startNode.next, pos = startPos;
475 currentNode !== tokenList.tail;
476 pos += currentNode.value.length, currentNode = currentNode.next
477 ) {
478
479 var str = currentNode.value;
480
481 if (tokenList.length > text.length) {
482 // Something went terribly wrong, ABORT, ABORT!
483 return;
484 }
485
486 if (str instanceof Token) {
487 continue;
488 }
489
490 var removeCount = 1; // this is the to parameter of removeBetween
491
492 if (greedy && currentNode != tokenList.tail.prev) {
493 pattern.lastIndex = pos;
494 var match = pattern.exec(text);
495 if (!match) {
496 break;
497 }
498
499 var from = match.index + (lookbehind && match[1] ? match[1].length : 0);
500 var to = match.index + match[0].length;
501 var p = pos;
502
503 // find the node that contains the match
504 p += currentNode.value.length;
505 while (from >= p) {
506 currentNode = currentNode.next;
507 p += currentNode.value.length;
508 }
509 // adjust pos (and p)
510 p -= currentNode.value.length;
511 pos = p;
512
513 // the current node is a Token, then the match starts inside another Token, which is invalid
514 if (currentNode.value instanceof Token) {
515 continue;
516 }
517
518 // find the last node which is affected by this match
519 for (
520 var k = currentNode;
521 k !== tokenList.tail && (p < to || (typeof k.value === 'string' && !k.prev.value.greedy));
522 k = k.next
523 ) {
524 removeCount++;
525 p += k.value.length;
526 }
527 removeCount--;
528
529 // replace with the new match
530 str = text.slice(pos, p);
531 match.index -= pos;
532 } else {
533 pattern.lastIndex = 0;
534
535 var match = pattern.exec(str);
536 }
537
538 if (!match) {
539 if (oneshot) {
540 break;
541 }
542
543 continue;
544 }
545
546 if (lookbehind) {
547 lookbehindLength = match[1] ? match[1].length : 0;
548 }
549
550 var from = match.index + lookbehindLength,
551 match = match[0].slice(lookbehindLength),
552 to = from + match.length,
553 before = str.slice(0, from),
554 after = str.slice(to);
555
556 var removeFrom = currentNode.prev;
557
558 if (before) {
559 removeFrom = addAfter(tokenList, removeFrom, before);
560 pos += before.length;
561 }
562
563 removeRange(tokenList, removeFrom, removeCount);
564
565 var wrapped = new Token(token, inside ? _.tokenize(match, inside) : match, alias, match, greedy);
566 currentNode = addAfter(tokenList, removeFrom, wrapped);
567
568 if (after) {
569 addAfter(tokenList, currentNode, after);
570 }
571
572
573 if (removeCount > 1)
574 matchGrammar(text, tokenList, grammar, currentNode.prev, pos, true, token + ',' + j);
575
576 if (oneshot)
577 break;
578 }
579 }
580 }
581}
582
583/**
584 * @typedef LinkedListNode
585 * @property {T} value
586 * @property {LinkedListNode<T> | null} prev The previous node.
587 * @property {LinkedListNode<T> | null} next The next node.
588 * @template T
589 */
590
591/**
592 * @template T
593 */
594function LinkedList() {
595 /** @type {LinkedListNode<T>} */
596 var head = { value: null, prev: null, next: null };
597 /** @type {LinkedListNode<T>} */
598 var tail = { value: null, prev: head, next: null };
599 head.next = tail;
600
601 /** @type {LinkedListNode<T>} */
602 this.head = head;
603 /** @type {LinkedListNode<T>} */
604 this.tail = tail;
605 this.length = 0;
606}
607
608/**
609 * Adds a new node with the given value to the list.
610 * @param {LinkedList<T>} list
611 * @param {LinkedListNode<T>} node
612 * @param {T} value
613 * @returns {LinkedListNode<T>} The added node.
614 * @template T
615 */
616function addAfter(list, node, value) {
617 // assumes that node != list.tail && values.length >= 0
618 var next = node.next;
619
620 var newNode = { value: value, prev: node, next: next };
621 node.next = newNode;
622 next.prev = newNode;
623 list.length++;
624
625 return newNode;
626}
627/**
628 * Removes `count` nodes after the given node. The given node will not be removed.
629 * @param {LinkedList<T>} list
630 * @param {LinkedListNode<T>} node
631 * @param {number} count
632 * @template T
633 */
634function removeRange(list, node, count) {
635 var next = node.next;
636 for (var i = 0; i < count && next !== list.tail; i++) {
637 next = next.next;
638 }
639 node.next = next;
640 next.prev = node;
641 list.length -= i;
642}
643/**
644 * @param {LinkedList<T>} list
645 * @returns {T[]}
646 * @template T
647 */
648function toArray(list) {
649 var array = [];
650 var node = list.head.next;
651 while (node !== list.tail) {
652 array.push(node.value);
653 node = node.next;
654 }
655 return array;
656}
657
658
659if (!_self.document) {
660 if (!_self.addEventListener) {
661 // in Node.js
662 return _;
663 }
664
665 if (!_.disableWorkerMessageHandler) {
666 // In worker
667 _self.addEventListener('message', function (evt) {
668 var message = JSON.parse(evt.data),
669 lang = message.language,
670 code = message.code,
671 immediateClose = message.immediateClose;
672
673 _self.postMessage(_.highlight(code, _.languages[lang], lang));
674 if (immediateClose) {
675 _self.close();
676 }
677 }, false);
678 }
679
680 return _;
681}
682
683//Get current script and highlight
684var script = _.util.currentScript();
685
686if (script) {
687 _.filename = script.src;
688
689 if (script.hasAttribute('data-manual')) {
690 _.manual = true;
691 }
692}
693
694function highlightAutomaticallyCallback() {
695 if (!_.manual) {
696 _.highlightAll();
697 }
698}
699
700if (!_.manual) {
701 // If the document state is "loading", then we'll use DOMContentLoaded.
702 // If the document state is "interactive" and the prism.js script is deferred, then we'll also use the
703 // DOMContentLoaded event because there might be some plugins or languages which have also been deferred and they
704 // might take longer one animation frame to execute which can create a race condition where only some plugins have
705 // been loaded when Prism.highlightAll() is executed, depending on how fast resources are loaded.
706 // See https://github.com/PrismJS/prism/issues/2102
707 var readyState = document.readyState;
708 if (readyState === 'loading' || readyState === 'interactive' && script && script.defer) {
709 document.addEventListener('DOMContentLoaded', highlightAutomaticallyCallback);
710 } else {
711 if (window.requestAnimationFrame) {
712 window.requestAnimationFrame(highlightAutomaticallyCallback);
713 } else {
714 window.setTimeout(highlightAutomaticallyCallback, 16);
715 }
716 }
717}
718
719return _;
720
721})(_self);
722
723if (typeof module !== 'undefined' && module.exports) {
724 module.exports = Prism;
725}
726
727// hack for components to work correctly in node.js
728if (typeof global !== 'undefined') {
729 global.Prism = Prism;
730}
731
732
733/* **********************************************
734 Begin prism-markup.js
735********************************************** */
736
737Prism.languages.markup = {
738 'comment': /<!--[\s\S]*?-->/,
739 'prolog': /<\?[\s\S]+?\?>/,
740 'doctype': {
741 pattern: /<!DOCTYPE(?:[^>"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:(?!<!--)[^"'\]]|"[^"]*"|'[^']*'|<!--[\s\S]*?-->)*\]\s*)?>/i,
742 greedy: true
743 },
744 'cdata': /<!\[CDATA\[[\s\S]*?]]>/i,
745 'tag': {
746 pattern: /<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/i,
747 greedy: true,
748 inside: {
749 'tag': {
750 pattern: /^<\/?[^\s>\/]+/i,
751 inside: {
752 'punctuation': /^<\/?/,
753 'namespace': /^[^\s>\/:]+:/
754 }
755 },
756 'attr-value': {
757 pattern: /=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/i,
758 inside: {
759 'punctuation': [
760 /^=/,
761 {
762 pattern: /^(\s*)["']|["']$/,
763 lookbehind: true
764 }
765 ]
766 }
767 },
768 'punctuation': /\/?>/,
769 'attr-name': {
770 pattern: /[^\s>\/]+/,
771 inside: {
772 'namespace': /^[^\s>\/:]+:/
773 }
774 }
775
776 }
777 },
778 'entity': /&#?[\da-z]{1,8};/i
779};
780
781Prism.languages.markup['tag'].inside['attr-value'].inside['entity'] =
782 Prism.languages.markup['entity'];
783
784// Plugin to make entity title show the real entity, idea by Roman Komarov
785Prism.hooks.add('wrap', function(env) {
786
787 if (env.type === 'entity') {
788 env.attributes['title'] = env.content.replace(/&amp;/, '&');
789 }
790});
791
792Object.defineProperty(Prism.languages.markup.tag, 'addInlined', {
793 /**
794 * Adds an inlined language to markup.
795 *
796 * An example of an inlined language is CSS with `<style>` tags.
797 *
798 * @param {string} tagName The name of the tag that contains the inlined language. This name will be treated as
799 * case insensitive.
800 * @param {string} lang The language key.
801 * @example
802 * addInlined('style', 'css');
803 */
804 value: function addInlined(tagName, lang) {
805 var includedCdataInside = {};
806 includedCdataInside['language-' + lang] = {
807 pattern: /(^<!\[CDATA\[)[\s\S]+?(?=\]\]>$)/i,
808 lookbehind: true,
809 inside: Prism.languages[lang]
810 };
811 includedCdataInside['cdata'] = /^<!\[CDATA\[|\]\]>$/i;
812
813 var inside = {
814 'included-cdata': {
815 pattern: /<!\[CDATA\[[\s\S]*?\]\]>/i,
816 inside: includedCdataInside
817 }
818 };
819 inside['language-' + lang] = {
820 pattern: /[\s\S]+/,
821 inside: Prism.languages[lang]
822 };
823
824 var def = {};
825 def[tagName] = {
826 pattern: RegExp(/(<__[\s\S]*?>)(?:<!\[CDATA\[[\s\S]*?\]\]>\s*|[\s\S])*?(?=<\/__>)/.source.replace(/__/g, function () { return tagName; }), 'i'),
827 lookbehind: true,
828 greedy: true,
829 inside: inside
830 };
831
832 Prism.languages.insertBefore('markup', 'cdata', def);
833 }
834});
835
836Prism.languages.xml = Prism.languages.extend('markup', {});
837Prism.languages.html = Prism.languages.markup;
838Prism.languages.mathml = Prism.languages.markup;
839Prism.languages.svg = Prism.languages.markup;
840
841
842/* **********************************************
843 Begin prism-css.js
844********************************************** */
845
846(function (Prism) {
847
848 var string = /("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/;
849
850 Prism.languages.css = {
851 'comment': /\/\*[\s\S]*?\*\//,
852 'atrule': {
853 pattern: /@[\w-]+[\s\S]*?(?:;|(?=\s*\{))/,
854 inside: {
855 'rule': /^@[\w-]+/,
856 'selector-function-argument': {
857 pattern: /(\bselector\s*\((?!\s*\))\s*)(?:[^()]|\((?:[^()]|\([^()]*\))*\))+?(?=\s*\))/,
858 lookbehind: true,
859 alias: 'selector'
860 }
861 // See rest below
862 }
863 },
864 'url': {
865 pattern: RegExp('url\\((?:' + string.source + '|[^\n\r()]*)\\)', 'i'),
866 greedy: true,
867 inside: {
868 'function': /^url/i,
869 'punctuation': /^\(|\)$/
870 }
871 },
872 'selector': RegExp('[^{}\\s](?:[^{};"\']|' + string.source + ')*?(?=\\s*\\{)'),
873 'string': {
874 pattern: string,
875 greedy: true
876 },
877 'property': /[-_a-z\xA0-\uFFFF][-\w\xA0-\uFFFF]*(?=\s*:)/i,
878 'important': /!important\b/i,
879 'function': /[-a-z0-9]+(?=\()/i,
880 'punctuation': /[(){};:,]/
881 };
882
883 Prism.languages.css['atrule'].inside.rest = Prism.languages.css;
884
885 var markup = Prism.languages.markup;
886 if (markup) {
887 markup.tag.addInlined('style', 'css');
888
889 Prism.languages.insertBefore('inside', 'attr-value', {
890 'style-attr': {
891 pattern: /\s*style=("|')(?:\\[\s\S]|(?!\1)[^\\])*\1/i,
892 inside: {
893 'attr-name': {
894 pattern: /^\s*style/i,
895 inside: markup.tag.inside
896 },
897 'punctuation': /^\s*=\s*['"]|['"]\s*$/,
898 'attr-value': {
899 pattern: /.+/i,
900 inside: Prism.languages.css
901 }
902 },
903 alias: 'language-css'
904 }
905 }, markup.tag);
906 }
907
908}(Prism));
909
910
911/* **********************************************
912 Begin prism-clike.js
913********************************************** */
914
915Prism.languages.clike = {
916 'comment': [
917 {
918 pattern: /(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,
919 lookbehind: true
920 },
921 {
922 pattern: /(^|[^\\:])\/\/.*/,
923 lookbehind: true,
924 greedy: true
925 }
926 ],
927 'string': {
928 pattern: /(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,
929 greedy: true
930 },
931 'class-name': {
932 pattern: /(\b(?:class|interface|extends|implements|trait|instanceof|new)\s+|\bcatch\s+\()[\w.\\]+/i,
933 lookbehind: true,
934 inside: {
935 'punctuation': /[.\\]/
936 }
937 },
938 'keyword': /\b(?:if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/,
939 'boolean': /\b(?:true|false)\b/,
940 'function': /\w+(?=\()/,
941 'number': /\b0x[\da-f]+\b|(?:\b\d+\.?\d*|\B\.\d+)(?:e[+-]?\d+)?/i,
942 'operator': /[<>]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,
943 'punctuation': /[{}[\];(),.:]/
944};
945
946
947/* **********************************************
948 Begin prism-javascript.js
949********************************************** */
950
951Prism.languages.javascript = Prism.languages.extend('clike', {
952 'class-name': [
953 Prism.languages.clike['class-name'],
954 {
955 pattern: /(^|[^$\w\xA0-\uFFFF])[_$A-Z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\.(?:prototype|constructor))/,
956 lookbehind: true
957 }
958 ],
959 'keyword': [
960 {
961 pattern: /((?:^|})\s*)(?:catch|finally)\b/,
962 lookbehind: true
963 },
964 {
965 pattern: /(^|[^.]|\.\.\.\s*)\b(?:as|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|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)\b/,
966 lookbehind: true
967 },
968 ],
969 'number': /\b(?:(?:0[xX](?:[\dA-Fa-f](?:_[\dA-Fa-f])?)+|0[bB](?:[01](?:_[01])?)+|0[oO](?:[0-7](?:_[0-7])?)+)n?|(?:\d(?:_\d)?)+n|NaN|Infinity)\b|(?:\b(?:\d(?:_\d)?)+\.?(?:\d(?:_\d)?)*|\B\.(?:\d(?:_\d)?)+)(?:[Ee][+-]?(?:\d(?:_\d)?)+)?/,
970 // Allow for all non-ASCII characters (See http://stackoverflow.com/a/2008444)
971 'function': /#?[_$a-zA-Z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,
972 'operator': /--|\+\+|\*\*=?|=>|&&|\|\||[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?[.?]?|[~:]/
973});
974
975Prism.languages.javascript['class-name'][0].pattern = /(\b(?:class|interface|extends|implements|instanceof|new)\s+)[\w.\\]+/;
976
977Prism.languages.insertBefore('javascript', 'keyword', {
978 'regex': {
979 pattern: /((?:^|[^$\w\xA0-\uFFFF."'\])\s])\s*)\/(?:\[(?:[^\]\\\r\n]|\\.)*]|\\.|[^/\\\[\r\n])+\/[gimyus]{0,6}(?=(?:\s|\/\*[\s\S]*?\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/,
980 lookbehind: true,
981 greedy: true
982 },
983 // This must be declared before keyword because we use "function" inside the look-forward
984 'function-variable': {
985 pattern: /#?[_$a-zA-Z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|[_$a-zA-Z\xA0-\uFFFF][$\w\xA0-\uFFFF]*)\s*=>))/,
986 alias: 'function'
987 },
988 'parameter': [
989 {
990 pattern: /(function(?:\s+[_$A-Za-z\xA0-\uFFFF][$\w\xA0-\uFFFF]*)?\s*\(\s*)(?!\s)(?:[^()]|\([^()]*\))+?(?=\s*\))/,
991 lookbehind: true,
992 inside: Prism.languages.javascript
993 },
994 {
995 pattern: /[_$a-z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\s*=>)/i,
996 inside: Prism.languages.javascript
997 },
998 {
999 pattern: /(\(\s*)(?!\s)(?:[^()]|\([^()]*\))+?(?=\s*\)\s*=>)/,
1000 lookbehind: true,
1001 inside: Prism.languages.javascript
1002 },
1003 {
1004 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]))(?:[_$A-Za-z\xA0-\uFFFF][$\w\xA0-\uFFFF]*\s*)\(\s*)(?!\s)(?:[^()]|\([^()]*\))+?(?=\s*\)\s*\{)/,
1005 lookbehind: true,
1006 inside: Prism.languages.javascript
1007 }
1008 ],
1009 'constant': /\b[A-Z](?:[A-Z_]|\dx?)*\b/
1010});
1011
1012Prism.languages.insertBefore('javascript', 'string', {
1013 'template-string': {
1014 pattern: /`(?:\\[\s\S]|\${(?:[^{}]|{(?:[^{}]|{[^}]*})*})+}|(?!\${)[^\\`])*`/,
1015 greedy: true,
1016 inside: {
1017 'template-punctuation': {
1018 pattern: /^`|`$/,
1019 alias: 'string'
1020 },
1021 'interpolation': {
1022 pattern: /((?:^|[^\\])(?:\\{2})*)\${(?:[^{}]|{(?:[^{}]|{[^}]*})*})+}/,
1023 lookbehind: true,
1024 inside: {
1025 'interpolation-punctuation': {
1026 pattern: /^\${|}$/,
1027 alias: 'punctuation'
1028 },
1029 rest: Prism.languages.javascript
1030 }
1031 },
1032 'string': /[\s\S]+/
1033 }
1034 }
1035});
1036
1037if (Prism.languages.markup) {
1038 Prism.languages.markup.tag.addInlined('script', 'javascript');
1039}
1040
1041Prism.languages.js = Prism.languages.javascript;
1042
1043
1044/* **********************************************
1045 Begin prism-file-highlight.js
1046********************************************** */
1047
1048(function () {
1049 if (typeof self === 'undefined' || !self.Prism || !self.document || !document.querySelector) {
1050 return;
1051 }
1052
1053 /**
1054 * @param {Element} [container=document]
1055 */
1056 self.Prism.fileHighlight = function(container) {
1057 container = container || document;
1058
1059 var Extensions = {
1060 'js': 'javascript',
1061 'py': 'python',
1062 'rb': 'ruby',
1063 'ps1': 'powershell',
1064 'psm1': 'powershell',
1065 'sh': 'bash',
1066 'bat': 'batch',
1067 'h': 'c',
1068 'tex': 'latex'
1069 };
1070
1071 Array.prototype.slice.call(container.querySelectorAll('pre[data-src]')).forEach(function (pre) {
1072 // ignore if already loaded
1073 if (pre.hasAttribute('data-src-loaded')) {
1074 return;
1075 }
1076
1077 // load current
1078 var src = pre.getAttribute('data-src');
1079
1080 var language, parent = pre;
1081 var lang = /\blang(?:uage)?-([\w-]+)\b/i;
1082 while (parent && !lang.test(parent.className)) {
1083 parent = parent.parentNode;
1084 }
1085
1086 if (parent) {
1087 language = (pre.className.match(lang) || [, ''])[1];
1088 }
1089
1090 if (!language) {
1091 var extension = (src.match(/\.(\w+)$/) || [, ''])[1];
1092 language = Extensions[extension] || extension;
1093 }
1094
1095 var code = document.createElement('code');
1096 code.className = 'language-' + language;
1097
1098 pre.textContent = '';
1099
1100 code.textContent = 'Loading…';
1101
1102 pre.appendChild(code);
1103
1104 var xhr = new XMLHttpRequest();
1105
1106 xhr.open('GET', src, true);
1107
1108 xhr.onreadystatechange = function () {
1109 if (xhr.readyState == 4) {
1110
1111 if (xhr.status < 400 && xhr.responseText) {
1112 code.textContent = xhr.responseText;
1113
1114 Prism.highlightElement(code);
1115 // mark as loaded
1116 pre.setAttribute('data-src-loaded', '');
1117 }
1118 else if (xhr.status >= 400) {
1119 code.textContent = '✖ Error ' + xhr.status + ' while fetching file: ' + xhr.statusText;
1120 }
1121 else {
1122 code.textContent = '✖ Error: File does not exist or is empty';
1123 }
1124 }
1125 };
1126
1127 xhr.send(null);
1128 });
1129 };
1130
1131 document.addEventListener('DOMContentLoaded', function () {
1132 // execute inside handler, for dropping Event as argument
1133 self.Prism.fileHighlight();
1134 });
1135
1136})();