/* http://prismjs.com/download.html?themes=prism&languages=markup+css+clike+javascript+php+coffeescript+c+cpp+python+ruby */ /** * Prism: Lightweight, robust, elegant syntax highlighting * MIT license http://www.opensource.org/licenses/mit-license.php/ * @author Lea Verou http://lea.verou.me */ var Prism = (function(){ // Private helper vars var lang = /\blang(?:uage)?-(?!\*)(\w+)\b/i; var _ = self.Prism = { util: { encode: function (tokens) { if (tokens instanceof Token) { return new Token(tokens.type, _.util.encode(tokens.content), tokens.alias); } else if (_.util.type(tokens) === 'Array') { return tokens.map(_.util.encode); } else { return tokens.replace(/&/g, '&').replace(/ text.length) { // Something went terribly wrong, ABORT, ABORT! break tokenloop; } if (str instanceof Token) { continue; } pattern.lastIndex = 0; var match = pattern.exec(str); if (match) { if(lookbehind) { lookbehindLength = match[1].length; } var from = match.index - 1 + lookbehindLength, match = match[0].slice(lookbehindLength), len = match.length, to = from + len, before = str.slice(0, from + 1), after = str.slice(to + 1); var args = [i, 1]; if (before) { args.push(before); } var wrapped = new Token(token, inside? _.tokenize(match, inside) : match, alias); args.push(wrapped); if (after) { args.push(after); } Array.prototype.splice.apply(strarr, args); } } } } return strarr; }, hooks: { all: {}, add: function (name, callback) { var hooks = _.hooks.all; hooks[name] = hooks[name] || []; hooks[name].push(callback); }, run: function (name, env) { var callbacks = _.hooks.all[name]; if (!callbacks || !callbacks.length) { return; } for (var i=0, callback; callback = callbacks[i++];) { callback(env); } } } }; var Token = _.Token = function(type, content, alias) { this.type = type; this.content = content; this.alias = alias; }; Token.stringify = function(o, language, parent) { if (typeof o == 'string') { return o; } if (Object.prototype.toString.call(o) == '[object Array]') { return o.map(function(element) { return Token.stringify(element, language, o); }).join(''); } var env = { type: o.type, content: Token.stringify(o.content, language, parent), tag: 'span', classes: ['token', o.type], attributes: {}, language: language, parent: parent }; if (env.type == 'comment') { env.attributes['spellcheck'] = 'true'; } if (o.alias) { var aliases = _.util.type(o.alias) === 'Array' ? o.alias : [o.alias]; Array.prototype.push.apply(env.classes, aliases); } _.hooks.run('wrap', env); var attributes = ''; for (var name in env.attributes) { attributes += name + '="' + (env.attributes[name] || '') + '"'; } return '<' + env.tag + ' class="' + env.classes.join(' ') + '" ' + attributes + '>' + env.content + ''; }; // if (!self.document) { // if (!self.addEventListener) { // // in Node.js // return self.Prism; // } // // In worker // self.addEventListener('message', function(evt) { // var message = JSON.parse(evt.data), // lang = message.language, // code = message.code; // self.postMessage(JSON.stringify(_.util.encode(_.tokenize(code, _.languages[lang])))); // self.close(); // }, false); // return self.Prism; // } // Get current script and highlight // var script = document.getElementsByTagName('script'); // script = script[script.length - 1]; // if (script) { // _.filename = script.src; // if (document.addEventListener && !script.hasAttribute('data-manual')) { // document.addEventListener('DOMContentLoaded', _.highlightAll); // } // } return self.Prism; })(); // if (typeof module !== 'undefined' && module.exports) { // module.exports = Prism; // } // ; Prism.languages.markup = { 'comment': //g, 'prolog': /<\?.+?\?>/, 'doctype': //, 'cdata': //i, 'tag': { pattern: /<\/?[\w:-]+\s*(?:\s+[\w:-]+(?:=(?:("|')(\\?[\w\W])*?\1|[^\s'">=]+))?\s*)*\/?>/gi, inside: { 'tag': { pattern: /^<\/?[\w:-]+/i, inside: { 'punctuation': /^<\/?/, 'namespace': /^[\w-]+?:/ } }, 'attr-value': { pattern: /=(?:('|")[\w\W]*?(\1)|[^\s>]+)/gi, inside: { 'punctuation': /=|>|"/g } }, 'punctuation': /\/?>/g, 'attr-name': { pattern: /[\w:-]+/g, inside: { 'namespace': /^[\w-]+?:/ } } } }, 'entity': /\&#?[\da-z]{1,8};/gi }; // Plugin to make entity title show the real entity, idea by Roman Komarov Prism.hooks.add('wrap', function(env) { if (env.type === 'entity') { env.attributes['title'] = env.content.replace(/&/, '&'); } }); ; Prism.languages.css = { 'comment': /\/\*[\w\W]*?\*\//g, 'atrule': { pattern: /@[\w-]+?.*?(;|(?=\s*{))/gi, inside: { 'punctuation': /[;:]/g } }, 'url': /url\((["']?).*?\1\)/gi, 'selector': /[^\{\}\s][^\{\};]*(?=\s*\{)/g, 'property': /(\b|\B)[\w-]+(?=\s*:)/ig, 'string': /("|')(\\?.)*?\1/g, 'important': /\B!important\b/gi, 'punctuation': /[\{\};:]/g, 'function': /[-a-z0-9]+(?=\()/ig }; if (Prism.languages.markup) { Prism.languages.insertBefore('markup', 'tag', { 'style': { pattern: /[\w\W]*?<\/style>/ig, inside: { 'tag': { pattern: /|<\/style>/ig, inside: Prism.languages.markup.tag.inside }, rest: Prism.languages.css }, alias: 'language-css' } }); Prism.languages.insertBefore('inside', 'attr-value', { 'style-attr': { pattern: /\s*style=("|').+?\1/ig, inside: { 'attr-name': { pattern: /^\s*style/ig, inside: Prism.languages.markup.tag.inside }, 'punctuation': /^\s*=\s*['"]|['"]\s*$/, 'attr-value': { pattern: /.+/gi, inside: Prism.languages.css } }, alias: 'language-css' } }, Prism.languages.markup.tag); }; Prism.languages.clike = { 'comment': [ { pattern: /(^|[^\\])\/\*[\w\W]*?\*\//g, lookbehind: true }, { pattern: /(^|[^\\:])\/\/.*?(\r?\n|$)/g, lookbehind: true } ], 'string': /("|')(\\?.)*?\1/g, 'class-name': { pattern: /((?:(?:class|interface|extends|implements|trait|instanceof|new)\s+)|(?:catch\s+\())[a-z0-9_\.\\]+/ig, lookbehind: true, inside: { punctuation: /(\.|\\)/ } }, 'keyword': /\b(if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/g, 'boolean': /\b(true|false)\b/g, 'function': { pattern: /[a-z0-9_]+\(/ig, inside: { punctuation: /\(/ } }, 'number': /\b-?(0x[\dA-Fa-f]+|\d*\.?\d+([Ee]-?\d+)?)\b/g, 'operator': /[-+]{1,2}|!|<=?|>=?|={1,3}|&{1,2}|\|?\||\?|\*|\/|\~|\^|\%/g, 'ignore': /&(lt|gt|amp);/gi, 'punctuation': /[{}[\];(),.:]/g }; ; Prism.languages.javascript = Prism.languages.extend('clike', { 'keyword': /\b(break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|false|finally|for|function|get|if|implements|import|in|instanceof|interface|let|new|null|package|private|protected|public|return|set|static|super|switch|this|throw|true|try|typeof|var|void|while|with|yield)\b/g, 'number': /\b-?(0x[\dA-Fa-f]+|\d*\.?\d+([Ee]-?\d+)?|NaN|-?Infinity)\b/g }); Prism.languages.insertBefore('javascript', 'keyword', { 'regex': { pattern: /(^|[^/])\/(?!\/)(\[.+?]|\\.|[^/\r\n])+\/[gim]{0,3}(?=\s*($|[\r\n,.;})]))/g, lookbehind: true } }); if (Prism.languages.markup) { Prism.languages.insertBefore('markup', 'tag', { 'script': { pattern: /[\w\W]*?<\/script>/ig, inside: { 'tag': { pattern: /|<\/script>/ig, inside: Prism.languages.markup.tag.inside }, rest: Prism.languages.javascript }, alias: 'language-javascript' } }); } ; /** * Original by Aaron Harun: http://aahacreative.com/2012/07/31/php-syntax-highlighting-prism/ * Modified by Miles Johnson: http://milesj.me * * Supports the following: * - Extends clike syntax * - Support for PHP 5.3+ (namespaces, traits, generators, etc) * - Smarter constant and function matching * * Adds the following new token classes: * constant, delimiter, variable, function, package */ Prism.languages.php = Prism.languages.extend('clike', { 'keyword': /\b(and|or|xor|array|as|break|case|cfunction|class|const|continue|declare|default|die|do|else|elseif|enddeclare|endfor|endforeach|endif|endswitch|endwhile|extends|for|foreach|function|include|include_once|global|if|new|return|static|switch|use|require|require_once|var|while|abstract|interface|public|implements|private|protected|parent|throw|null|echo|print|trait|namespace|final|yield|goto|instanceof|finally|try|catch)\b/ig, 'constant': /\b[A-Z0-9_]{2,}\b/g, 'comment': { pattern: /(^|[^\\])(\/\*[\w\W]*?\*\/|(^|[^:])(\/\/|#).*?(\r?\n|$))/g, lookbehind: true } }); Prism.languages.insertBefore('php', 'keyword', { 'delimiter': /(\?>|<\?php|<\?)/ig, 'variable': /(\$\w+)\b/ig, 'package': { pattern: /(\\|namespace\s+|use\s+)[\w\\]+/g, lookbehind: true, inside: { punctuation: /\\/ } } }); // Must be defined after the function pattern Prism.languages.insertBefore('php', 'operator', { 'property': { pattern: /(->)[\w]+/g, lookbehind: true } }); // Add HTML support of the markup language exists if (Prism.languages.markup) { // Tokenize all inline PHP blocks that are wrapped in // This allows for easy PHP + markup highlighting Prism.hooks.add('before-highlight', function(env) { if (env.language !== 'php') { return; } env.tokenStack = []; env.backupCode = env.code; env.code = env.code.replace(/(?:<\?php|<\?)[\w\W]*?(?:\?>)/ig, function(match) { env.tokenStack.push(match); return '{{{PHP' + env.tokenStack.length + '}}}'; }); }); // Restore env.code for other plugins (e.g. line-numbers) Prism.hooks.add('before-insert', function(env) { if (env.language === 'php') { env.code = env.backupCode; delete env.backupCode; } }); // Re-insert the tokens after highlighting Prism.hooks.add('after-highlight', function(env) { if (env.language !== 'php') { return; } for (var i = 0, t; t = env.tokenStack[i]; i++) { env.highlightedCode = env.highlightedCode.replace('{{{PHP' + (i + 1) + '}}}', Prism.highlight(t, env.grammar, 'php')); } env.element.innerHTML = env.highlightedCode; }); // Wrap tokens in classes that are missing them Prism.hooks.add('wrap', function(env) { if (env.language === 'php' && env.type === 'markup') { env.content = env.content.replace(/(\{\{\{PHP[0-9]+\}\}\})/g, "$1"); } }); // Add the rules before all others Prism.languages.insertBefore('php', 'comment', { 'markup': { pattern: /<[^?]\/?(.*?)>/g, inside: Prism.languages.markup }, 'php': /\{\{\{PHP[0-9]+\}\}\}/g }); } ; Prism.languages.coffeescript = Prism.languages.extend('javascript', { 'comment': [ /([#]{3}\s*\r?\n(.*\s*\r*\n*)\s*?\r?\n[#]{3})/g, /(\s|^)([#]{1}[^#^\r^\n]{2,}?(\r?\n|$))/g ], 'keyword': /\b(this|window|delete|class|extends|namespace|extend|ar|let|if|else|while|do|for|each|of|return|in|instanceof|new|with|typeof|try|catch|finally|null|undefined|break|continue)\b/g }); Prism.languages.insertBefore('coffeescript', 'keyword', { 'function': { pattern: /[a-z|A-z]+\s*[:|=]\s*(\([.|a-z\s|,|:|{|}|\"|\'|=]*\))?\s*->/gi, inside: { 'function-name': /[_?a-z-|A-Z-]+(\s*[:|=])| @[_?$?a-z-|A-Z-]+(\s*)| /g, 'operator': /[-+]{1,2}|!|=?<|=?>|={1,2}|(&){1,2}|\|?\||\?|\*|\//g } }, 'attr-name': /[_?a-z-|A-Z-]+(\s*:)| @[_?$?a-z-|A-Z-]+(\s*)| /g }); ; Prism.languages.c = Prism.languages.extend('clike', { // allow for c multiline strings 'string': /("|')([^\n\\\1]|\\.|\\\r*\n)*?\1/g, 'keyword': /\b(asm|typeof|inline|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|int|long|register|return|short|signed|sizeof|static|struct|switch|typedef|union|unsigned|void|volatile|while)\b/g, 'operator': /[-+]{1,2}|!=?|<{1,2}=?|>{1,2}=?|\->|={1,2}|\^|~|%|&{1,2}|\|?\||\?|\*|\//g }); Prism.languages.insertBefore('c', 'string', { // property class reused for macro statements 'property': { // allow for multiline macro definitions // spaces after the # character compile fine with gcc pattern: /((^|\n)\s*)#\s*[a-z]+([^\n\\]|\\.|\\\r*\n)*/gi, lookbehind: true, inside: { // highlight the path of the include statement as a string 'string': { pattern: /(#\s*include\s*)(<.+?>|("|')(\\?.)+?\3)/g, lookbehind: true, } } } }); delete Prism.languages.c['class-name']; delete Prism.languages.c['boolean'];; Prism.languages.cpp = Prism.languages.extend('c', { 'keyword': /\b(alignas|alignof|asm|auto|bool|break|case|catch|char|char16_t|char32_t|class|compl|const|constexpr|const_cast|continue|decltype|default|delete|delete\[\]|do|double|dynamic_cast|else|enum|explicit|export|extern|float|for|friend|goto|if|inline|int|long|mutable|namespace|new|new\[\]|noexcept|nullptr|operator|private|protected|public|register|reinterpret_cast|return|short|signed|sizeof|static|static_assert|static_cast|struct|switch|template|this|thread_local|throw|try|typedef|typeid|typename|union|unsigned|using|virtual|void|volatile|wchar_t|while)\b/g, 'boolean': /\b(true|false)\b/g, 'operator': /[-+]{1,2}|!=?|<{1,2}=?|>{1,2}=?|\->|:{1,2}|={1,2}|\^|~|%|&{1,2}|\|?\||\?|\*|\/|\b(and|and_eq|bitand|bitor|not|not_eq|or|or_eq|xor|xor_eq)\b/g }); Prism.languages.insertBefore('cpp', 'keyword', { 'class-name': { pattern: /(class\s+)[a-z0-9_]+/ig, lookbehind: true, }, });; Prism.languages.python= { 'comment': { pattern: /(^|[^\\])#.*?(\r?\n|$)/g, lookbehind: true }, 'string': /"""[\s\S]+?"""|("|')(\\?.)*?\1/g, 'keyword' : /\b(as|assert|break|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|pass|print|raise|return|try|while|with|yield)\b/g, 'boolean' : /\b(True|False)\b/g, 'number' : /\b-?(0x)?\d*\.?[\da-f]+\b/g, 'operator' : /[-+]{1,2}|=?<|=?>|!|={1,2}|(&){1,2}|(&){1,2}|\|?\||\?|\*|\/|~|\^|%|\b(or|and|not)\b/g, 'ignore' : /&(lt|gt|amp);/gi, 'punctuation' : /[{}[\];(),.:]/g }; ; /** * Original by Samuel Flores * * Adds the following new token classes: * constant, builtin, variable, symbol, regex */ Prism.languages.ruby = Prism.languages.extend('clike', { 'comment': /#[^\r\n]*(\r?\n|$)/g, 'keyword': /\b(alias|and|BEGIN|begin|break|case|class|def|define_method|defined|do|each|else|elsif|END|end|ensure|false|for|if|in|module|new|next|nil|not|or|raise|redo|require|rescue|retry|return|self|super|then|throw|true|undef|unless|until|when|while|yield)\b/g, 'builtin': /\b(Array|Bignum|Binding|Class|Continuation|Dir|Exception|FalseClass|File|Stat|File|Fixnum|Fload|Hash|Integer|IO|MatchData|Method|Module|NilClass|Numeric|Object|Proc|Range|Regexp|String|Struct|TMS|Symbol|ThreadGroup|Thread|Time|TrueClass)\b/, 'constant': /\b[A-Z][a-zA-Z_0-9]*[?!]?\b/g }); Prism.languages.insertBefore('ruby', 'keyword', { 'regex': { pattern: /(^|[^/])\/(?!\/)(\[.+?]|\\.|[^/\r\n])+\/[gim]{0,3}(?=\s*($|[\r\n,.;})]))/g, lookbehind: true }, 'variable': /[@$]+\b[a-zA-Z_][a-zA-Z_0-9]*[?!]?\b/g, 'symbol': /:\b[a-zA-Z_][a-zA-Z_0-9]*[?!]?\b/g }); ;