├── Plugin.php
├── README.md
└── static
├── clipboard.min.js
├── prism.full.js
├── prism.js
└── styles
├── coy.css
├── dark.css
├── default.css
├── funky.css
├── okaikia.css
├── solarized-light.css
├── tomorrow-night.css
└── twilight.css
/Plugin.php:
--------------------------------------------------------------------------------
1 | 可显示语言类型、行号,有复制功能
(请勿与其它同类插件同时启用,以免互相影响)
详细说明:https://github.com/Copterfly/CodeHighlighter-for-Typecho
4 | *
5 | * @package CodeHighlighter
6 | * @author Copterfly
7 | * @version 1.0.0
8 | * @link https://www.copterfly.cn
9 | */
10 | class CodeHighlighter_Plugin implements Typecho_Plugin_Interface {
11 | /**
12 | * 激活插件方法,如果激活失败,直接抛出异常
13 | *
14 | * @access public
15 | * @return void
16 | * @throws Typecho_Plugin_Exception
17 | */
18 | public static function activate() {
19 | Typecho_Plugin::factory('Widget_Archive')->header = array(__CLASS__, 'header');
20 | Typecho_Plugin::factory('Widget_Archive')->footer = array(__CLASS__, 'footer');
21 | }
22 |
23 | /**
24 | * 禁用插件方法,如果禁用失败,直接抛出异常
25 | *
26 | * @static
27 | * @access public
28 | * @return void
29 | * @throws Typecho_Plugin_Exception
30 | */
31 | public static function deactivate(){}
32 |
33 | /**
34 | * 获取插件配置面板
35 | *
36 | * @access public
37 | * @param Typecho_Widget_Helper_Form $form 配置面板
38 | * @return void
39 | */
40 | public static function config(Typecho_Widget_Helper_Form $form){
41 | //设置代码风格样式
42 | $styles = array_map('basename', glob(dirname(__FILE__) . '/static/styles/*.css'));
43 | $styles = array_combine($styles, $styles);
44 | $name = new Typecho_Widget_Helper_Form_Element_Select('code_style', $styles, 'okaikia.css', _t('选择高亮主题风格'));
45 | $form->addInput($name->addRule('enum', _t('必须选择主题'), $styles));
46 | $showLineNumber = new Typecho_Widget_Helper_Form_Element_Checkbox('showLineNumber', array('showLineNumber' => _t('显示行号')), array('showLineNumber'), _t('是否在代码左侧显示行号'));
47 | $form->addInput($showLineNumber);
48 | }
49 |
50 | /**
51 | * 个人用户的配置面板
52 | *
53 | * @access public
54 | * @param Typecho_Widget_Helper_Form $form
55 | * @return void
56 | */
57 | public static function personalConfig(Typecho_Widget_Helper_Form $form){}
58 |
59 | /**
60 | * 插件实现方法
61 | *
62 | * @access public
63 | * @return void
64 | */
65 | public static function render() {
66 |
67 | }
68 |
69 | /**
70 | *为header添加css文件
71 | *@return void
72 | */
73 | public static function header() {
74 | $style = Helper::options()->plugin('CodeHighlighter')->code_style;
75 | $cssUrl = Helper::options()->pluginUrl . '/CodeHighlighter/static/styles/' . $style;
76 | echo '';
77 | }
78 |
79 | /**
80 | *为footer添加js文件
81 | *@return void
82 | */
83 | public static function footer() {
84 | $jsUrl = Helper::options()->pluginUrl . '/CodeHighlighter/static/prism.js';
85 | $jsUrl_clipboard = Helper::options()->pluginUrl . '/CodeHighlighter/static/clipboard.min.js';
86 | $showLineNumber = Helper::options()->plugin('CodeHighlighter')->showLineNumber;
87 | if ($showLineNumber) {
88 | echo <<
90 | (function(){
91 | var pres = document.querySelectorAll('pre');
92 | var lineNumberClassName = 'line-numbers';
93 | pres.forEach(function (item, index) {
94 | item.className = item.className == '' ? lineNumberClassName : item.className + ' ' + lineNumberClassName;
95 | });
96 | })();
97 |
98 |
99 | HTML;
100 | }
101 | echo <<
103 |
104 |
105 | HTML;
106 | }
107 | }
108 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # CodeHighlighter-for-Typecho
2 |
3 | 基于 prismjs 的代码语法高亮插件 for Typecho,可显示语言类型、行号,有复制代码到剪切板功能。
4 |
5 | github开源地址:[https://github.com/Copterfly/CodeHighlighter-for-Typecho][1]
6 |
7 | ## 起始
8 |
9 | 本插件是基于 [prismjs][2] 的 `Typecho` 代码语法高亮显示插件。( Typecho 1.1版可用,其它版本请自行尝试)
10 |
11 | 可显示语言类型、行号,有复制功能。(请勿与其它同类插件同时启用,以免互相影响)
12 |
13 | ## 使用方法
14 |
15 | 第 1 步:下载本插件,解压,放到 `usr/plugins/` 目录中;
16 |
17 | 第 2 步:文件夹名改为 `CodeHighlighter`;
18 |
19 | 第 3 步:登录管理后台,激活插件;
20 |
21 | 第 4 步:设置:选择主题风格,是否显示行号等。
22 |
23 | **代码写法**
24 |
25 | ```
26 | '''javascript (语言类型必填)
27 | // codes go here
28 | '''
29 | ```
30 |
31 | **高亮效果图**
32 |
33 | ![代码高亮.png][3]
34 |
35 | ## 重要说明
36 |
37 | ### 可设置项
38 |
39 | **1. 选择高亮主题风格** (官方提供的 8 种风格切换)
40 |
41 | - coy.css
42 | - dark.css
43 | - default.css
44 | - funky.css
45 | - okaikia.css (默认选中,因为比较顺眼)
46 | - solarized-light.css
47 | - tomorrow-night.css
48 | - twilight.css
49 |
50 | **2. 是否在代码左侧显示行号** (默认开启)
51 |
52 | ### 在插件中不方便实现的设置项
53 |
54 | 由于 `prismjs` 与 `highlightjs` 的插件扩展机制不同,所以本插件的有些扩展项是无法设置的。
55 |
56 | 本插件支持常见的一些语言高亮。您可以打开以下链接查看详情:
57 |
58 | [http://prismjs.com/download.html#themes=prism-okaidia&languages=markup+css+clike+javascript+apacheconf+c+aspnet+bash+cpp+csharp+coffeescript+markup-templating+git+java+less+markdown+nginx+php+sql+python+smarty&plugins=line-numbers+toolbar+show-language+copy-to-clipboard][4]
59 |
60 | 如有需要,请勾选需要支持的语言定制您的 js 和 css 文件,下载好后,分别替换以下文件:
61 |
62 | `Typecho 插件目录\CodeHighlighter\static\prism.js`
63 |
64 | `Typecho 插件目录\CodeHighlighter\static\styles\改为对应的风格名.css` (如跟您博客样式有冲突,稍作修改此 `css` 即可)
65 |
66 | **建议**
67 |
68 | 插件 `Plugins` 最好至少勾选以下 4 项:
69 |
70 | - Line Numbers (在代码左侧显示行号)
71 | - Toolbar (代码块右上方工具条)
72 | - Show Language (显示代码是什么语言【依赖: Toolbar】)
73 | - Copy to Clipboard Button (复制代码功能【依赖: Toolbar】)
74 |
75 | ## 与我联系
76 |
77 | 作者:Copterfly
78 |
79 | 有问题请到博客留言交流:[http://www.copterfly.cn/server-side/php/typecho-code-highlighter.html][5]
80 |
81 |
82 | [1]: https://github.com/Copterfly/CodeHighlighter-for-Typecho
83 | [2]: http://prismjs.com/
84 | [3]: http://www.copterfly.cn/usr/uploads/2018/05/2713638326.png
85 | [4]: http://prismjs.com/download.html#themes=prism-okaidia&languages=markup+css+clike+javascript+apacheconf+c+aspnet+bash+cpp+csharp+coffeescript+markup-templating+git+java+less+markdown+nginx+php+sql+python+smarty&plugins=line-numbers+toolbar+show-language+copy-to-clipboard
86 | [5]: http://www.copterfly.cn/server-side/php/typecho-code-highlighter.html
87 |
--------------------------------------------------------------------------------
/static/clipboard.min.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * clipboard.js v2.0.0
3 | * https://zenorocha.github.io/clipboard.js
4 | *
5 | * Licensed MIT © Zeno Rocha
6 | */
7 | !function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.ClipboardJS=e():t.ClipboardJS=e()}(this,function(){return function(t){function e(o){if(n[o])return n[o].exports;var r=n[o]={i:o,l:!1,exports:{}};return t[o].call(r.exports,r,r.exports,e),r.l=!0,r.exports}var n={};return e.m=t,e.c=n,e.i=function(t){return t},e.d=function(t,n,o){e.o(t,n)||Object.defineProperty(t,n,{configurable:!1,enumerable:!0,get:o})},e.n=function(t){var n=t&&t.__esModule?function(){return t.default}:function(){return t};return e.d(n,"a",n),n},e.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},e.p="",e(e.s=3)}([function(t,e,n){var o,r,i;!function(a,c){r=[t,n(7)],o=c,void 0!==(i="function"==typeof o?o.apply(e,r):o)&&(t.exports=i)}(0,function(t,e){"use strict";function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}var o=function(t){return t&&t.__esModule?t:{default:t}}(e),r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},i=function(){function t(t,e){for(var n=0;n0&&void 0!==arguments[0]?arguments[0]:{};this.action=t.action,this.container=t.container,this.emitter=t.emitter,this.target=t.target,this.text=t.text,this.trigger=t.trigger,this.selectedText=""}},{key:"initSelection",value:function(){this.text?this.selectFake():this.target&&this.selectTarget()}},{key:"selectFake",value:function(){var t=this,e="rtl"==document.documentElement.getAttribute("dir");this.removeFake(),this.fakeHandlerCallback=function(){return t.removeFake()},this.fakeHandler=this.container.addEventListener("click",this.fakeHandlerCallback)||!0,this.fakeElem=document.createElement("textarea"),this.fakeElem.style.fontSize="12pt",this.fakeElem.style.border="0",this.fakeElem.style.padding="0",this.fakeElem.style.margin="0",this.fakeElem.style.position="absolute",this.fakeElem.style[e?"right":"left"]="-9999px";var n=window.pageYOffset||document.documentElement.scrollTop;this.fakeElem.style.top=n+"px",this.fakeElem.setAttribute("readonly",""),this.fakeElem.value=this.text,this.container.appendChild(this.fakeElem),this.selectedText=(0,o.default)(this.fakeElem),this.copyText()}},{key:"removeFake",value:function(){this.fakeHandler&&(this.container.removeEventListener("click",this.fakeHandlerCallback),this.fakeHandler=null,this.fakeHandlerCallback=null),this.fakeElem&&(this.container.removeChild(this.fakeElem),this.fakeElem=null)}},{key:"selectTarget",value:function(){this.selectedText=(0,o.default)(this.target),this.copyText()}},{key:"copyText",value:function(){var t=void 0;try{t=document.execCommand(this.action)}catch(e){t=!1}this.handleResult(t)}},{key:"handleResult",value:function(t){this.emitter.emit(t?"success":"error",{action:this.action,text:this.selectedText,trigger:this.trigger,clearSelection:this.clearSelection.bind(this)})}},{key:"clearSelection",value:function(){this.trigger&&this.trigger.focus(),window.getSelection().removeAllRanges()}},{key:"destroy",value:function(){this.removeFake()}},{key:"action",set:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"copy";if(this._action=t,"copy"!==this._action&&"cut"!==this._action)throw new Error('Invalid "action" value, use either "copy" or "cut"')},get:function(){return this._action}},{key:"target",set:function(t){if(void 0!==t){if(!t||"object"!==(void 0===t?"undefined":r(t))||1!==t.nodeType)throw new Error('Invalid "target" value, use a valid Element');if("copy"===this.action&&t.hasAttribute("disabled"))throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute');if("cut"===this.action&&(t.hasAttribute("readonly")||t.hasAttribute("disabled")))throw new Error('Invalid "target" attribute. You can\'t cut text from elements with "readonly" or "disabled" attributes');this._target=t}},get:function(){return this._target}}]),t}();t.exports=a})},function(t,e,n){function o(t,e,n){if(!t&&!e&&!n)throw new Error("Missing required arguments");if(!c.string(e))throw new TypeError("Second argument must be a String");if(!c.fn(n))throw new TypeError("Third argument must be a Function");if(c.node(t))return r(t,e,n);if(c.nodeList(t))return i(t,e,n);if(c.string(t))return a(t,e,n);throw new TypeError("First argument must be a String, HTMLElement, HTMLCollection, or NodeList")}function r(t,e,n){return t.addEventListener(e,n),{destroy:function(){t.removeEventListener(e,n)}}}function i(t,e,n){return Array.prototype.forEach.call(t,function(t){t.addEventListener(e,n)}),{destroy:function(){Array.prototype.forEach.call(t,function(t){t.removeEventListener(e,n)})}}}function a(t,e,n){return u(document.body,t,e,n)}var c=n(6),u=n(5);t.exports=o},function(t,e){function n(){}n.prototype={on:function(t,e,n){var o=this.e||(this.e={});return(o[t]||(o[t]=[])).push({fn:e,ctx:n}),this},once:function(t,e,n){function o(){r.off(t,o),e.apply(n,arguments)}var r=this;return o._=e,this.on(t,o,n)},emit:function(t){var e=[].slice.call(arguments,1),n=((this.e||(this.e={}))[t]||[]).slice(),o=0,r=n.length;for(o;o0&&void 0!==arguments[0]?arguments[0]:{};this.action="function"==typeof t.action?t.action:this.defaultAction,this.target="function"==typeof t.target?t.target:this.defaultTarget,this.text="function"==typeof t.text?t.text:this.defaultText,this.container="object"===d(t.container)?t.container:document.body}},{key:"listenClick",value:function(t){var e=this;this.listener=(0,f.default)(t,"click",function(t){return e.onClick(t)})}},{key:"onClick",value:function(t){var e=t.delegateTarget||t.currentTarget;this.clipboardAction&&(this.clipboardAction=null),this.clipboardAction=new l.default({action:this.action(e),target:this.target(e),text:this.text(e),container:this.container,trigger:e,emitter:this})}},{key:"defaultAction",value:function(t){return u("action",t)}},{key:"defaultTarget",value:function(t){var e=u("target",t);if(e)return document.querySelector(e)}},{key:"defaultText",value:function(t){return u("text",t)}},{key:"destroy",value:function(){this.listener.destroy(),this.clipboardAction&&(this.clipboardAction.destroy(),this.clipboardAction=null)}}],[{key:"isSupported",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:["copy","cut"],e="string"==typeof t?[t]:t,n=!!document.queryCommandSupported;return e.forEach(function(t){n=n&&!!document.queryCommandSupported(t)}),n}}]),e}(s.default);t.exports=p})},function(t,e){function n(t,e){for(;t&&t.nodeType!==o;){if("function"==typeof t.matches&&t.matches(e))return t;t=t.parentNode}}var o=9;if("undefined"!=typeof Element&&!Element.prototype.matches){var r=Element.prototype;r.matches=r.matchesSelector||r.mozMatchesSelector||r.msMatchesSelector||r.oMatchesSelector||r.webkitMatchesSelector}t.exports=n},function(t,e,n){function o(t,e,n,o,r){var a=i.apply(this,arguments);return t.addEventListener(n,a,r),{destroy:function(){t.removeEventListener(n,a,r)}}}function r(t,e,n,r,i){return"function"==typeof t.addEventListener?o.apply(null,arguments):"function"==typeof n?o.bind(null,document).apply(null,arguments):("string"==typeof t&&(t=document.querySelectorAll(t)),Array.prototype.map.call(t,function(t){return o(t,e,n,r,i)}))}function i(t,e,n,o){return function(n){n.delegateTarget=a(n.target,e),n.delegateTarget&&o.call(t,n)}}var a=n(4);t.exports=r},function(t,e){e.node=function(t){return void 0!==t&&t instanceof HTMLElement&&1===t.nodeType},e.nodeList=function(t){var n=Object.prototype.toString.call(t);return void 0!==t&&("[object NodeList]"===n||"[object HTMLCollection]"===n)&&"length"in t&&(0===t.length||e.node(t[0]))},e.string=function(t){return"string"==typeof t||t instanceof String},e.fn=function(t){return"[object Function]"===Object.prototype.toString.call(t)}},function(t,e){function n(t){var e;if("SELECT"===t.nodeName)t.focus(),e=t.value;else if("INPUT"===t.nodeName||"TEXTAREA"===t.nodeName){var n=t.hasAttribute("readonly");n||t.setAttribute("readonly",""),t.select(),t.setSelectionRange(0,t.value.length),n||t.removeAttribute("readonly"),e=t.value}else{t.hasAttribute("contenteditable")&&t.focus();var o=window.getSelection(),r=document.createRange();r.selectNodeContents(t),o.removeAllRanges(),o.addRange(r),e=o.toString()}return e}t.exports=n}])});
--------------------------------------------------------------------------------
/static/prism.full.js:
--------------------------------------------------------------------------------
1 | /* PrismJS 1.14.0
2 | http://prismjs.com/download.html#themes=prism-okaidia&languages=markup+css+clike+javascript+apacheconf+c+aspnet+bash+cpp+csharp+coffeescript+markup-templating+git+java+less+markdown+nginx+php+sql+python+smarty&plugins=line-numbers+toolbar+show-language+copy-to-clipboard
3 | Modified by Copterfly
4 | */
5 | var _self = (typeof window !== 'undefined')
6 | ? window // if in browser
7 | : (
8 | (typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope)
9 | ? self // if in worker
10 | : {} // if in node js
11 | );
12 |
13 | /**
14 | * Prism: Lightweight, robust, elegant syntax highlighting
15 | * MIT license http://www.opensource.org/licenses/mit-license.php/
16 | * @author Lea Verou http://lea.verou.me
17 | */
18 |
19 | var Prism = (function(){
20 |
21 | // Private helper vars
22 | var lang = /\blang(?:uage)?-([\w-]+)\b/i;
23 | var uniqueId = 0;
24 |
25 | var _ = _self.Prism = {
26 | manual: _self.Prism && _self.Prism.manual,
27 | disableWorkerMessageHandler: _self.Prism && _self.Prism.disableWorkerMessageHandler,
28 | util: {
29 | encode: function (tokens) {
30 | if (tokens instanceof Token) {
31 | return new Token(tokens.type, _.util.encode(tokens.content), tokens.alias);
32 | } else if (_.util.type(tokens) === 'Array') {
33 | return tokens.map(_.util.encode);
34 | } else {
35 | return tokens.replace(/&/g, '&').replace(/ text.length) {
327 | // Something went terribly wrong, ABORT, ABORT!
328 | return;
329 | }
330 |
331 | if (str instanceof Token) {
332 | continue;
333 | }
334 |
335 | if (greedy && i != strarr.length - 1) {
336 | pattern.lastIndex = pos;
337 | var match = pattern.exec(text);
338 | if (!match) {
339 | break;
340 | }
341 |
342 | var from = match.index + (lookbehind ? match[1].length : 0),
343 | to = match.index + match[0].length,
344 | k = i,
345 | p = pos;
346 |
347 | for (var len = strarr.length; k < len && (p < to || (!strarr[k].type && !strarr[k - 1].greedy)); ++k) {
348 | p += strarr[k].length;
349 | // Move the index i to the element in strarr that is closest to from
350 | if (from >= p) {
351 | ++i;
352 | pos = p;
353 | }
354 | }
355 |
356 | // If strarr[i] is a Token, then the match starts inside another Token, which is invalid
357 | if (strarr[i] instanceof Token) {
358 | continue;
359 | }
360 |
361 | // Number of tokens to delete and replace with the new match
362 | delNum = k - i;
363 | str = text.slice(pos, p);
364 | match.index -= pos;
365 | } else {
366 | pattern.lastIndex = 0;
367 |
368 | var match = pattern.exec(str),
369 | delNum = 1;
370 | }
371 |
372 | if (!match) {
373 | if (oneshot) {
374 | break;
375 | }
376 |
377 | continue;
378 | }
379 |
380 | if(lookbehind) {
381 | lookbehindLength = match[1] ? match[1].length : 0;
382 | }
383 |
384 | var from = match.index + lookbehindLength,
385 | match = match[0].slice(lookbehindLength),
386 | to = from + match.length,
387 | before = str.slice(0, from),
388 | after = str.slice(to);
389 |
390 | var args = [i, delNum];
391 |
392 | if (before) {
393 | ++i;
394 | pos += before.length;
395 | args.push(before);
396 | }
397 |
398 | var wrapped = new Token(token, inside? _.tokenize(match, inside) : match, alias, match, greedy);
399 |
400 | args.push(wrapped);
401 |
402 | if (after) {
403 | args.push(after);
404 | }
405 |
406 | Array.prototype.splice.apply(strarr, args);
407 |
408 | if (delNum != 1)
409 | _.matchGrammar(text, strarr, grammar, i, pos, true, token);
410 |
411 | if (oneshot)
412 | break;
413 | }
414 | }
415 | }
416 | },
417 |
418 | tokenize: function(text, grammar, language) {
419 | var strarr = [text];
420 |
421 | var rest = grammar.rest;
422 |
423 | if (rest) {
424 | for (var token in rest) {
425 | grammar[token] = rest[token];
426 | }
427 |
428 | delete grammar.rest;
429 | }
430 |
431 | _.matchGrammar(text, strarr, grammar, 0, 0, false);
432 |
433 | return strarr;
434 | },
435 |
436 | hooks: {
437 | all: {},
438 |
439 | add: function (name, callback) {
440 | var hooks = _.hooks.all;
441 |
442 | hooks[name] = hooks[name] || [];
443 |
444 | hooks[name].push(callback);
445 | },
446 |
447 | run: function (name, env) {
448 | var callbacks = _.hooks.all[name];
449 |
450 | if (!callbacks || !callbacks.length) {
451 | return;
452 | }
453 |
454 | for (var i=0, callback; callback = callbacks[i++];) {
455 | callback(env);
456 | }
457 | }
458 | }
459 | };
460 |
461 | var Token = _.Token = function(type, content, alias, matchedStr, greedy) {
462 | this.type = type;
463 | this.content = content;
464 | this.alias = alias;
465 | // Copy of the full string this token was created from
466 | this.length = (matchedStr || "").length|0;
467 | this.greedy = !!greedy;
468 | };
469 |
470 | Token.stringify = function(o, language, parent) {
471 | if (typeof o == 'string') {
472 | return o;
473 | }
474 |
475 | if (_.util.type(o) === 'Array') {
476 | return o.map(function(element) {
477 | return Token.stringify(element, language, o);
478 | }).join('');
479 | }
480 |
481 | var env = {
482 | type: o.type,
483 | content: Token.stringify(o.content, language, parent),
484 | tag: 'span',
485 | classes: ['token', o.type],
486 | attributes: {},
487 | language: language,
488 | parent: parent
489 | };
490 |
491 | if (o.alias) {
492 | var aliases = _.util.type(o.alias) === 'Array' ? o.alias : [o.alias];
493 | Array.prototype.push.apply(env.classes, aliases);
494 | }
495 |
496 | _.hooks.run('wrap', env);
497 |
498 | var attributes = Object.keys(env.attributes).map(function(name) {
499 | return name + '="' + (env.attributes[name] || '').replace(/"/g, '"') + '"';
500 | }).join(' ');
501 |
502 | return '<' + env.tag + ' class="' + env.classes.join(' ') + '"' + (attributes ? ' ' + attributes : '') + '>' + env.content + '' + env.tag + '>';
503 |
504 | };
505 |
506 | if (!_self.document) {
507 | if (!_self.addEventListener) {
508 | // in Node.js
509 | return _self.Prism;
510 | }
511 |
512 | if (!_.disableWorkerMessageHandler) {
513 | // In worker
514 | _self.addEventListener('message', function (evt) {
515 | var message = JSON.parse(evt.data),
516 | lang = message.language,
517 | code = message.code,
518 | immediateClose = message.immediateClose;
519 |
520 | _self.postMessage(_.highlight(code, _.languages[lang], lang));
521 | if (immediateClose) {
522 | _self.close();
523 | }
524 | }, false);
525 | }
526 |
527 | return _self.Prism;
528 | }
529 |
530 | //Get current script and highlight
531 | var script = document.currentScript || [].slice.call(document.getElementsByTagName("script")).pop();
532 |
533 | if (script) {
534 | _.filename = script.src;
535 |
536 | if (!_.manual && !script.hasAttribute('data-manual')) {
537 | if(document.readyState !== "loading") {
538 | if (window.requestAnimationFrame) {
539 | window.requestAnimationFrame(_.highlightAll);
540 | } else {
541 | window.setTimeout(_.highlightAll, 16);
542 | }
543 | }
544 | else {
545 | document.addEventListener('DOMContentLoaded', _.highlightAll);
546 | }
547 | }
548 | }
549 |
550 | return _self.Prism;
551 |
552 | })();
553 |
554 | if (typeof module !== 'undefined' && module.exports) {
555 | module.exports = Prism;
556 | }
557 |
558 | // hack for components to work correctly in node.js
559 | if (typeof global !== 'undefined') {
560 | global.Prism = Prism;
561 | }
562 | ;
563 | Prism.languages.markup = {
564 | 'comment': //,
565 | 'prolog': /<\?[\s\S]+?\?>/,
566 | 'doctype': //i,
567 | 'cdata': //i,
568 | 'tag': {
569 | pattern: /<\/?(?!\d)[^\s>\/=$<%]+(?:\s+[^\s>\/=]+(?:=(?:("|')(?:\\[\s\S]|(?!\1)[^\\])*\1|[^\s'">=]+))?)*\s*\/?>/i,
570 | greedy: true,
571 | inside: {
572 | 'tag': {
573 | pattern: /^<\/?[^\s>\/]+/i,
574 | inside: {
575 | 'punctuation': /^<\/?/,
576 | 'namespace': /^[^\s>\/:]+:/
577 | }
578 | },
579 | 'attr-value': {
580 | pattern: /=(?:("|')(?:\\[\s\S]|(?!\1)[^\\])*\1|[^\s'">=]+)/i,
581 | inside: {
582 | 'punctuation': [
583 | /^=/,
584 | {
585 | pattern: /(^|[^\\])["']/,
586 | lookbehind: true
587 | }
588 | ]
589 | }
590 | },
591 | 'punctuation': /\/?>/,
592 | 'attr-name': {
593 | pattern: /[^\s>\/]+/,
594 | inside: {
595 | 'namespace': /^[^\s>\/:]+:/
596 | }
597 | }
598 |
599 | }
600 | },
601 | 'entity': /?[\da-z]{1,8};/i
602 | };
603 |
604 | Prism.languages.markup['tag'].inside['attr-value'].inside['entity'] =
605 | Prism.languages.markup['entity'];
606 |
607 | // Plugin to make entity title show the real entity, idea by Roman Komarov
608 | Prism.hooks.add('wrap', function(env) {
609 |
610 | if (env.type === 'entity') {
611 | env.attributes['title'] = env.content.replace(/&/, '&');
612 | }
613 | });
614 |
615 | Prism.languages.xml = Prism.languages.markup;
616 | Prism.languages.html = Prism.languages.markup;
617 | Prism.languages.mathml = Prism.languages.markup;
618 | Prism.languages.svg = Prism.languages.markup;
619 |
620 | Prism.languages.css = {
621 | 'comment': /\/\*[\s\S]*?\*\//,
622 | 'atrule': {
623 | pattern: /@[\w-]+?.*?(?:;|(?=\s*\{))/i,
624 | inside: {
625 | 'rule': /@[\w-]+/
626 | // See rest below
627 | }
628 | },
629 | 'url': /url\((?:(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1|.*?)\)/i,
630 | 'selector': /[^{}\s][^{};]*?(?=\s*\{)/,
631 | 'string': {
632 | pattern: /("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,
633 | greedy: true
634 | },
635 | 'property': /[-_a-z\xA0-\uFFFF][-\w\xA0-\uFFFF]*(?=\s*:)/i,
636 | 'important': /\B!important\b/i,
637 | 'function': /[-a-z0-9]+(?=\()/i,
638 | 'punctuation': /[(){};:]/
639 | };
640 |
641 | Prism.languages.css['atrule'].inside.rest = Prism.languages.css;
642 |
643 | if (Prism.languages.markup) {
644 | Prism.languages.insertBefore('markup', 'tag', {
645 | 'style': {
646 | pattern: /(