light-boilerplate
Version:
Lightweight and powerfull startkit for your next project!
1,526 lines (1,332 loc) • 43.9 kB
JavaScript
/* eslint-disable */
/* http://prismjs.com/download.html?themes=prism&languages=markup+css+clike+javascript+bash+css-extras+handlebars+json+markdown+php+php-extras+scss+twig&plugins=line-numbers+remove-initial-line-feed */
var _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 uniqueId = 0;
var _ = (_self.Prism = {
manual: _self.Prism && _self.Prism.manual,
disableWorkerMessageHandler:
_self.Prism && _self.Prism.disableWorkerMessageHandler,
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];
},
objId: function(obj) {
if (!obj['__id']) {
Object.defineProperty(obj, '__id', { value: ++uniqueId });
}
return obj['__id'];
},
// 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, visited) {
visited = visited || {};
for (var i in o) {
if (o.hasOwnProperty(i)) {
callback.call(o, i, o[i], type || i);
if (
_.util.type(o[i]) === 'Object' &&
!visited[_.util.objId(o[i])]
) {
visited[_.util.objId(o[i])] = true;
_.languages.DFS(o[i], callback, null, visited);
} else if (
_.util.type(o[i]) === 'Array' &&
!visited[_.util.objId(o[i])]
) {
visited[_.util.objId(o[i])] = true;
_.languages.DFS(o[i], callback, i, visited);
}
}
}
},
},
plugins: {},
highlightAll: function(async, callback) {
var env = {
callback: callback,
selector:
'code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code',
};
_.hooks.run('before-highlightall', env);
var elements = env.elements || document.querySelectorAll(env.selector);
for (var i = 0, element; (element = elements[i++]); ) {
_.highlightElement(element, async === true, env.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].toLowerCase();
grammar = _.languages[language];
}
// Set language on the element, if not present
element.className =
element.className.replace(lang, '').replace(/\s+/g, ' ') +
' language-' +
language;
if (element.parentNode) {
// 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;
var env = {
element: element,
language: language,
grammar: grammar,
code: code,
};
_.hooks.run('before-sanity-check', env);
if (!env.code || !env.grammar) {
if (env.code) {
_.hooks.run('before-highlight', env);
env.element.textContent = env.code;
_.hooks.run('after-highlight', env);
}
_.hooks.run('complete', env);
return;
}
_.hooks.run('before-highlight', env);
if (async && _self.Worker) {
var worker = new Worker(_.filename);
worker.onmessage = function(evt) {
env.highlightedCode = evt.data;
_.hooks.run('before-insert', env);
env.element.innerHTML = env.highlightedCode;
callback && callback.call(env.element);
_.hooks.run('after-highlight', env);
_.hooks.run('complete', env);
};
worker.postMessage(
JSON.stringify({
language: env.language,
code: env.code,
immediateClose: true,
})
);
} 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);
_.hooks.run('complete', env);
}
},
highlight: function(text, grammar, language) {
var tokens = _.tokenize(text, grammar);
return Token.stringify(_.util.encode(tokens), language);
},
matchGrammar: function(
text,
strarr,
grammar,
index,
startPos,
oneshot,
target
) {
var Token = _.Token;
for (var token in grammar) {
if (!grammar.hasOwnProperty(token) || !grammar[token]) {
continue;
}
if (token == target) {
return;
}
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,
greedy = !!pattern.greedy,
lookbehindLength = 0,
alias = pattern.alias;
if (greedy && !pattern.pattern.global) {
// Without the global flag, lastIndex won't work
var flags = pattern.pattern.toString().match(/[imuy]*$/)[0];
pattern.pattern = RegExp(pattern.pattern.source, flags + 'g');
}
pattern = pattern.pattern || pattern;
// Don’t cache length as it changes during the loop
for (
var i = index, pos = startPos;
i < strarr.length;
pos += strarr[i].length, ++i
) {
var str = strarr[i];
if (strarr.length > text.length) {
// Something went terribly wrong, ABORT, ABORT!
return;
}
if (str instanceof Token) {
continue;
}
pattern.lastIndex = 0;
var match = pattern.exec(str),
delNum = 1;
// Greedy patterns can override/remove up to two previously matched tokens
if (!match && greedy && i != strarr.length - 1) {
pattern.lastIndex = pos;
match = pattern.exec(text);
if (!match) {
break;
}
var from = match.index + (lookbehind ? match[1].length : 0),
to = match.index + match[0].length,
k = i,
p = pos;
for (
var len = strarr.length;
k < len &&
(p < to || (!strarr[k].type && !strarr[k - 1].greedy));
++k
) {
p += strarr[k].length;
// Move the index i to the element in strarr that is closest to from
if (from >= p) {
++i;
pos = p;
}
}
/*
* If strarr[i] is a Token, then the match starts inside another Token, which is invalid
* If strarr[k - 1] is greedy we are in conflict with another greedy pattern
*/
if (strarr[i] instanceof Token || strarr[k - 1].greedy) {
continue;
}
// Number of tokens to delete and replace with the new match
delNum = k - i;
str = text.slice(pos, p);
match.index -= pos;
}
if (!match) {
if (oneshot) {
break;
}
continue;
}
if (lookbehind) {
lookbehindLength = match[1].length;
}
var from = match.index + lookbehindLength,
match = match[0].slice(lookbehindLength),
to = from + match.length,
before = str.slice(0, from),
after = str.slice(to);
var args = [i, delNum];
if (before) {
++i;
pos += before.length;
args.push(before);
}
var wrapped = new Token(
token,
inside ? _.tokenize(match, inside) : match,
alias,
match,
greedy
);
args.push(wrapped);
if (after) {
args.push(after);
}
Array.prototype.splice.apply(strarr, args);
if (delNum != 1)
_.matchGrammar(text, strarr, grammar, i, pos, true, token);
if (oneshot) break;
}
}
}
},
tokenize: function(text, grammar, language) {
var strarr = [text];
var rest = grammar.rest;
if (rest) {
for (var token in rest) {
grammar[token] = rest[token];
}
delete grammar.rest;
}
_.matchGrammar(text, strarr, grammar, 0, 0, false);
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, matchedStr, greedy) {
this.type = type;
this.content = content;
this.alias = alias;
// Copy of the full string this token was created from
this.length = (matchedStr || '').length | 0;
this.greedy = !!greedy;
});
Token.stringify = function(o, language, parent) {
if (typeof o == 'string') {
return o;
}
if (_.util.type(o) === '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 (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 = Object.keys(env.attributes)
.map(function(name) {
return (
name +
'="' +
(env.attributes[name] || '').replace(/"/g, '"') +
'"'
);
})
.join(' ');
return (
'<' +
env.tag +
' class="' +
env.classes.join(' ') +
'"' +
(attributes ? ' ' + attributes : '') +
'>' +
env.content +
'</' +
env.tag +
'>'
);
};
if (!_self.document) {
if (!_self.addEventListener) {
// in Node.js
return _self.Prism;
}
if (!_.disableWorkerMessageHandler) {
// In worker
_self.addEventListener(
'message',
function(evt) {
var message = JSON.parse(evt.data),
lang = message.language,
code = message.code,
immediateClose = message.immediateClose;
_self.postMessage(_.highlight(code, _.languages[lang], lang));
if (immediateClose) {
_self.close();
}
},
false
);
}
return _self.Prism;
}
//Get current script and highlight
var script =
document.currentScript ||
[].slice.call(document.getElementsByTagName('script')).pop();
if (script) {
_.filename = script.src;
if (!_.manual && !script.hasAttribute('data-manual')) {
if (document.readyState !== 'loading') {
if (window.requestAnimationFrame) {
window.requestAnimationFrame(_.highlightAll);
} else {
window.setTimeout(_.highlightAll, 16);
}
} else {
document.addEventListener('DOMContentLoaded', _.highlightAll);
}
}
}
return _self.Prism;
})();
if (typeof module !== 'undefined' && module.exports) {
module.exports = Prism;
}
// hack for components to work correctly in node.js
if (typeof global !== 'undefined') {
global.Prism = Prism;
}
Prism.languages.markup = {
comment: /<!--[\s\S]*?-->/,
prolog: /<\?[\s\S]+?\?>/,
doctype: /<!DOCTYPE[\s\S]+?>/i,
cdata: /<!\[CDATA\[[\s\S]*?]]>/i,
tag: {
pattern: /<\/?(?!\d)[^\s>\/=$<]+(?:\s+[^\s>\/=]+(?:=(?:("|')(?:\\[\s\S]|(?!\1)[^\\])*\1|[^\s'">=]+))?)*\s*\/?>/i,
inside: {
tag: {
pattern: /^<\/?[^\s>\/]+/i,
inside: {
punctuation: /^<\/?/,
namespace: /^[^\s>\/:]+:/,
},
},
'attr-value': {
pattern: /=(?:("|')(?:\\[\s\S]|(?!\1)[^\\])*\1|[^\s'">=]+)/i,
inside: {
punctuation: [
/^=/,
{
pattern: /(^|[^\\])["']/,
lookbehind: true,
},
],
},
},
punctuation: /\/?>/,
'attr-name': {
pattern: /[^\s>\/]+/,
inside: {
namespace: /^[^\s>\/:]+:/,
},
},
},
},
entity: /&#?[\da-z]{1,8};/i,
};
Prism.languages.markup['tag'].inside['attr-value'].inside['entity'] =
Prism.languages.markup['entity'];
// 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.xml = Prism.languages.markup;
Prism.languages.html = Prism.languages.markup;
Prism.languages.mathml = Prism.languages.markup;
Prism.languages.svg = Prism.languages.markup;
Prism.languages.css = {
comment: /\/\*[\s\S]*?\*\//,
atrule: {
pattern: /@[\w-]+?.*?(?:;|(?=\s*\{))/i,
inside: {
rule: /@[\w-]+/,
// See rest below
},
},
url: /url\((?:(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1|.*?)\)/i,
selector: /[^{}\s][^{};]*?(?=\s*\{)/,
string: {
pattern: /("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,
greedy: true,
},
property: /[\w-]+(?=\s*:)/i,
important: /\B!important\b/i,
function: /[-a-z0-9]+(?=\()/i,
punctuation: /[(){};:]/,
};
Prism.languages.css['atrule'].inside.rest = Prism.util.clone(
Prism.languages.css
);
if (Prism.languages.markup) {
Prism.languages.insertBefore('markup', 'tag', {
style: {
pattern: /(<style[\s\S]*?>)[\s\S]*?(?=<\/style>)/i,
lookbehind: true,
inside: Prism.languages.css,
alias: 'language-css',
},
});
Prism.languages.insertBefore(
'inside',
'attr-value',
{
'style-attr': {
pattern: /\s*style=("|')(?:\\[\s\S]|(?!\1)[^\\])*\1/i,
inside: {
'attr-name': {
pattern: /^\s*style/i,
inside: Prism.languages.markup.tag.inside,
},
punctuation: /^\s*=\s*['"]|['"]\s*$/,
'attr-value': {
pattern: /.+/i,
inside: Prism.languages.css,
},
},
alias: 'language-css',
},
},
Prism.languages.markup.tag
);
}
Prism.languages.clike = {
comment: [
{
pattern: /(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,
lookbehind: true,
},
{
pattern: /(^|[^\\:])\/\/.*/,
lookbehind: true,
},
],
string: {
pattern: /(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,
greedy: true,
},
'class-name': {
pattern: /((?:\b(?:class|interface|extends|implements|trait|instanceof|new)\s+)|(?:catch\s+\())[\w.\\]+/i,
lookbehind: true,
inside: {
punctuation: /[.\\]/,
},
},
keyword: /\b(?:if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/,
boolean: /\b(?:true|false)\b/,
function: /[a-z0-9_]+(?=\()/i,
number: /\b-?(?:0x[\da-f]+|\d*\.?\d+(?:e[+-]?\d+)?)\b/i,
operator: /--?|\+\+?|!=?=?|<=?|>=?|==?=?|&&?|\|\|?|\?|\*|\/|~|\^|%/,
punctuation: /[{}[\];(),.:]/,
};
Prism.languages.javascript = Prism.languages.extend('clike', {
keyword: /\b(?: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|var|void|while|with|yield)\b/,
number: /\b-?(?:0[xX][\dA-Fa-f]+|0[bB][01]+|0[oO][0-7]+|\d*\.?\d+(?:[Ee][+-]?\d+)?|NaN|Infinity)\b/,
// Allow for all non-ASCII characters (See http://stackoverflow.com/a/2008444)
function: /[_$a-zA-Z\xA0-\uFFFF][_$a-zA-Z0-9\xA0-\uFFFF]*(?=\s*\()/i,
operator: /-[-=]?|\+[+=]?|!=?=?|<<?=?|>>?>?=?|=(?:==?|>)?|&[&=]?|\|[|=]?|\*\*?=?|\/=?|~|\^=?|%=?|\?|\.{3}/,
});
Prism.languages.insertBefore('javascript', 'keyword', {
regex: {
pattern: /(^|[^/])\/(?!\/)(\[[^\]\r\n]+]|\\.|[^/\\\[\r\n])+\/[gimyu]{0,5}(?=\s*($|[\r\n,.;})]))/,
lookbehind: true,
greedy: true,
},
// This must be declared before keyword because we use "function" inside the look-forward
'function-variable': {
pattern: /[_$a-zA-Z\xA0-\uFFFF][_$a-zA-Z0-9\xA0-\uFFFF]*(?=\s*=\s*(?:function\b|(?:\([^()]*\)|[_$a-zA-Z\xA0-\uFFFF][_$a-zA-Z0-9\xA0-\uFFFF]*)\s*=>))/i,
alias: 'function',
},
});
Prism.languages.insertBefore('javascript', 'string', {
'template-string': {
pattern: /`(?:\\[\s\S]|[^\\`])*`/,
greedy: true,
inside: {
interpolation: {
pattern: /\$\{[^}]+\}/,
inside: {
'interpolation-punctuation': {
pattern: /^\$\{|\}$/,
alias: 'punctuation',
},
rest: Prism.languages.javascript,
},
},
string: /[\s\S]+/,
},
},
});
if (Prism.languages.markup) {
Prism.languages.insertBefore('markup', 'tag', {
script: {
pattern: /(<script[\s\S]*?>)[\s\S]*?(?=<\/script>)/i,
lookbehind: true,
inside: Prism.languages.javascript,
alias: 'language-javascript',
},
});
}
Prism.languages.js = Prism.languages.javascript;
(function(Prism) {
var insideString = {
variable: [
// Arithmetic Environment
{
pattern: /\$?\(\([\s\S]+?\)\)/,
inside: {
// If there is a $ sign at the beginning highlight $(( and )) as variable
variable: [
{
pattern: /(^\$\(\([\s\S]+)\)\)/,
lookbehind: true,
},
/^\$\(\(/,
],
number: /\b-?(?:0x[\dA-Fa-f]+|\d*\.?\d+(?:[Ee]-?\d+)?)\b/,
// Operators according to https://www.gnu.org/software/bash/manual/bashref.html#Shell-Arithmetic
operator: /--?|-=|\+\+?|\+=|!=?|~|\*\*?|\*=|\/=?|%=?|<<=?|>>=?|<=?|>=?|==?|&&?|&=|\^=?|\|\|?|\|=|\?|:/,
// If there is no $ sign at the beginning highlight (( and )) as punctuation
punctuation: /\(\(?|\)\)?|,|;/,
},
},
// Command Substitution
{
pattern: /\$\([^)]+\)|`[^`]+`/,
inside: {
variable: /^\$\(|^`|\)$|`$/,
},
},
/\$(?:[\w#?*!@]+|\{[^}]+\})/i,
],
};
Prism.languages.bash = {
shebang: {
pattern: /^#!\s*\/bin\/bash|^#!\s*\/bin\/sh/,
alias: 'important',
},
comment: {
pattern: /(^|[^"{\\])#.*/,
lookbehind: true,
},
string: [
//Support for Here-Documents https://en.wikipedia.org/wiki/Here_document
{
pattern: /((?:^|[^<])<<\s*)["']?(\w+?)["']?\s*\r?\n(?:[\s\S])*?\r?\n\2/,
lookbehind: true,
greedy: true,
inside: insideString,
},
{
pattern: /(["'])(?:\\[\s\S]|(?!\1)[^\\])*\1/,
greedy: true,
inside: insideString,
},
],
variable: insideString.variable,
// Originally based on http://ss64.com/bash/
function: {
pattern: /(^|[\s;|&])(?:alias|apropos|apt-get|aptitude|aspell|awk|basename|bash|bc|bg|builtin|bzip2|cal|cat|cd|cfdisk|chgrp|chmod|chown|chroot|chkconfig|cksum|clear|cmp|comm|command|cp|cron|crontab|csplit|cut|date|dc|dd|ddrescue|df|diff|diff3|dig|dir|dircolors|dirname|dirs|dmesg|du|egrep|eject|enable|env|ethtool|eval|exec|expand|expect|export|expr|fdformat|fdisk|fg|fgrep|file|find|fmt|fold|format|free|fsck|ftp|fuser|gawk|getopts|git|grep|groupadd|groupdel|groupmod|groups|gzip|hash|head|help|hg|history|hostname|htop|iconv|id|ifconfig|ifdown|ifup|import|install|jobs|join|kill|killall|less|link|ln|locate|logname|logout|look|lpc|lpr|lprint|lprintd|lprintq|lprm|ls|lsof|make|man|mkdir|mkfifo|mkisofs|mknod|more|most|mount|mtools|mtr|mv|mmv|nano|netstat|nice|nl|nohup|notify-send|npm|nslookup|open|op|passwd|paste|pathchk|ping|pkill|popd|pr|printcap|printenv|printf|ps|pushd|pv|pwd|quota|quotacheck|quotactl|ram|rar|rcp|read|readarray|readonly|reboot|rename|renice|remsync|rev|rm|rmdir|rsync|screen|scp|sdiff|sed|seq|service|sftp|shift|shopt|shutdown|sleep|slocate|sort|source|split|ssh|stat|strace|su|sudo|sum|suspend|sync|tail|tar|tee|test|time|timeout|times|touch|top|traceroute|trap|tr|tsort|tty|type|ulimit|umask|umount|unalias|uname|unexpand|uniq|units|unrar|unshar|uptime|useradd|userdel|usermod|users|uuencode|uudecode|v|vdir|vi|vmstat|wait|watch|wc|wget|whereis|which|who|whoami|write|xargs|xdg-open|yes|zip)(?=$|[\s;|&])/,
lookbehind: true,
},
keyword: {
pattern: /(^|[\s;|&])(?:let|:|\.|if|then|else|elif|fi|for|break|continue|while|in|case|function|select|do|done|until|echo|exit|return|set|declare)(?=$|[\s;|&])/,
lookbehind: true,
},
boolean: {
pattern: /(^|[\s;|&])(?:true|false)(?=$|[\s;|&])/,
lookbehind: true,
},
operator: /&&?|\|\|?|==?|!=?|<<<?|>>|<=?|>=?|=~/,
punctuation: /\$?\(\(?|\)\)?|\.\.|[{}[\];]/,
};
var inside = insideString.variable[1].inside;
inside['function'] = Prism.languages.bash['function'];
inside.keyword = Prism.languages.bash.keyword;
inside.boolean = Prism.languages.bash.boolean;
inside.operator = Prism.languages.bash.operator;
inside.punctuation = Prism.languages.bash.punctuation;
})(Prism);
Prism.languages.css.selector = {
pattern: /[^{}\s][^{}]*(?=\s*\{)/,
inside: {
'pseudo-element': /:(?:after|before|first-letter|first-line|selection)|::[-\w]+/,
'pseudo-class': /:[-\w]+(?:\(.*\))?/,
class: /\.[-:.\w]+/,
id: /#[-:.\w]+/,
attribute: /\[[^\]]+\]/,
},
};
Prism.languages.insertBefore('css', 'function', {
hexcode: /#[\da-f]{3,8}/i,
entity: /\\[\da-f]{1,8}/i,
number: /[\d%.]+/,
});
(function(Prism) {
var handlebars_pattern = /\{\{\{[\s\S]+?\}\}\}|\{\{[\s\S]+?\}\}/;
Prism.languages.handlebars = Prism.languages.extend('markup', {
handlebars: {
pattern: handlebars_pattern,
inside: {
delimiter: {
pattern: /^\{\{\{?|\}\}\}?$/i,
alias: 'punctuation',
},
string: /(["'])(?:\\.|(?!\1)[^\\\r\n])*\1/,
number: /\b-?(?:0x[\dA-Fa-f]+|\d*\.?\d+(?:[Ee][+-]?\d+)?)\b/,
boolean: /\b(?:true|false)\b/,
block: {
pattern: /^(\s*~?\s*)[#\/]\S+?(?=\s*~?\s*$|\s)/i,
lookbehind: true,
alias: 'keyword',
},
brackets: {
pattern: /\[[^\]]+\]/,
inside: {
punctuation: /\[|\]/,
variable: /[\s\S]+/,
},
},
punctuation: /[!"#%&'()*+,.\/;<=>@\[\\\]^`{|}~]/,
variable: /[^!"#%&'()*+,.\/;<=>@\[\\\]^`{|}~\s]+/,
},
},
});
// Comments are inserted at top so that they can
// surround markup
Prism.languages.insertBefore('handlebars', 'tag', {
'handlebars-comment': {
pattern: /\{\{![\s\S]*?\}\}/,
alias: ['handlebars', 'comment'],
},
});
// Tokenize all inline Handlebars expressions that are wrapped in {{ }} or {{{ }}}
// This allows for easy Handlebars + markup highlighting
Prism.hooks.add('before-highlight', function(env) {
if (env.language !== 'handlebars') {
return;
}
env.tokenStack = [];
env.backupCode = env.code;
env.code = env.code.replace(handlebars_pattern, function(match) {
var i = env.tokenStack.length;
// Check for existing strings
while (env.backupCode.indexOf('___HANDLEBARS' + i + '___') !== -1) ++i;
// Create a sparse array
env.tokenStack[i] = match;
return '___HANDLEBARS' + i + '___';
});
});
// Restore env.code for other plugins (e.g. line-numbers)
Prism.hooks.add('before-insert', function(env) {
if (env.language === 'handlebars') {
env.code = env.backupCode;
delete env.backupCode;
}
});
// Re-insert the tokens after highlighting
// and highlight them with defined grammar
Prism.hooks.add('after-highlight', function(env) {
if (env.language !== 'handlebars') {
return;
}
for (var i = 0, keys = Object.keys(env.tokenStack); i < keys.length; ++i) {
var k = keys[i];
var t = env.tokenStack[k];
// The replace prevents $$, $&, $`, $', $n, $nn from being interpreted as special patterns
env.highlightedCode = env.highlightedCode.replace(
'___HANDLEBARS' + k + '___',
Prism.highlight(t, env.grammar, 'handlebars').replace(/\$/g, '$$$$')
);
}
env.element.innerHTML = env.highlightedCode;
});
})(Prism);
Prism.languages.json = {
property: /"(?:\\.|[^\\"\r\n])*"(?=\s*:)/i,
string: {
pattern: /"(?:\\.|[^\\"\r\n])*"(?!\s*:)/,
greedy: true,
},
number: /\b-?(?:0x[\dA-Fa-f]+|\d*\.?\d+(?:[Ee][+-]?\d+)?)\b/,
punctuation: /[{}[\]);,]/,
operator: /:/g,
boolean: /\b(?:true|false)\b/i,
null: /\bnull\b/i,
};
Prism.languages.jsonp = Prism.languages.json;
Prism.languages.markdown = Prism.languages.extend('markup', {});
Prism.languages.insertBefore('markdown', 'prolog', {
blockquote: {
// > ...
pattern: /^>(?:[\t ]*>)*/m,
alias: 'punctuation',
},
code: [
{
// Prefixed by 4 spaces or 1 tab
pattern: /^(?: {4}|\t).+/m,
alias: 'keyword',
},
{
// `code`
// ``code``
pattern: /``.+?``|`[^`\n]+`/,
alias: 'keyword',
},
],
title: [
{
// title 1
// =======
// title 2
// -------
pattern: /\w+.*(?:\r?\n|\r)(?:==+|--+)/,
alias: 'important',
inside: {
punctuation: /==+$|--+$/,
},
},
{
// # title 1
// ###### title 6
pattern: /(^\s*)#+.+/m,
lookbehind: true,
alias: 'important',
inside: {
punctuation: /^#+|#+$/,
},
},
],
hr: {
// ***
// ---
// * * *
// -----------
pattern: /(^\s*)([*-])(?:[\t ]*\2){2,}(?=\s*$)/m,
lookbehind: true,
alias: 'punctuation',
},
list: {
// * item
// + item
// - item
// 1. item
pattern: /(^\s*)(?:[*+-]|\d+\.)(?=[\t ].)/m,
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: /(^|[^\\])(\*\*|__)(?:(?:\r?\n|\r)(?!\r?\n|\r)|.)+?\2/,
lookbehind: true,
inside: {
punctuation: /^\*\*|^__|\*\*$|__$/,
},
},
italic: {
// *em*
// _em_
// Allow only one line break
pattern: /(^|[^\\])([*_])(?:(?:\r?\n|\r)(?!\r?\n|\r)|.)+?\2/,
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']
);
/**
* 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/i,
constant: /\b[A-Z0-9_]{2,}\b/,
comment: {
pattern: /(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/,
lookbehind: true,
},
});
// Shell-like comments are matched after strings, because they are less
// common than strings containing hashes...
Prism.languages.insertBefore('php', 'class-name', {
'shell-comment': {
pattern: /(^|[^\\])#.*/,
lookbehind: true,
alias: 'comment',
},
});
Prism.languages.insertBefore('php', 'keyword', {
delimiter: {
pattern: /\?>|<\?(?:php|=)?/i,
alias: 'important',
},
variable: /\$\w+\b/i,
package: {
pattern: /(\\|namespace\s+|use\s+)[\w\\]+/,
lookbehind: true,
inside: {
punctuation: /\\/,
},
},
});
// Must be defined after the function pattern
Prism.languages.insertBefore('php', 'operator', {
property: {
pattern: /(->)[\w]+/,
lookbehind: true,
},
});
// Add HTML support if 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' || !/(?:<\?php|<\?)/gi.test(env.code)) {
return;
}
env.tokenStack = [];
env.backupCode = env.code;
env.code = env.code.replace(/(?:<\?php|<\?)[\s\S]*?(?:\?>|$)/gi, function(
match
) {
var i = env.tokenStack.length;
// Check for existing strings
while (env.backupCode.indexOf('___PHP' + i + '___') !== -1) ++i;
// Create a sparse array
env.tokenStack[i] = match;
return '___PHP' + i + '___';
});
// Switch the grammar to markup
env.grammar = Prism.languages.markup;
});
// Restore env.code for other plugins (e.g. line-numbers)
Prism.hooks.add('before-insert', function(env) {
if (env.language === 'php' && env.backupCode) {
env.code = env.backupCode;
delete env.backupCode;
}
});
// Re-insert the tokens after highlighting
Prism.hooks.add('after-highlight', function(env) {
if (env.language !== 'php' || !env.tokenStack) {
return;
}
// Switch the grammar back
env.grammar = Prism.languages.php;
for (var i = 0, keys = Object.keys(env.tokenStack); i < keys.length; ++i) {
var k = keys[i];
var t = env.tokenStack[k];
// The replace prevents $$, $&, $`, $', $n, $nn from being interpreted as special patterns
env.highlightedCode = env.highlightedCode.replace(
'___PHP' + k + '___',
'<span class="token php language-php">' +
Prism.highlight(t, env.grammar, 'php').replace(/\$/g, '$$$$') +
'</span>'
);
}
env.element.innerHTML = env.highlightedCode;
});
}
Prism.languages.insertBefore('php', 'variable', {
this: /\$this\b/,
global: /\$(?:_(?:SERVER|GET|POST|FILES|REQUEST|SESSION|ENV|COOKIE)|GLOBALS|HTTP_RAW_POST_DATA|argc|argv|php_errormsg|http_response_header)\b/,
scope: {
pattern: /\b[\w\\]+::/,
inside: {
keyword: /static|self|parent/,
punctuation: /::|\\/,
},
},
});
Prism.languages.scss = Prism.languages.extend('css', {
comment: {
pattern: /(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/,
lookbehind: true,
},
atrule: {
pattern: /@[\w-]+(?:\([^()]+\)|[^(])*?(?=\s+[{;])/,
inside: {
rule: /@[\w-]+/,
// See rest below
},
},
// url, compassified
url: /(?:[-a-z]+-)*url(?=\()/i,
// 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 characters 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 hard to do, so please be careful if you edit this one :)
selector: {
// Initial look-ahead is used to prevent matching of blank selectors
pattern: /(?=\S)[^@;{}()]?(?:[^@;{}()]|&|#\{\$[-\w]+\})+(?=\s*\{(?:\}|\s|[^}]+[:{][^}]+))/m,
inside: {
parent: {
pattern: /&/,
alias: 'important',
},
placeholder: /%[-\w]+/,
variable: /\$[-\w]+|#\{\$[-\w]+\}/,
},
},
});
Prism.languages.insertBefore('scss', 'atrule', {
keyword: [
/@(?:if|else(?: if)?|for|each|while|import|extend|debug|warn|mixin|include|function|return|content)/i,
{
pattern: /( +)(?:from|through)(?= )/,
lookbehind: true,
},
],
});
Prism.languages.scss.property = {
pattern: /(?:[\w-]|\$[-\w]+|#\{\$[-\w]+\})+(?=\s*:)/i,
inside: {
variable: /\$[-\w]+|#\{\$[-\w]+\}/,
},
};
Prism.languages.insertBefore('scss', 'important', {
// var and interpolated vars
variable: /\$[-\w]+|#\{\$[-\w]+\}/,
});
Prism.languages.insertBefore('scss', 'function', {
placeholder: {
pattern: /%[-\w]+/,
alias: 'selector',
},
statement: {
pattern: /\B!(?:default|optional)\b/i,
alias: 'keyword',
},
boolean: /\b(?:true|false)\b/,
null: /\bnull\b/,
operator: {
pattern: /(\s)(?:[-+*\/%]|[=!]=|<=?|>=?|and|or|not)(?=\s)/,
lookbehind: true,
},
});
Prism.languages.scss['atrule'].inside.rest = Prism.util.clone(
Prism.languages.scss
);
Prism.languages.twig = {
comment: /\{#[\s\S]*?#\}/,
tag: {
pattern: /\{\{[\s\S]*?\}\}|\{%[\s\S]*?%\}/,
inside: {
ld: {
pattern: /^(?:\{\{-?|\{%-?\s*\w+)/,
inside: {
punctuation: /^(?:\{\{|\{%)-?/,
keyword: /\w+/,
},
},
rd: {
pattern: /-?(?:%\}|\}\})$/,
inside: {
punctuation: /.*/,
},
},
string: {
pattern: /("|')(?:\\.|(?!\1)[^\\\r\n])*\1/,
inside: {
punctuation: /^['"]|['"]$/,
},
},
keyword: /\b(?:even|if|odd)\b/,
boolean: /\b(?:true|false|null)\b/,
number: /\b-?(?:0x[\dA-Fa-f]+|\d*\.?\d+(?:[Ee][-+]?\d+)?)\b/,
operator: [
{
pattern: /(\s)(?:and|b-and|b-xor|b-or|ends with|in|is|matches|not|or|same as|starts with)(?=\s)/,
lookbehind: true,
},
/[=<>]=?|!=|\*\*?|\/\/?|\?:?|[-+~%|]/,
],
property: /\b[a-zA-Z_]\w*\b/,
punctuation: /[()\[\]{}:.,]/,
},
},
// The rest can be parsed as HTML
other: {
// We want non-blank matches
pattern: /\S(?:[\s\S]*\S)?/,
inside: Prism.languages.markup,
},
};
(function() {
if (typeof self === 'undefined' || !self.Prism || !self.document) {
return;
}
/**
* Class name for <pre> which is activating the plugin
* @type {String}
*/
var PLUGIN_CLASS = 'line-numbers';
/**
* Resizes line numbers spans according to height of line of code
* @param {Element} element <pre> element
*/
var _resizeElement = function(element) {
var codeStyles = getStyles(element);
var whiteSpace = codeStyles['white-space'];
if (whiteSpace === 'pre-wrap' || whiteSpace === 'pre-line') {
var codeElement = element.querySelector('code');
var lineNumbersWrapper = element.querySelector('.line-numbers-rows');
var lineNumberSizer = element.querySelector('.line-numbers-sizer');
var codeLines = element.textContent.split('\n');
if (!lineNumberSizer) {
lineNumberSizer = document.createElement('span');
lineNumberSizer.className = 'line-numbers-sizer';
codeElement.appendChild(lineNumberSizer);
}
lineNumberSizer.style.display = 'block';
codeLines.forEach(function(line, lineNumber) {
lineNumberSizer.textContent = line || '\n';
var lineSize = lineNumberSizer.getBoundingClientRect().height;
lineNumbersWrapper.children[lineNumber].style.height = lineSize + 'px';
});
lineNumberSizer.textContent = '';
lineNumberSizer.style.display = 'none';
}
};
/**
* Returns style declarations for the element
* @param {Element} element
*/
var getStyles = function(element) {
if (!element) {
return null;
}
return window.getComputedStyle
? getComputedStyle(element)
: element.currentStyle || null;
};
window.addEventListener('resize', function() {
Array.prototype.forEach.call(
document.querySelectorAll('pre.' + PLUGIN_CLASS),
_resizeElement
);
});
Prism.hooks.add('complete', function(env) {
if (!env.code) {
return;
}
// works only for <code> wrapped inside <pre> (not inline)
var pre = env.element.parentNode;
var clsReg = /\s*\bline-numbers\b\s*/;
if (
!pre ||
!/pre/i.test(pre.nodeName) ||
// Abort only if nor the <pre> nor the <code> have the class
(!clsReg.test(pre.className) && !clsReg.test(env.element.className))
) {
return;
}
if (env.element.querySelector('.line-numbers-rows')) {
// Abort if line numbers already exists
return;
}
if (clsReg.test(env.element.className)) {
// Remove the class "line-numbers" from the <code>
env.element.className = env.element.className.replace(clsReg, ' ');
}
if (!clsReg.test(pre.className)) {
// Add the class "line-numbers" to the <pre>
pre.className += ' line-numbers';
}
var match = env.code.match(/\n(?!$)/g);
var linesNum = match ? match.length + 1 : 1;
var lineNumbersWrapper;
var lines = new Array(linesNum + 1);
lines = lines.join('<span></span>');
lineNumbersWrapper = document.createElement('span');
lineNumbersWrapper.setAttribute('aria-hidden', 'true');
lineNumbersWrapper.className = 'line-numbers-rows';
lineNumbersWrapper.innerHTML = lines;
if (pre.hasAttribute('data-start')) {
pre.style.counterReset =
'linenumber ' + (parseInt(pre.getAttribute('data-start'), 10) - 1);
}
env.element.appendChild(lineNumbersWrapper);
_resizeElement(pre);
});
})();
(function() {
if (typeof self === 'undefined' || !self.Prism || !self.document) {
return;
}
Prism.hooks.add('before-sanity-check', function(env) {
if (env.code) {
var pre = env.element.parentNode;
var clsReg = /\s*\bkeep-initial-line-feed\b\s*/;
if (
pre &&
pre.nodeName.toLowerCase() === 'pre' &&
// Apply only if nor the <pre> or the <code> have the class
(!clsReg.test(pre.className) && !clsReg.test(env.element.className))
) {
env.code = env.code.replace(/^(?:\r?\n|\r)/, '');
}
}
});
})();
/* eslint-enable */