|
/* http://prismjs.com/download.html?themes=prism&languages=markup+css+clike+javascript+php+coffeescript+scss+bash+c+markdown&plugins=show-invisibles+show-language */ |
|
self = (typeof window !== 'undefined') |
|
? window // if in browser |
|
: ( |
|
(typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope) |
|
? self // if in worker |
|
: {} // if in node js |
|
); |
|
|
|
/** |
|
* 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(/</g, '<').replace(/\u00a0/g, ' '); |
|
} |
|
}, |
|
|
|
type: function (o) { |
|
return Object.prototype.toString.call(o).match(/\[object (\w+)\]/)[1]; |
|
}, |
|
|
|
// Deep clone a language definition (e.g. to extend it) |
|
clone: function (o) { |
|
var type = _.util.type(o); |
|
|
|
switch (type) { |
|
case 'Object': |
|
var clone = {}; |
|
|
|
for (var key in o) { |
|
if (o.hasOwnProperty(key)) { |
|
clone[key] = _.util.clone(o[key]); |
|
} |
|
} |
|
|
|
return clone; |
|
|
|
case 'Array': |
|
return o.map(function(v) { return _.util.clone(v); }); |
|
} |
|
|
|
return o; |
|
} |
|
}, |
|
|
|
languages: { |
|
extend: function (id, redef) { |
|
var lang = _.util.clone(_.languages[id]); |
|
|
|
for (var key in redef) { |
|
lang[key] = redef[key]; |
|
} |
|
|
|
return lang; |
|
}, |
|
|
|
/** |
|
* Insert a token before another token in a language literal |
|
* As this needs to recreate the object (we cannot actually insert before keys in object literals), |
|
* we cannot just provide an object, we need anobject and a key. |
|
* @param inside The key (or language id) of the parent |
|
* @param before The key to insert before. If not provided, the function appends instead. |
|
* @param insert Object with the key/value pairs to insert |
|
* @param root The object that contains `inside`. If equal to Prism.languages, it can be omitted. |
|
*/ |
|
insertBefore: function (inside, before, insert, root) { |
|
root = root || _.languages; |
|
var grammar = root[inside]; |
|
|
|
if (arguments.length == 2) { |
|
insert = arguments[1]; |
|
|
|
for (var newToken in insert) { |
|
if (insert.hasOwnProperty(newToken)) { |
|
grammar[newToken] = insert[newToken]; |
|
} |
|
} |
|
|
|
return grammar; |
|
} |
|
|
|
var ret = {}; |
|
|
|
for (var token in grammar) { |
|
|
|
if (grammar.hasOwnProperty(token)) { |
|
|
|
if (token == before) { |
|
|
|
for (var newToken in insert) { |
|
|
|
if (insert.hasOwnProperty(newToken)) { |
|
ret[newToken] = insert[newToken]; |
|
} |
|
} |
|
} |
|
|
|
ret[token] = grammar[token]; |
|
} |
|
} |
|
|
|
// Update references in other language definitions |
|
_.languages.DFS(_.languages, function(key, value) { |
|
if (value === root[inside] && key != inside) { |
|
this[key] = ret; |
|
} |
|
}); |
|
|
|
return root[inside] = ret; |
|
}, |
|
|
|
// Traverse a language definition with Depth First Search |
|
DFS: function(o, callback, type) { |
|
for (var i in o) { |
|
if (o.hasOwnProperty(i)) { |
|
callback.call(o, i, o[i], type || i); |
|
|
|
if (_.util.type(o[i]) === 'Object') { |
|
_.languages.DFS(o[i], callback); |
|
} |
|
else if (_.util.type(o[i]) === 'Array') { |
|
_.languages.DFS(o[i], callback, i); |
|
} |
|
} |
|
} |
|
} |
|
}, |
|
|
|
highlightAll: function(async, callback) { |
|
var elements = document.querySelectorAll('code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code'); |
|
|
|
for (var i=0, element; element = elements[i++];) { |
|
_.highlightElement(element, async === true, callback); |
|
} |
|
}, |
|
|
|
highlightElement: function(element, async, callback) { |
|
// Find language |
|
var language, grammar, parent = element; |
|
|
|
while (parent && !lang.test(parent.className)) { |
|
parent = parent.parentNode; |
|
} |
|
|
|
if (parent) { |
|
language = (parent.className.match(lang) || [,''])[1]; |
|
grammar = _.languages[language]; |
|
} |
|
|
|
if (!grammar) { |
|
return; |
|
} |
|
|
|
// Set language on the element, if not present |
|
element.className = element.className.replace(lang, '').replace(/\s+/g, ' ') + ' language-' + language; |
|
|
|
// Set language on the parent, for styling |
|
parent = element.parentNode; |
|
|
|
if (/pre/i.test(parent.nodeName)) { |
|
parent.className = parent.className.replace(lang, '').replace(/\s+/g, ' ') + ' language-' + language; |
|
} |
|
|
|
var code = element.textContent; |
|
|
|
if(!code) { |
|
return; |
|
} |
|
|
|
code = code.replace(/^(?:\r?\n|\r)/,''); |
|
|
|
var env = { |
|
element: element, |
|
language: language, |
|
grammar: grammar, |
|
code: code |
|
}; |
|
|
|
_.hooks.run('before-highlight', env); |
|
|
|
if (async && self.Worker) { |
|
var worker = new Worker(_.filename); |
|
|
|
worker.onmessage = function(evt) { |
|
env.highlightedCode = Token.stringify(JSON.parse(evt.data), language); |
|
|
|
_.hooks.run('before-insert', env); |
|
|
|
env.element.innerHTML = env.highlightedCode; |
|
|
|
callback && callback.call(env.element); |
|
_.hooks.run('after-highlight', env); |
|
}; |
|
|
|
worker.postMessage(JSON.stringify({ |
|
language: env.language, |
|
code: env.code |
|
})); |
|
} |
|
else { |
|
env.highlightedCode = _.highlight(env.code, env.grammar, env.language); |
|
|
|
_.hooks.run('before-insert', env); |
|
|
|
env.element.innerHTML = env.highlightedCode; |
|
|
|
callback && callback.call(element); |
|
|
|
_.hooks.run('after-highlight', env); |
|
} |
|
}, |
|
|
|
highlight: function (text, grammar, language) { |
|
var tokens = _.tokenize(text, grammar); |
|
return Token.stringify(_.util.encode(tokens), language); |
|
}, |
|
|
|
tokenize: function(text, grammar, language) { |
|
var Token = _.Token; |
|
|
|
var strarr = [text]; |
|
|
|
var rest = grammar.rest; |
|
|
|
if (rest) { |
|
for (var token in rest) { |
|
grammar[token] = rest[token]; |
|
} |
|
|
|
delete grammar.rest; |
|
} |
|
|
|
tokenloop: for (var token in grammar) { |
|
if(!grammar.hasOwnProperty(token) || !grammar[token]) { |
|
continue; |
|
} |
|
|
|
var patterns = grammar[token]; |
|
patterns = (_.util.type(patterns) === "Array") ? patterns : [patterns]; |
|
|
|
for (var j = 0; j < patterns.length; ++j) { |
|
var pattern = patterns[j], |
|
inside = pattern.inside, |
|
lookbehind = !!pattern.lookbehind, |
|
lookbehindLength = 0, |
|
alias = pattern.alias; |
|
|
|
pattern = pattern.pattern || pattern; |
|
|
|
for (var i=0; i<strarr.length; i++) { // Don’t cache length as it changes during the loop |
|
|
|
var str = strarr[i]; |
|
|
|
if (strarr.length > 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 + '</' + env.tag + '>'; |
|
|
|
}; |
|
|
|
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': /<!--[\w\W]*?-->/g, |
|
'prolog': /<\?.+?\?>/, |
|
'doctype': /<!DOCTYPE.+?>/, |
|
'cdata': /<!\[CDATA\[[\w\W]*?]]>/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\((?:(["'])(\\\n|\\?.)*?\1|.*?)\)/gi, |
|
'selector': /[^\{\}\s][^\{\};]*(?=\s*\{)/g, |
|
'string': /("|')(\\\n|\\?.)*?\1/g, |
|
'property': /(\b|\B)[\w-]+(?=\s*:)/ig, |
|
'important': /\B!important\b/gi, |
|
'punctuation': /[\{\};:]/g, |
|
'function': /[-a-z0-9]+(?=\()/ig |
|
}; |
|
|
|
if (Prism.languages.markup) { |
|
Prism.languages.insertBefore('markup', 'tag', { |
|
'style': { |
|
pattern: /<style[\w\W]*?>[\w\W]*?<\/style>/ig, |
|
inside: { |
|
'tag': { |
|
pattern: /<style[\w\W]*?>|<\/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': /("|')(\\\n|\\?.)*?\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, |
|
'function': /(?!\d)[a-z0-9_$]+(?=\()/ig |
|
}); |
|
|
|
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: /<script[\w\W]*?>[\w\W]*?<\/script>/ig, |
|
inside: { |
|
'tag': { |
|
pattern: /<script[\w\W]*?>|<\/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 <?php ?> |
|
// 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, "<span class=\"token php\">$1</span>"); |
|
} |
|
}); |
|
|
|
// Add the rules before all others |
|
Prism.languages.insertBefore('php', 'comment', { |
|
'markup': { |
|
pattern: /<[^?]\/?(.*?)>/g, |
|
inside: Prism.languages.markup |
|
}, |
|
'php': /\{\{\{PHP[0-9]+\}\}\}/g |
|
}); |
|
} |
|
; |
|
(function(Prism) { |
|
|
|
// Ignore comments starting with { to privilege string interpolation highlighting |
|
var comment = /#(?!\{).+/g, |
|
interpolation = { |
|
pattern: /#\{[^}]+\}/g, |
|
alias: 'variable' |
|
}; |
|
|
|
Prism.languages.coffeescript = Prism.languages.extend('javascript', { |
|
'comment': comment, |
|
'string': [ |
|
|
|
// Strings are multiline |
|
/'(?:\\?[\s\S])*?'/g, |
|
|
|
{ |
|
// Strings are multiline |
|
pattern: /"(?:\\?[\s\S])*?"/g, |
|
inside: { |
|
'interpolation': interpolation |
|
} |
|
} |
|
], |
|
'keyword': /\b(and|break|by|catch|class|continue|debugger|delete|do|each|else|extend|extends|false|finally|for|if|in|instanceof|is|isnt|let|loop|namespace|new|no|not|null|of|off|on|or|own|return|super|switch|then|this|throw|true|try|typeof|undefined|unless|until|when|while|window|with|yes|yield)\b/g, |
|
'class-member': { |
|
pattern: /@(?!\d)\w+/, |
|
alias: 'variable' |
|
} |
|
}); |
|
|
|
Prism.languages.insertBefore('coffeescript', 'comment', { |
|
'multiline-comment': { |
|
pattern: /###[\s\S]+?###/g, |
|
alias: 'comment' |
|
}, |
|
|
|
// Block regexp can contain comments and interpolation |
|
'block-regex': { |
|
pattern: /\/{3}[\s\S]*?\/{3}/, |
|
alias: 'regex', |
|
inside: { |
|
'comment': comment, |
|
'interpolation': interpolation |
|
} |
|
} |
|
}); |
|
|
|
Prism.languages.insertBefore('coffeescript', 'string', { |
|
'inline-javascript': { |
|
pattern: /`(?:\\?[\s\S])*?`/g, |
|
inside: { |
|
'delimiter': { |
|
pattern: /^`|`$/g, |
|
alias: 'punctuation' |
|
}, |
|
rest: Prism.languages.javascript |
|
} |
|
}, |
|
|
|
// Block strings |
|
'multiline-string': [ |
|
{ |
|
pattern: /'''[\s\S]*?'''/, |
|
alias: 'string' |
|
}, |
|
{ |
|
pattern: /"""[\s\S]*?"""/, |
|
alias: 'string', |
|
inside: { |
|
interpolation: interpolation |
|
} |
|
} |
|
] |
|
|
|
}); |
|
|
|
Prism.languages.insertBefore('coffeescript', 'keyword', { |
|
// Object property |
|
'property': /(?!\d)\w+(?=\s*:(?!:))/g |
|
}); |
|
|
|
}(Prism));; |
|
Prism.languages.scss = Prism.languages.extend('css', { |
|
'comment': { |
|
pattern: /(^|[^\\])(\/\*[\w\W]*?\*\/|\/\/.*?(\r?\n|$))/g, |
|
lookbehind: true |
|
}, |
|
// aturle is just the @***, not the entire rule (to highlight var & stuffs) |
|
// + add ability to highlight number & unit for media queries |
|
'atrule': /@[\w-]+(?=\s+(\(|\{|;))/gi, |
|
// url, compassified |
|
'url': /([-a-z]+-)*url(?=\()/gi, |
|
// CSS selector regex is not appropriate for Sass |
|
// since there can be lot more things (var, @ directive, nesting..) |
|
// a selector must start at the end of a property or after a brace (end of other rules or nesting) |
|
// it can contain some caracters that aren't used for defining rules or end of selector, & (parent selector), or interpolated variable |
|
// the end of a selector is found when there is no rules in it ( {} or {\s}) or if there is a property (because an interpolated var |
|
// can "pass" as a selector- e.g: proper#{$erty}) |
|
// this one was ard to do, so please be careful if you edit this one 🙂 |
|
'selector': /([^@;\{\}\(\)]?([^@;\{\}\(\)]|&|#\{\$[-_\w]+\})+)(?=\s*\{(\}|\s|[^\}]+(:|\{)[^\}]+))/gm |
|
}); |
|
|
|
Prism.languages.insertBefore('scss', 'atrule', { |
|
'keyword': /@(if|else if|else|for|each|while|import|extend|debug|warn|mixin|include|function|return|content)|(?=@for\s+\$[-_\w]+\s)+from/i |
|
}); |
|
|
|
Prism.languages.insertBefore('scss', 'property', { |
|
// var and interpolated vars |
|
'variable': /((\$[-_\w]+)|(#\{\$[-_\w]+\}))/i |
|
}); |
|
|
|
Prism.languages.insertBefore('scss', 'function', { |
|
'placeholder': /%[-_\w]+/i, |
|
'statement': /\B!(default|optional)\b/gi, |
|
'boolean': /\b(true|false)\b/g, |
|
'null': /\b(null)\b/g, |
|
'operator': /\s+([-+]{1,2}|={1,2}|!=|\|?\||\?|\*|\/|%)\s+/g |
|
}); |
|
; |
|
Prism.languages.bash = Prism.languages.extend('clike', { |
|
'comment': { |
|
pattern: /(^|[^"{\\])(#.*?(\r?\n|$))/g, |
|
lookbehind: true |
|
}, |
|
'string': { |
|
//allow multiline string |
|
pattern: /("|')(\\?[\s\S])*?\1/g, |
|
inside: { |
|
//'property' class reused for bash variables |
|
'property': /\$([a-zA-Z0-9_#\?\-\*!@]+|\{[^\}]+\})/g |
|
} |
|
}, |
|
'keyword': /\b(if|then|else|elif|fi|for|break|continue|while|in|case|function|select|do|done|until|echo|exit|return|set|declare)\b/g |
|
}); |
|
|
|
Prism.languages.insertBefore('bash', 'keyword', { |
|
//'property' class reused for bash variables |
|
'property': /\$([a-zA-Z0-9_#\?\-\*!@]+|\{[^}]+\})/g |
|
}); |
|
Prism.languages.insertBefore('bash', 'comment', { |
|
//shebang must be before comment, 'important' class from css reused |
|
'important': /(^#!\s*\/bin\/bash)|(^#!\s*\/bin\/sh)/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 |
|
} |
|
} |
|
} |
|
}); |
|
|
|
|
|
// prism-glsl : start |
|
Prism.languages.glsl = Prism.languages.extend('clike', { |
|
'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|vec2|vec3|vec4)\b/g, |
|
'operator': /[-+]{1,2}|!=?|<{1,2}=?|>{1,2}=?|\->|={1,2}|\^|~|%|&{1,2}|\|?\||\?|\*|\//g |
|
}); |
|
Prism.languages.insertBefore('glsl', '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 |
|
} |
|
} |
|
} |
|
}); |
|
// prism-glsl : end |
|
|
|
delete Prism.languages.c['class-name']; |
|
delete Prism.languages.c['boolean'];; |
|
Prism.languages.markdown = Prism.languages.extend('markup', {}); |
|
Prism.languages.insertBefore('markdown', 'prolog', { |
|
'blockquote': { |
|
// > ... |
|
pattern: /(^|\n)>(?:[\t ]*>)*/, |
|
lookbehind: true, |
|
alias: 'punctuation' |
|
}, |
|
'code': [ |
|
{ |
|
// Prefixed by 4 spaces or 1 tab |
|
pattern: /(^|\n)(?: {4}|\t).+/, |
|
lookbehind: true, |
|
alias: 'keyword' |
|
}, |
|
{ |
|
// `code` |
|
// ``code`` |
|
pattern: /``.+?``|`[^`\n]+`/, |
|
alias: 'keyword' |
|
} |
|
], |
|
'title': [ |
|
{ |
|
// title 1 |
|
// ======= |
|
|
|
// title 2 |
|
// ------- |
|
pattern: /\w+.*\n(?:==+|--+)/, |
|
alias: 'important', |
|
inside: { |
|
punctuation: /==+$|--+$/ |
|
} |
|
}, |
|
{ |
|
// # title 1 |
|
// ###### title 6 |
|
pattern: /((?:^|\n)\s*)#+.+/, |
|
lookbehind: true, |
|
alias: 'important', |
|
inside: { |
|
punctuation: /^#+|#+$/ |
|
} |
|
} |
|
], |
|
'hr': { |
|
// *** |
|
// --- |
|
// * * * |
|
// ----------- |
|
pattern: /((?:^|\n)\s*)([*-])([\t ]*\2){2,}(?=\s*(?:\n|$))/, |
|
lookbehind: true, |
|
alias: 'punctuation' |
|
}, |
|
'list': { |
|
// * item |
|
// + item |
|
// - item |
|
// 1. item |
|
pattern: /((?:^|\n)\s*)(?:[*+-]|\d+\.)(?=[\t ].)/, |
|
lookbehind: true, |
|
alias: 'punctuation' |
|
}, |
|
'url-reference': { |
|
// [id]: http://example.com "Optional title" |
|
// [id]: http://example.com 'Optional title' |
|
// [id]: http://example.com (Optional title) |
|
// [id]: <http://example.com> "Optional title" |
|
pattern: /!?\[[^\]]+\]:[\t ]+(?:\S+|<(?:[^>]|\\>)+>)(?:[\t ]+(?:"(?:[^"]|\\")*"|'(?:[^']|\\')*'|\((?:[^)]|\\\))*\)))?/, |
|
inside: { |
|
'variable': { |
|
pattern: /^(!?\[)[^\]]+/, |
|
lookbehind: true |
|
}, |
|
'string': /(?:"(?:[^"]|\\")*"|'(?:[^']|\\')*'|\((?:[^)]|\\\))*\))$/, |
|
'punctuation': /[[\]\(\)<>:]/ |
|
}, |
|
alias: 'url' |
|
}, |
|
'bold': { |
|
// **strong** |
|
// __strong__ |
|
|
|
// Allow only one line break |
|
pattern: /(^|[^\\])(\*\*|__)(?:\n(?!\n)|.)+?\2/, |
|
lookbehind: true, |
|
inside: { |
|
'punctuation': /^\*\*|^__|\*\*\s*$|__\s*$/ |
|
} |
|
}, |
|
'italic': { |
|
// *em* |
|
// _em_ |
|
|
|
// Allow only one line break |
|
pattern: /(^|[^\\])(?:\*(?:\n(?!\n)|.)+?\*|_(?:\n(?!\n)|.)+?_)/, |
|
lookbehind: true, |
|
inside: { |
|
'punctuation': /^[*_]|[*_]$/ |
|
} |
|
}, |
|
'url': { |
|
// [example](http://example.com "Optional title") |
|
// [example] [id] |
|
pattern: /!?\[[^\]]+\](?:\([^\s)]+(?:[\t ]+"(?:[^"]|\\")*")?\)| ?\[[^\]\n]*\])/, |
|
inside: { |
|
'variable': { |
|
pattern: /(!?\[)[^\]]+(?=\]$)/, |
|
lookbehind: true |
|
}, |
|
'string': { |
|
pattern: /"(?:[^"]|\\")*"(?=\)$)/ |
|
} |
|
} |
|
} |
|
}); |
|
|
|
Prism.languages.markdown['bold'].inside['url'] = Prism.util.clone(Prism.languages.markdown['url']); |
|
Prism.languages.markdown['italic'].inside['url'] = Prism.util.clone(Prism.languages.markdown['url']); |
|
Prism.languages.markdown['bold'].inside['italic'] = Prism.util.clone(Prism.languages.markdown['italic']); |
|
Prism.languages.markdown['italic'].inside['bold'] = Prism.util.clone(Prism.languages.markdown['bold']);; |
|
(function(){ |
|
|
|
if(!window.Prism) { |
|
return; |
|
} |
|
|
|
for (var language in Prism.languages) { |
|
var tokens = Prism.languages[language]; |
|
|
|
tokens.tab = /\t/g; |
|
tokens.crlf = /\r\n/g; |
|
tokens.lf = /\n/g; |
|
tokens.cr = /\r/g; |
|
} |
|
|
|
})(); |
|
; |
|
(function(){ |
|
|
|
if (!self.Prism) { |
|
return; |
|
} |
|
|
|
var Languages = { |
|
'csharp': 'C#', |
|
'cpp': 'C++' |
|
}; |
|
Prism.hooks.add('before-highlight', function(env) { |
|
var language = Languages[env.language] || env.language; |
|
env.element.setAttribute('data-language', language); |
|
}); |
|
|
|
})(); |
|
; |