diff --git a/assets/javascripts/vendor/prism.js b/assets/javascripts/vendor/prism.js index a01a207c..86fbb074 100644 --- a/assets/javascripts/vendor/prism.js +++ b/assets/javascripts/vendor/prism.js @@ -1,11 +1,11 @@ -/* PrismJS 1.17.1 -https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript+c+bash+cpp+coffeescript+ruby+d+dart+markup-templating+elixir+erlang+go+groovy+java+php+json+julia+kotlin+crystal+lua+django+matlab+typescript+nginx+nim+perl+sql+scss+python+jsx+rust+yaml */ +/* PrismJS 1.19.0 +https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript+bash+c+cpp+coffeescript+crystal+d+dart+django+elixir+erlang+go+groovy+java+json+julia+kotlin+lua+markup-templating+matlab+nginx+nim+perl+php+python+jsx+ruby+rust+scss+shell-session+sql+typescript+yaml */ var _self = (typeof window !== 'undefined') ? window // if in browser : ( (typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope) - ? self // if in worker - : {} // if in node js + ? self // if in worker + : {} // if in node js ); /** @@ -17,529 +17,599 @@ var _self = (typeof window !== 'undefined') var Prism = (function (_self){ // Private helper vars - var lang = /\blang(?:uage)?-([\w-]+)\b/i; - var uniqueId = 0; - - var _ = { - 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 (Array.isArray(tokens)) { - return tokens.map(_.util.encode); - } else { - return tokens.replace(/&/g, '&').replace(/ text.length) { + // Something went terribly wrong, ABORT, ABORT! + return; + } - if (strarr.length > text.length) { - // Something went terribly wrong, ABORT, ABORT! - return; - } + if (str instanceof Token) { + continue; + } - if (str instanceof Token) { - continue; + if (greedy && i != strarr.length - 1) { + pattern.lastIndex = pos; + var match = pattern.exec(text); + if (!match) { + break; } - if (greedy && i != strarr.length - 1) { - pattern.lastIndex = pos; - var match = pattern.exec(text); - if (!match) { - break; - } - - var from = match.index + (lookbehind ? match[1].length : 0), + var from = match.index + (lookbehind && match[1] ? 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[i] instanceof Token) { - continue; + 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; } - - // Number of tokens to delete and replace with the new match - delNum = k - i; - str = text.slice(pos, p); - match.index -= pos; - } else { - pattern.lastIndex = 0; - - var match = pattern.exec(str), - delNum = 1; } - if (!match) { - if (oneshot) { - break; - } - + // If strarr[i] is a Token, then the match starts inside another Token, which is invalid + if (strarr[i] instanceof Token) { continue; } - if(lookbehind) { - lookbehindLength = match[1] ? match[1].length : 0; + // Number of tokens to delete and replace with the new match + delNum = k - i; + str = text.slice(pos, p); + match.index -= pos; + } else { + pattern.lastIndex = 0; + + var match = pattern.exec(str), + delNum = 1; + } + + if (!match) { + if (oneshot) { + break; } - var from = match.index + lookbehindLength, + continue; + } + + if(lookbehind) { + lookbehindLength = match[1] ? match[1].length : 0; + } + + 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]; + var args = [i, delNum]; - if (before) { - ++i; - pos += before.length; - args.push(before); - } + if (before) { + ++i; + pos += before.length; + args.push(before); + } - var wrapped = new Token(token, inside? _.tokenize(match, inside) : match, alias, match, greedy); + var wrapped = new Token(token, inside? _.tokenize(match, inside) : match, alias, match, greedy); - args.push(wrapped); + args.push(wrapped); - if (after) { - args.push(after); - } + if (after) { + args.push(after); + } - Array.prototype.splice.apply(strarr, args); + Array.prototype.splice.apply(strarr, args); - if (delNum != 1) - _.matchGrammar(text, strarr, grammar, i, pos, true, token); + if (delNum != 1) + _.matchGrammar(text, strarr, grammar, i, pos, true, token + ',' + j); - if (oneshot) - break; - } + if (oneshot) + break; } } - }, - - tokenize: function(text, grammar) { - var strarr = [text]; + } + }, - var rest = grammar.rest; + tokenize: function(text, grammar) { + var strarr = [text]; - if (rest) { - for (var token in rest) { - grammar[token] = rest[token]; - } + var rest = grammar.rest; - delete grammar.rest; + if (rest) { + for (var token in rest) { + grammar[token] = rest[token]; } - _.matchGrammar(text, strarr, grammar, 0, 0, false); - - return strarr; - }, - - hooks: { - all: {}, + delete grammar.rest; + } - add: function (name, callback) { - var hooks = _.hooks.all; + _.matchGrammar(text, strarr, grammar, 0, 0, false); - hooks[name] = hooks[name] || []; + return strarr; + }, - hooks[name].push(callback); - }, + hooks: { + all: {}, - run: function (name, env) { - var callbacks = _.hooks.all[name]; + add: function (name, callback) { + var hooks = _.hooks.all; - if (!callbacks || !callbacks.length) { - return; - } + hooks[name] = hooks[name] || []; - for (var i=0, callback; callback = callbacks[i++];) { - callback(env); - } - } + hooks[name].push(callback); }, - Token: Token - }; - - _self.Prism = _; + run: function (name, env) { + var callbacks = _.hooks.all[name]; - function Token(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; - } + if (!callbacks || !callbacks.length) { + return; + } - Token.stringify = function(o, language) { - if (typeof o == 'string') { - return o; + for (var i=0, callback; callback = callbacks[i++];) { + callback(env); + } } + }, - if (Array.isArray(o)) { - return o.map(function(element) { - return Token.stringify(element, language); - }).join(''); - } + Token: Token +}; - var env = { - type: o.type, - content: Token.stringify(o.content, language), - tag: 'span', - classes: ['token', o.type], - attributes: {}, - language: language - }; +_self.Prism = _; - if (o.alias) { - var aliases = Array.isArray(o.alias) ? o.alias : [o.alias]; - Array.prototype.push.apply(env.classes, aliases); - } +function Token(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; +} - _.hooks.run('wrap', env); +Token.stringify = function(o, language) { + if (typeof o == 'string') { + return o; + } - var attributes = Object.keys(env.attributes).map(function(name) { - return name + '="' + (env.attributes[name] || '').replace(/"/g, '"') + '"'; - }).join(' '); + if (Array.isArray(o)) { + return o.map(function(element) { + return Token.stringify(element, language); + }).join(''); + } - return '<' + env.tag + ' class="' + env.classes.join(' ') + '"' + (attributes ? ' ' + attributes : '') + '>' + env.content + ''; + var env = { + type: o.type, + content: Token.stringify(o.content, language), + tag: 'span', + classes: ['token', o.type], + attributes: {}, + language: language }; - if (!_self.document) { - if (!_self.addEventListener) { - // in Node.js - return _; - } + if (o.alias) { + var aliases = Array.isArray(o.alias) ? o.alias : [o.alias]; + Array.prototype.push.apply(env.classes, aliases); + } - if (!_.disableWorkerMessageHandler) { - // In worker - _self.addEventListener('message', function (evt) { - var message = JSON.parse(evt.data), - lang = message.language, - code = message.code, - immediateClose = message.immediateClose; + _.hooks.run('wrap', env); - _self.postMessage(_.highlight(code, _.languages[lang], lang)); - if (immediateClose) { - _self.close(); - } - }, false); - } + 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 + ''; +}; + +if (!_self.document) { + if (!_self.addEventListener) { + // in Node.js return _; } + 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 _; +} + //Get current script and highlight - var script = document.currentScript || [].slice.call(document.getElementsByTagName("script")).pop(); +var script = _.util.currentScript(); - if (script) { - _.filename = script.src; +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); - } + if (script.hasAttribute('data-manual')) { + _.manual = true; + } +} + +if (!_.manual) { + function highlightAutomaticallyCallback() { + if (!_.manual) { + _.highlightAll(); } } - return _; + // If the document state is "loading", then we'll use DOMContentLoaded. + // If the document state is "interactive" and the prism.js script is deferred, then we'll also use the + // DOMContentLoaded event because there might be some plugins or languages which have also been deferred and they + // might take longer one animation frame to execute which can create a race condition where only some plugins have + // been loaded when Prism.highlightAll() is executed, depending on how fast resources are loaded. + // See https://github.com/PrismJS/prism/issues/2102 + var readyState = document.readyState; + if (readyState === 'loading' || readyState === 'interactive' && script && script.defer) { + document.addEventListener('DOMContentLoaded', highlightAutomaticallyCallback); + } else { + if (window.requestAnimationFrame) { + window.requestAnimationFrame(highlightAutomaticallyCallback); + } else { + window.setTimeout(highlightAutomaticallyCallback, 16); + } + } +} + +return _; })(_self); @@ -555,7 +625,10 @@ if (typeof global !== 'undefined') { Prism.languages.markup = { 'comment': //, 'prolog': /<\?[\s\S]+?\?>/, - 'doctype': //i, + 'doctype': { + pattern: /"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:(?!)*\]\s*)?>/i, + greedy: true + }, 'cdata': //i, 'tag': { pattern: /<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/i, @@ -728,17 +801,17 @@ Prism.languages.clike = { greedy: true }, 'class-name': { - pattern: /((?:\b(?:class|interface|extends|implements|trait|instanceof|new)\s+)|(?:catch\s+\())[\w.\\]+/i, + pattern: /(\b(?:class|interface|extends|implements|trait|instanceof|new)\s+|\bcatch\s+\()[\w.\\]+/i, lookbehind: true, inside: { - punctuation: /[.\\]/ + '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': /\w+(?=\()/, 'number': /\b0x[\da-f]+\b|(?:\b\d+\.?\d*|\B\.\d+)(?:e[+-]?\d+)?/i, - 'operator': /--?|\+\+?|!=?=?|<=?|>=?|==?=?|&&?|\|\|?|\?|\*|\/|~|\^|%/, + 'operator': /[<>]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/, 'punctuation': /[{}[\];(),.:]/ }; @@ -756,21 +829,21 @@ Prism.languages.javascript = Prism.languages.extend('clike', { lookbehind: true }, { - pattern: /(^|[^.])\b(?:as|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/, + pattern: /(^|[^.]|\.\.\.\s*)\b(?:as|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/, lookbehind: true }, ], 'number': /\b(?:(?:0[xX](?:[\dA-Fa-f](?:_[\dA-Fa-f])?)+|0[bB](?:[01](?:_[01])?)+|0[oO](?:[0-7](?:_[0-7])?)+)n?|(?:\d(?:_\d)?)+n|NaN|Infinity)\b|(?:\b(?:\d(?:_\d)?)+\.?(?:\d(?:_\d)?)*|\B\.(?:\d(?:_\d)?)+)(?:[Ee][+-]?(?:\d(?:_\d)?)+)?/, // Allow for all non-ASCII characters (See http://stackoverflow.com/a/2008444) 'function': /#?[_$a-zA-Z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/, - 'operator': /-[-=]?|\+[+=]?|!=?=?|<>?>?=?|=(?:==?|>)?|&[&=]?|\|[|=]?|\*\*?=?|\/=?|~|\^=?|%=?|\?|\.{3}/ + 'operator': /--|\+\+|\*\*=?|=>|&&|\|\||[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?[.?]?|[~:]/ }); Prism.languages.javascript['class-name'][0].pattern = /(\b(?:class|interface|extends|implements|instanceof|new)\s+)[\w.\\]+/; Prism.languages.insertBefore('javascript', 'keyword', { 'regex': { - pattern: /((?:^|[^$\w\xA0-\uFFFF."'\])\s])\s*)\/(\[(?:[^\]\\\r\n]|\\.)*]|\\.|[^/\\\[\r\n])+\/[gimyus]{0,6}(?=\s*($|[\r\n,.;})\]]))/, + pattern: /((?:^|[^$\w\xA0-\uFFFF."'\])\s])\s*)\/(?:\[(?:[^\]\\\r\n]|\\.)*]|\\.|[^/\\\[\r\n])+\/[gimyus]{0,6}(?=(?:\s|\/\*[\s\S]*?\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/, lookbehind: true, greedy: true }, @@ -834,43 +907,6 @@ if (Prism.languages.markup) { Prism.languages.js = Prism.languages.javascript; -Prism.languages.c = Prism.languages.extend('clike', { - 'class-name': { - pattern: /(\b(?:enum|struct)\s+)\w+/, - lookbehind: true - }, - 'keyword': /\b(?:_Alignas|_Alignof|_Atomic|_Bool|_Complex|_Generic|_Imaginary|_Noreturn|_Static_assert|_Thread_local|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/, - 'operator': />>=?|<<=?|->|([-+&|:])\1|[?:~]|[-+*/%&|^!=<>]=?/, - 'number': /(?:\b0x(?:[\da-f]+\.?[\da-f]*|\.[\da-f]+)(?:p[+-]?\d+)?|(?:\b\d+\.?\d*|\B\.\d+)(?:e[+-]?\d+)?)[ful]*/i -}); - -Prism.languages.insertBefore('c', 'string', { - 'macro': { - // allow for multiline macro definitions - // spaces after the # character compile fine with gcc - pattern: /(^\s*)#\s*[a-z]+(?:[^\r\n\\]|\\(?:\r\n|[\s\S]))*/im, - lookbehind: true, - alias: 'property', - inside: { - // highlight the path of the include statement as a string - 'string': { - pattern: /(#\s*include\s*)(?:<.+?>|("|')(?:\\?.)+?\2)/, - lookbehind: true - }, - // highlight macro directives as keywords - 'directive': { - pattern: /(#\s*)\b(?:define|defined|elif|else|endif|error|ifdef|ifndef|if|import|include|line|pragma|undef|using)\b/, - lookbehind: true, - alias: 'keyword' - } - } - }, - // highlight predefined macros as constants - 'constant': /\b(?:__FILE__|__LINE__|__DATE__|__TIME__|__TIMESTAMP__|__func__|EOF|NULL|SEEK_CUR|SEEK_END|SEEK_SET|stdin|stdout|stderr)\b/ -}); - -delete Prism.languages.c['boolean']; - (function(Prism) { // $ set | grep '^[A-Z][^[:space:]]*=' | cut -d= -f1 | tr '\n' '|' // + LC_ALL, RANDOM, REPLY, SECONDS. @@ -980,7 +1016,7 @@ delete Prism.languages.c['boolean']; 'string': [ // Support for Here-documents https://en.wikipedia.org/wiki/Here_document { - pattern: /((?:^|[^<])<<-?\s*)(\w+?)\s*(?:\r?\n|\r)(?:[\s\S])*?(?:\r?\n|\r)\2/, + pattern: /((?:^|[^<])<<-?\s*)(\w+?)\s*(?:\r?\n|\r)[\s\S]*?(?:\r?\n|\r)\2/, lookbehind: true, greedy: true, inside: insideString @@ -988,7 +1024,7 @@ delete Prism.languages.c['boolean']; // Here-document with quotes around the tag // → No expansion (so no “inside”). { - pattern: /((?:^|[^<])<<-?\s*)(["'])(\w+)\2\s*(?:\r?\n|\r)(?:[\s\S])*?(?:\r?\n|\r)\3/, + pattern: /((?:^|[^<])<<-?\s*)(["'])(\w+)\2\s*(?:\r?\n|\r)[\s\S]*?(?:\r?\n|\r)\3/, lookbehind: true, greedy: true }, @@ -1069,125 +1105,162 @@ delete Prism.languages.c['boolean']; Prism.languages.shell = Prism.languages.bash; })(Prism); -Prism.languages.cpp = Prism.languages.extend('c', { +Prism.languages.c = Prism.languages.extend('clike', { 'class-name': { - pattern: /(\b(?:class|enum|struct)\s+)\w+/, + pattern: /(\b(?:enum|struct)\s+)\w+/, lookbehind: true }, - '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|do|double|dynamic_cast|else|enum|explicit|export|extern|float|for|friend|goto|if|inline|int|int8_t|int16_t|int32_t|int64_t|uint8_t|uint16_t|uint32_t|uint64_t|long|mutable|namespace|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/, - 'number': { - pattern: /(?:\b0b[01']+|\b0x(?:[\da-f']+\.?[\da-f']*|\.[\da-f']+)(?:p[+-]?[\d']+)?|(?:\b[\d']+\.?[\d']*|\B\.[\d']+)(?:e[+-]?[\d']+)?)[ful]*/i, - greedy: true - }, - 'operator': />>=?|<<=?|->|([-+&|:])\1|[?:~]|[-+*/%&|^!=<>]=?|\b(?:and|and_eq|bitand|bitor|not|not_eq|or|or_eq|xor|xor_eq)\b/, - 'boolean': /\b(?:true|false)\b/ -}); - -Prism.languages.insertBefore('cpp', 'string', { - 'raw-string': { - pattern: /R"([^()\\ ]{0,16})\([\s\S]*?\)\1"/, - alias: 'string', - greedy: true - } + 'keyword': /\b(?:_Alignas|_Alignof|_Atomic|_Bool|_Complex|_Generic|_Imaginary|_Noreturn|_Static_assert|_Thread_local|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/, + 'operator': />>=?|<<=?|->|([-+&|:])\1|[?:~]|[-+*/%&|^!=<>]=?/, + 'number': /(?:\b0x(?:[\da-f]+\.?[\da-f]*|\.[\da-f]+)(?:p[+-]?\d+)?|(?:\b\d+\.?\d*|\B\.\d+)(?:e[+-]?\d+)?)[ful]*/i }); -(function(Prism) { - -// Ignore comments starting with { to privilege string interpolation highlighting - var comment = /#(?!\{).+/, - interpolation = { - pattern: /#\{[^}]+\}/, - alias: 'variable' - }; - - Prism.languages.coffeescript = Prism.languages.extend('javascript', { - 'comment': comment, - 'string': [ - - // Strings are multiline - { - pattern: /'(?:\\[\s\S]|[^\\'])*'/, - greedy: true +Prism.languages.insertBefore('c', 'string', { + 'macro': { + // allow for multiline macro definitions + // spaces after the # character compile fine with gcc + pattern: /(^\s*)#\s*[a-z]+(?:[^\r\n\\]|\\(?:\r\n|[\s\S]))*/im, + lookbehind: true, + alias: 'property', + inside: { + // highlight the path of the include statement as a string + 'string': { + pattern: /(#\s*include\s*)(?:<.+?>|("|')(?:\\?.)+?\2)/, + lookbehind: true }, - - { - // Strings are multiline - pattern: /"(?:\\[\s\S]|[^\\"])*"/, - greedy: true, - inside: { - 'interpolation': interpolation - } + // highlight macro directives as keywords + 'directive': { + pattern: /(#\s*)\b(?:define|defined|elif|else|endif|error|ifdef|ifndef|if|import|include|line|pragma|undef|using)\b/, + lookbehind: true, + alias: 'keyword' } - ], - '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/, - 'class-member': { - pattern: /@(?!\d)\w+/, - alias: 'variable' } - }); + }, + // highlight predefined macros as constants + 'constant': /\b(?:__FILE__|__LINE__|__DATE__|__TIME__|__TIMESTAMP__|__func__|EOF|NULL|SEEK_CUR|SEEK_END|SEEK_SET|stdin|stdout|stderr)\b/ +}); - Prism.languages.insertBefore('coffeescript', 'comment', { - 'multiline-comment': { - pattern: /###[\s\S]+?###/, - alias: 'comment' +delete Prism.languages.c['boolean']; + +Prism.languages.cpp = Prism.languages.extend('c', { + 'class-name': { + pattern: /(\b(?:class|enum|struct)\s+)\w+/, + lookbehind: true + }, + '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|do|double|dynamic_cast|else|enum|explicit|export|extern|float|for|friend|goto|if|inline|int|int8_t|int16_t|int32_t|int64_t|uint8_t|uint16_t|uint32_t|uint64_t|long|mutable|namespace|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/, + 'number': { + pattern: /(?:\b0b[01']+|\b0x(?:[\da-f']+\.?[\da-f']*|\.[\da-f']+)(?:p[+-]?[\d']+)?|(?:\b[\d']+\.?[\d']*|\B\.[\d']+)(?:e[+-]?[\d']+)?)[ful]*/i, + greedy: true + }, + 'operator': />>=?|<<=?|->|([-+&|:])\1|[?:~]|[-+*/%&|^!=<>]=?|\b(?:and|and_eq|bitand|bitor|not|not_eq|or|or_eq|xor|xor_eq)\b/, + 'boolean': /\b(?:true|false)\b/ +}); + +Prism.languages.insertBefore('cpp', 'string', { + 'raw-string': { + pattern: /R"([^()\\ ]{0,16})\([\s\S]*?\)\1"/, + alias: 'string', + greedy: true + } +}); + +(function(Prism) { + +// Ignore comments starting with { to privilege string interpolation highlighting +var comment = /#(?!\{).+/, + interpolation = { + pattern: /#\{[^}]+\}/, + alias: 'variable' + }; + +Prism.languages.coffeescript = Prism.languages.extend('javascript', { + 'comment': comment, + 'string': [ + + // Strings are multiline + { + pattern: /'(?:\\[\s\S]|[^\\'])*'/, + greedy: true }, - // Block regexp can contain comments and interpolation - 'block-regex': { - pattern: /\/{3}[\s\S]*?\/{3}/, - alias: 'regex', + { + // Strings are multiline + pattern: /"(?:\\[\s\S]|[^\\"])*"/, + greedy: true, inside: { - 'comment': comment, '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/, + 'class-member': { + pattern: /@(?!\d)\w+/, + alias: 'variable' + } +}); - Prism.languages.insertBefore('coffeescript', 'string', { - 'inline-javascript': { - pattern: /`(?:\\[\s\S]|[^\\`])*`/, - inside: { - 'delimiter': { - pattern: /^`|`$/, - alias: 'punctuation' - }, - rest: Prism.languages.javascript - } - }, +Prism.languages.insertBefore('coffeescript', 'comment', { + 'multiline-comment': { + pattern: /###[\s\S]+?###/, + alias: 'comment' + }, - // Block strings - 'multiline-string': [ - { - pattern: /'''[\s\S]*?'''/, - greedy: true, - alias: 'string' + // 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]|[^\\`])*`/, + inside: { + 'delimiter': { + pattern: /^`|`$/, + alias: 'punctuation' }, - { - pattern: /"""[\s\S]*?"""/, - greedy: true, - alias: 'string', - inside: { - interpolation: interpolation - } + rest: Prism.languages.javascript + } + }, + + // Block strings + 'multiline-string': [ + { + pattern: /'''[\s\S]*?'''/, + greedy: true, + alias: 'string' + }, + { + pattern: /"""[\s\S]*?"""/, + greedy: true, + alias: 'string', + inside: { + interpolation: interpolation } - ] + } + ] - }); +}); - Prism.languages.insertBefore('coffeescript', 'keyword', { - // Object property - 'property': /(?!\d)\w+(?=\s*:(?!:))/ - }); +Prism.languages.insertBefore('coffeescript', 'keyword', { + // Object property + 'property': /(?!\d)\w+(?=\s*:(?!:))/ +}); - delete Prism.languages.coffeescript['template-string']; +delete Prism.languages.coffeescript['template-string']; - Prism.languages.coffee = Prism.languages.coffeescript; +Prism.languages.coffee = Prism.languages.coffeescript; }(Prism)); /** * Original by Samuel Flores * * Adds the following new token classes: - * constant, builtin, variable, symbol, regex + * constant, builtin, variable, symbol, regex */ (function(Prism) { Prism.languages.ruby = Prism.languages.extend('clike', { @@ -1198,7 +1271,14 @@ Prism.languages.insertBefore('cpp', 'string', { greedy: true } ], - '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|protected|private|public|raise|redo|require|rescue|retry|return|self|super|then|throw|true|undef|unless|until|when|while|yield)\b/ + 'class-name': { + pattern: /(\b(?:class)\s+|\bcatch\s+\()[\w.\\]+/i, + lookbehind: true, + inside: { + 'punctuation': /[.\\]/ + } + }, + 'keyword': /\b(?:alias|and|BEGIN|begin|break|case|class|def|define_method|defined|do|each|else|elsif|END|end|ensure|extend|for|if|in|include|module|new|next|nil|not|or|prepend|protected|private|public|raise|redo|require|rescue|retry|return|self|super|then|throw|undef|unless|until|when|while|yield)\b/ }); var interpolation = { @@ -1253,7 +1333,7 @@ Prism.languages.insertBefore('cpp', 'string', { } }, { - pattern: /(^|[^/])\/(?!\/)(\[.+?]|\\.|[^/\\\r\n])+\/[gim]{0,3}(?=\s*($|[\r\n,.;})]))/, + pattern: /(^|[^/])\/(?!\/)(?:\[.+?]|\\.|[^/\\\r\n])+\/[gim]{0,3}(?=\s*(?:$|[\r\n,.;})]))/, lookbehind: true, greedy: true } @@ -1327,22 +1407,109 @@ Prism.languages.insertBefore('cpp', 'string', { Prism.languages.rb = Prism.languages.ruby; }(Prism)); +(function(Prism) { + Prism.languages.crystal = Prism.languages.extend('ruby', { + keyword: [ + /\b(?:abstract|alias|as|asm|begin|break|case|class|def|do|else|elsif|end|ensure|enum|extend|for|fun|if|include|instance_sizeof|lib|macro|module|next|of|out|pointerof|private|protected|rescue|return|require|select|self|sizeof|struct|super|then|type|typeof|uninitialized|union|unless|until|when|while|with|yield|__DIR__|__END_LINE__|__FILE__|__LINE__)\b/, + { + pattern: /(\.\s*)(?:is_a|responds_to)\?/, + lookbehind: true + } + ], + + number: /\b(?:0b[01_]*[01]|0o[0-7_]*[0-7]|0x[\da-fA-F_]*[\da-fA-F]|(?:\d(?:[\d_]*\d)?)(?:\.[\d_]*\d)?(?:[eE][+-]?[\d_]*\d)?)(?:_(?:[uif](?:8|16|32|64))?)?\b/ + }); + + Prism.languages.insertBefore('crystal', 'string', { + attribute: { + pattern: /@\[.+?\]/, + alias: 'attr-name', + inside: { + delimiter: { + pattern: /^@\[|\]$/, + alias: 'tag' + }, + rest: Prism.languages.crystal + } + }, + + expansion: [ + { + pattern: /\{\{.+?\}\}/, + inside: { + delimiter: { + pattern: /^\{\{|\}\}$/, + alias: 'tag' + }, + rest: Prism.languages.crystal + } + }, + { + pattern: /\{%.+?%\}/, + inside: { + delimiter: { + pattern: /^\{%|%\}$/, + alias: 'tag' + }, + rest: Prism.languages.crystal + } + } + ] + }); + +}(Prism)); + Prism.languages.d = Prism.languages.extend('clike', { + 'comment': [ + { + // Shebang + pattern: /^\s*#!.+/, + greedy: true + }, + { + pattern: RegExp(/(^|[^\\])/.source + '(?:' + [ + // /+ comment +/ + // Allow one level of nesting + /\/\+(?:\/\+[\s\S]*?\+\/|(?!\/\+)[\s\S])*?\+\//.source, + // // comment + /\/\/.*/.source, + // /* comment */ + /\/\*[\s\S]*?\*\//.source + ].join('|') + ')'), + lookbehind: true, + greedy: true + } + ], 'string': [ - // r"", x"" - /\b[rx]"(?:\\[\s\S]|[^\\"])*"[cwd]?/, - // q"[]", q"()", q"<>", q"{}" - /\bq"(?:\[[\s\S]*?\]|\([\s\S]*?\)|<[\s\S]*?>|\{[\s\S]*?\})"/, - // q"IDENT - // ... - // IDENT" - /\bq"([_a-zA-Z][_a-zA-Z\d]*)(?:\r?\n|\r)[\s\S]*?(?:\r?\n|\r)\1"/, - // q"//", q"||", etc. - /\bq"(.)[\s\S]*?\1"/, - // Characters - /'(?:\\'|\\?[^']+)'/, - - /(["`])(?:\\[\s\S]|(?!\1)[^\\])*\1[cwd]?/ + { + pattern: RegExp([ + // r"", x"" + /\b[rx]"(?:\\[\s\S]|[^\\"])*"[cwd]?/.source, + + // q"[]", q"()", q"<>", q"{}" + /\bq"(?:\[[\s\S]*?\]|\([\s\S]*?\)|<[\s\S]*?>|\{[\s\S]*?\})"/.source, + + // q"IDENT + // ... + // IDENT" + /\bq"((?!\d)\w+)$[\s\S]*?^\1"/.source, + + // q"//", q"||", etc. + /\bq"(.)[\s\S]*?\2"/.source, + + // Characters + // 'a', '\\', '\n', '\xFF', '\377', '\uFFFF', '\U0010FFFF', '\quot' + /'(?:\\(?:\W|\w+)|[^\\])'/.source, + + /(["`])(?:\\[\s\S]|(?!\3)[^\\])*\3[cwd]?/.source + ].join('|'), 'm'), + greedy: true + }, + { + pattern: /\bq\{(?:\{[^{}]*\}|[^{}])*\}/, + greedy: true, + alias: 'token-string' + } ], 'number': [ @@ -1360,26 +1527,6 @@ Prism.languages.d = Prism.languages.extend('clike', { 'operator': /\|[|=]?|&[&=]?|\+[+=]?|-[-=]?|\.?\.\.|=[>=]?|!(?:i[ns]\b|<>?=?|>=?|=)?|\bi[ns]\b|(?:<[<>]?|>>?>?|\^\^|[*\/%^~])=?/ }); - -Prism.languages.d.comment = [ - // Shebang - /^\s*#!.+/, - // /+ +/ - { - // Allow one level of nesting - pattern: /(^|[^\\])\/\+(?:\/\+[\s\S]*?\+\/|[\s\S])*?\+\//, - lookbehind: true - } -].concat(Prism.languages.d.comment); - -Prism.languages.insertBefore('d', 'comment', { - 'token-string': { - // Allow one level of nesting - pattern: /\bq\{(?:\{[^}]*\}|[^}])*\}/, - alias: 'string' - } -}); - Prism.languages.insertBefore('d', 'keyword', { 'property': /\B@\w*/ }); @@ -1391,6 +1538,7 @@ Prism.languages.insertBefore('d', 'function', { alias: 'variable' } }); + Prism.languages.dart = Prism.languages.extend('clike', { 'string': [ { @@ -1539,50 +1687,111 @@ Prism.languages.insertBefore('dart','function',{ }(Prism)); -Prism.languages.elixir = { - 'comment': /#.*/m, - // ~r"""foo""" (multi-line), ~r'''foo''' (multi-line), ~r/foo/, ~r|foo|, ~r"foo", ~r'foo', ~r(foo), ~r[foo], ~r{foo}, ~r - 'regex': { - pattern: /~[rR](?:("""|''')(?:\\[\s\S]|(?!\1)[^\\])+\1|([\/|"'])(?:\\.|(?!\2)[^\\\r\n])+\2|\((?:\\.|[^\\)\r\n])+\)|\[(?:\\.|[^\\\]\r\n])+\]|\{(?:\\.|[^\\}\r\n])+\}|<(?:\\.|[^\\>\r\n])+>)[uismxfr]*/, - greedy: true - }, - 'string': [ - { - // ~s"""foo""" (multi-line), ~s'''foo''' (multi-line), ~s/foo/, ~s|foo|, ~s"foo", ~s'foo', ~s(foo), ~s[foo], ~s{foo} (with interpolation care), ~s - pattern: /~[cCsSwW](?:("""|''')(?:\\[\s\S]|(?!\1)[^\\])+\1|([\/|"'])(?:\\.|(?!\2)[^\\\r\n])+\2|\((?:\\.|[^\\)\r\n])+\)|\[(?:\\.|[^\\\]\r\n])+\]|\{(?:\\.|#\{[^}]+\}|[^\\}\r\n])+\}|<(?:\\.|[^\\>\r\n])+>)[csa]?/, - greedy: true, - inside: { - // See interpolation below - } +// Django/Jinja2 syntax definition for Prism.js syntax highlighter. +// Mostly it works OK but can paint code incorrectly on complex html/template tag combinations. + +(function (Prism) { + + Prism.languages.django = { + 'comment': /^{#[\s\S]*?#}$/, + 'tag': { + pattern: /(^{%[+-]?\s*)\w+/, + lookbehind: true, + alias: 'keyword' }, - { - pattern: /("""|''')[\s\S]*?\1/, - greedy: true, - inside: { - // See interpolation below - } + 'delimiter': { + pattern: /^{[{%][+-]?|[+-]?[}%]}$/, + alias: 'punctuation' }, - { - // Multi-line strings are allowed - pattern: /("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/, - greedy: true, - inside: { - // See interpolation below - } - } - ], - 'atom': { - // Look-behind prevents bad highlighting of the :: operator - pattern: /(^|[^:]):\w+/, - lookbehind: true, - alias: 'symbol' - }, - // Look-ahead prevents bad highlighting of the :: operator - 'attr-name': /\w+:(?!:)/, - 'capture': { - // Look-behind prevents bad highlighting of the && operator - pattern: /(^|[^&])&(?:[^&\s\d()][^\s()]*|(?=\())/, - lookbehind: true, + 'string': { + pattern: /("|')(?:\\.|(?!\1)[^\\\r\n])*\1/, + greedy: true + }, + 'filter': { + pattern: /(\|)\w+/, + lookbehind: true, + alias: 'function' + }, + 'test': { + pattern: /(\bis\s+(?:not\s+)?)(?!not\b)\w+/, + lookbehind: true, + alias: 'function' + }, + 'function': /\b[a-z_]\w+(?=\s*\()/i, + 'keyword': /\b(?:and|as|by|else|for|if|import|in|is|loop|not|or|recursive|with|without)\b/, + 'operator': /[-+*/%=]=?|!=|\*\*?=?|\/\/?=?|<[<=>]?|>[=>]?|[&|^~]/, + 'number': /\b\d+(?:\.\d+)?\b/, + 'boolean': /[Tt]rue|[Ff]alse|[Nn]one/, + 'variable': /\b\w+?\b/, + 'punctuation': /[{}[\](),.:;]/ + }; + + + var pattern = /{{[\s\S]*?}}|{%[\s\S]*?%}|{#[\s\S]*?#}/g; + var markupTemplating = Prism.languages['markup-templating']; + + Prism.hooks.add('before-tokenize', function (env) { + markupTemplating.buildPlaceholders(env, 'django', pattern); + }); + Prism.hooks.add('after-tokenize', function (env) { + markupTemplating.tokenizePlaceholders(env, 'django'); + }); + + // Add an Jinja2 alias + Prism.languages.jinja2 = Prism.languages.django; + Prism.hooks.add('before-tokenize', function (env) { + markupTemplating.buildPlaceholders(env, 'jinja2', pattern); + }); + Prism.hooks.add('after-tokenize', function (env) { + markupTemplating.tokenizePlaceholders(env, 'jinja2'); + }); + +})(Prism); + +Prism.languages.elixir = { + 'comment': /#.*/m, + // ~r"""foo""" (multi-line), ~r'''foo''' (multi-line), ~r/foo/, ~r|foo|, ~r"foo", ~r'foo', ~r(foo), ~r[foo], ~r{foo}, ~r + 'regex': { + pattern: /~[rR](?:("""|''')(?:\\[\s\S]|(?!\1)[^\\])+\1|([\/|"'])(?:\\.|(?!\2)[^\\\r\n])+\2|\((?:\\.|[^\\)\r\n])+\)|\[(?:\\.|[^\\\]\r\n])+\]|\{(?:\\.|[^\\}\r\n])+\}|<(?:\\.|[^\\>\r\n])+>)[uismxfr]*/, + greedy: true + }, + 'string': [ + { + // ~s"""foo""" (multi-line), ~s'''foo''' (multi-line), ~s/foo/, ~s|foo|, ~s"foo", ~s'foo', ~s(foo), ~s[foo], ~s{foo} (with interpolation care), ~s + pattern: /~[cCsSwW](?:("""|''')(?:\\[\s\S]|(?!\1)[^\\])+\1|([\/|"'])(?:\\.|(?!\2)[^\\\r\n])+\2|\((?:\\.|[^\\)\r\n])+\)|\[(?:\\.|[^\\\]\r\n])+\]|\{(?:\\.|#\{[^}]+\}|[^\\}\r\n])+\}|<(?:\\.|[^\\>\r\n])+>)[csa]?/, + greedy: true, + inside: { + // See interpolation below + } + }, + { + pattern: /("""|''')[\s\S]*?\1/, + greedy: true, + inside: { + // See interpolation below + } + }, + { + // Multi-line strings are allowed + pattern: /("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/, + greedy: true, + inside: { + // See interpolation below + } + } + ], + 'atom': { + // Look-behind prevents bad highlighting of the :: operator + pattern: /(^|[^:]):\w+/, + lookbehind: true, + alias: 'symbol' + }, + // Look-ahead prevents bad highlighting of the :: operator + 'attr-name': /\w+\??:(?!:)/, + 'capture': { + // Look-behind prevents bad highlighting of the && operator + pattern: /(^|[^&])&(?:[^&\s\d()][^\s()]*|(?=\())/, + lookbehind: true, alias: 'function' }, 'argument': { @@ -1680,30 +1889,32 @@ Prism.languages.go = Prism.languages.extend('clike', { 'operator': /[*\/%^!=]=?|\+[=+]?|-[=-]?|\|[=|]?|&(?:=|&|\^=?)?|>(?:>=?|=)?|<(?:<=?|=|-)?|:=|\.\.\./, 'number': /(?:\b0x[a-f\d]+|(?:\b\d+\.?\d*|\B\.\d+)(?:e[-+]?\d+)?)i?/i, 'string': { - pattern: /(["'`])(\\[\s\S]|(?!\1)[^\\])*\1/, + pattern: /(["'`])(?:\\[\s\S]|(?!\1)[^\\])*\1/, greedy: true } }); delete Prism.languages.go['class-name']; Prism.languages.groovy = Prism.languages.extend('clike', { - 'keyword': /\b(?:as|def|in|abstract|assert|boolean|break|byte|case|catch|char|class|const|continue|default|do|double|else|enum|extends|final|finally|float|for|goto|if|implements|import|instanceof|int|interface|long|native|new|package|private|protected|public|return|short|static|strictfp|super|switch|synchronized|this|throw|throws|trait|transient|try|void|volatile|while)\b/, 'string': [ { - pattern: /("""|''')[\s\S]*?\1|(?:\$\/)(?:\$\/\$|[\s\S])*?\/\$/, + pattern: /("""|''')(?:[^\\]|\\[\s\S])*?\1|\$\/(?:\$\/\$|[\s\S])*?\/\$/, greedy: true }, { - pattern: /(["'\/])(?:\\.|(?!\1)[^\\\r\n])*\1/, + // TODO: Slash strings (e.g. /foo/) can contain line breaks but this will cause a lot of trouble with + // simple division (see JS regex), so find a fix maybe? + pattern: /(["'/])(?:\\.|(?!\1)[^\\\r\n])*\1/, greedy: true } ], + 'keyword': /\b(?:as|def|in|abstract|assert|boolean|break|byte|case|catch|char|class|const|continue|default|do|double|else|enum|extends|final|finally|float|for|goto|if|implements|import|instanceof|int|interface|long|native|new|package|private|protected|public|return|short|static|strictfp|super|switch|synchronized|this|throw|throws|trait|transient|try|void|volatile|while)\b/, 'number': /\b(?:0b[01_]+|0x[\da-f_]+(?:\.[\da-f_p\-]+)?|[\d_]+(?:\.[\d_]+)?(?:e[+-]?[\d]+)?)[glidf]?\b/i, 'operator': { - pattern: /(^|[^.])(?:~|==?~?|\?[.:]?|\*(?:[.=]|\*=?)?|\.[@&]|\.\.<|\.{1,2}(?!\.)|-[-=>]?|\+[+=]?|!=?|<(?:<=?|=>?)?|>(?:>>?=?|=)?|&[&=]?|\|[|=]?|\/=?|\^=?|%=?)/, + pattern: /(^|[^.])(?:~|==?~?|\?[.:]?|\*(?:[.=]|\*=?)?|\.[@&]|\.\.<|\.\.(?!\.)|-[-=>]?|\+[+=]?|!=?|<(?:<=?|=>?)?|>(?:>>?=?|=)?|&[&=]?|\|[|=]?|\/=?|\^=?|%=?)/, lookbehind: true }, - 'punctuation': /\.+|[{}[\];(),:$]/ + 'punctuation': /\.+|[{}[\];(),.:$]/ }); Prism.languages.insertBefore('groovy', 'string', { @@ -1719,9 +1930,9 @@ Prism.languages.insertBefore('groovy', 'punctuation', { Prism.languages.insertBefore('groovy', 'function', { 'annotation': { - alias: 'punctuation', pattern: /(^|[^.])@\w+/, - lookbehind: true + lookbehind: true, + alias: 'punctuation' } }); @@ -1754,7 +1965,7 @@ Prism.hooks.add('wrap', function(env) { (function (Prism) { - var keywords = /\b(?:abstract|continue|for|new|switch|assert|default|goto|package|synchronized|boolean|do|if|private|this|break|double|implements|protected|throw|byte|else|import|public|throws|case|enum|instanceof|return|transient|catch|extends|int|short|try|char|final|interface|static|void|class|finally|long|strictfp|volatile|const|float|native|super|while|var|null|exports|module|open|opens|provides|requires|to|transitive|uses|with)\b/; + var keywords = /\b(?:abstract|assert|boolean|break|byte|case|catch|char|class|const|continue|default|do|double|else|enum|exports|extends|final|finally|float|for|goto|if|implements|import|instanceof|int|interface|long|module|native|new|null|open|opens|package|private|protected|provides|public|requires|return|short|static|strictfp|super|switch|synchronized|this|throw|throws|to|transient|transitive|try|uses|var|void|volatile|while|with|yield)\b/; // based on the java naming conventions var className = /\b[A-Z](?:\w*[a-z]\w*)?\b/; @@ -1777,11 +1988,20 @@ Prism.hooks.add('wrap', function(env) { ], 'number': /\b0b[01][01_]*L?\b|\b0x[\da-f_]*\.?[\da-f_p+-]+\b|(?:\b\d[\d_]*\.?[\d_]*|\B\.\d[\d_]*)(?:e[+-]?\d[\d_]*)?[dfl]?/i, 'operator': { - pattern: /(^|[^.])(?:<<=?|>>>?=?|->|([-+&|])\2|[?:~]|[-+*/%&|^!=<>]=?)/m, + pattern: /(^|[^.])(?:<<=?|>>>?=?|->|--|\+\+|&&|\|\||::|[?:~]|[-+*/%&|^!=<>]=?)/m, lookbehind: true } }); + Prism.languages.insertBefore('java', 'string', { + 'triple-quoted-string': { + // http://openjdk.java.net/jeps/355#Description + pattern: /"""[ \t]*[\r\n](?:(?:"|"")?(?:\\.|[^"\\]))*"""/, + greedy: true, + alias: 'string' + } + }); + Prism.languages.insertBefore('java', 'class-name', { 'annotation': { alias: 'punctuation', @@ -1789,7 +2009,7 @@ Prism.hooks.add('wrap', function(env) { lookbehind: true }, 'namespace': { - pattern: /(\b(?:exports|import(?:\s+static)?|module|open|opens|package|provides|requires|to|transitive|uses|with)\s+)[a-z]\w*(\.[a-z]\w*)+/, + pattern: /(\b(?:exports|import(?:\s+static)?|module|open|opens|package|provides|requires|to|transitive|uses|with)\s+)[a-z]\w*(?:\.[a-z]\w*)+/, lookbehind: true, inside: { 'punctuation': /\./, @@ -1807,139 +2027,6 @@ Prism.hooks.add('wrap', function(env) { }); }(Prism)); -/** - * 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 - */ -(function (Prism) { - Prism.languages.php = Prism.languages.extend('clike', { - 'keyword': /\b(?:__halt_compiler|abstract|and|array|as|break|callable|case|catch|class|clone|const|continue|declare|default|die|do|echo|else|elseif|empty|enddeclare|endfor|endforeach|endif|endswitch|endwhile|eval|exit|extends|final|finally|for|foreach|function|global|goto|if|implements|include|include_once|instanceof|insteadof|interface|isset|list|namespace|new|or|parent|print|private|protected|public|require|require_once|return|static|switch|throw|trait|try|unset|use|var|while|xor|yield)\b/i, - 'boolean': { - pattern: /\b(?:false|true)\b/i, - alias: 'constant' - }, - 'constant': [ - /\b[A-Z_][A-Z0-9_]*\b/, - /\b(?:null)\b/i, - ], - 'comment': { - pattern: /(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/, - lookbehind: true - } - }); - - Prism.languages.insertBefore('php', 'string', { - 'shell-comment': { - pattern: /(^|[^\\])#.*/, - lookbehind: true, - alias: 'comment' - } - }); - - Prism.languages.insertBefore('php', 'comment', { - 'delimiter': { - pattern: /\?>$|^<\?(?:php(?=\s)|=)?/i, - alias: 'important' - } - }); - - Prism.languages.insertBefore('php', 'keyword', { - '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 - } - }); - - var string_interpolation = { - pattern: /{\$(?:{(?:{[^{}]+}|[^{}]+)}|[^{}])+}|(^|[^\\{])\$+(?:\w+(?:\[.+?]|->\w+)*)/, - lookbehind: true, - inside: { - rest: Prism.languages.php - } - }; - - Prism.languages.insertBefore('php', 'string', { - 'nowdoc-string': { - pattern: /<<<'([^']+)'(?:\r\n?|\n)(?:.*(?:\r\n?|\n))*?\1;/, - greedy: true, - alias: 'string', - inside: { - 'delimiter': { - pattern: /^<<<'[^']+'|[a-z_]\w*;$/i, - alias: 'symbol', - inside: { - 'punctuation': /^<<<'?|[';]$/ - } - } - } - }, - 'heredoc-string': { - pattern: /<<<(?:"([^"]+)"(?:\r\n?|\n)(?:.*(?:\r\n?|\n))*?\1;|([a-z_]\w*)(?:\r\n?|\n)(?:.*(?:\r\n?|\n))*?\2;)/i, - greedy: true, - alias: 'string', - inside: { - 'delimiter': { - pattern: /^<<<(?:"[^"]+"|[a-z_]\w*)|[a-z_]\w*;$/i, - alias: 'symbol', - inside: { - 'punctuation': /^<<<"?|[";]$/ - } - }, - 'interpolation': string_interpolation // See below - } - }, - 'single-quoted-string': { - pattern: /'(?:\\[\s\S]|[^\\'])*'/, - greedy: true, - alias: 'string' - }, - 'double-quoted-string': { - pattern: /"(?:\\[\s\S]|[^\\"])*"/, - greedy: true, - alias: 'string', - inside: { - 'interpolation': string_interpolation // See below - } - } - }); - // The different types of PHP strings "replace" the C-like standard string - delete Prism.languages.php['string']; - - Prism.hooks.add('before-tokenize', function(env) { - if (!/<\?/.test(env.code)) { - return; - } - - var phpPattern = /<\?(?:[^"'/#]|\/(?![*/])|("|')(?:\\[\s\S]|(?!\1)[^\\])*\1|(?:\/\/|#)(?:[^?\n\r]|\?(?!>))*|\/\*[\s\S]*?(?:\*\/|$))*?(?:\?>|$)/ig; - Prism.languages['markup-templating'].buildPlaceholders(env, 'php', phpPattern); - }); - - Prism.hooks.add('after-tokenize', function(env) { - Prism.languages['markup-templating'].tokenizePlaceholders(env, 'php'); - }); - -}(Prism)); - Prism.languages.json = { 'property': { pattern: /"(?:\\.|[^\\"\r\n])*"(?=\s*:)/, @@ -1950,7 +2037,7 @@ Prism.languages.json = { greedy: true }, 'comment': /\/\/.*|\/\*[\s\S]*?(?:\*\/|$)/, - 'number': /-?\d+\.?\d*(e[+-]?\d+)?/i, + 'number': /-?\d+\.?\d*(?:e[+-]?\d+)?/i, 'punctuation': /[{}[\],]/, 'operator': /:/, 'boolean': /\b(?:true|false)\b/, @@ -2018,7 +2105,7 @@ Prism.languages.julia= { { pattern: /\$\{[^}]+\}/, inside: { - delimiter: { + 'delimiter': { pattern: /^\$\{|\}$/, alias: 'variable' }, @@ -2037,58 +2124,6 @@ Prism.languages.julia= { }(Prism)); -(function(Prism) { - Prism.languages.crystal = Prism.languages.extend('ruby', { - keyword: [ - /\b(?:abstract|alias|as|asm|begin|break|case|class|def|do|else|elsif|end|ensure|enum|extend|for|fun|if|include|instance_sizeof|lib|macro|module|next|of|out|pointerof|private|protected|rescue|return|require|select|self|sizeof|struct|super|then|type|typeof|uninitialized|union|unless|until|when|while|with|yield|__DIR__|__END_LINE__|__FILE__|__LINE__)\b/, - { - pattern: /(\.\s*)(?:is_a|responds_to)\?/, - lookbehind: true - } - ], - - number: /\b(?:0b[01_]*[01]|0o[0-7_]*[0-7]|0x[\da-fA-F_]*[\da-fA-F]|(?:\d(?:[\d_]*\d)?)(?:\.[\d_]*\d)?(?:[eE][+-]?[\d_]*\d)?)(?:_(?:[uif](?:8|16|32|64))?)?\b/ - }); - - Prism.languages.insertBefore('crystal', 'string', { - attribute: { - pattern: /@\[.+?\]/, - alias: 'attr-name', - inside: { - delimiter: { - pattern: /^@\[|\]$/, - alias: 'tag' - }, - rest: Prism.languages.crystal - } - }, - - expansion: [ - { - pattern: /\{\{.+?\}\}/, - inside: { - delimiter: { - pattern: /^\{\{|\}\}$/, - alias: 'tag' - }, - rest: Prism.languages.crystal - } - }, - { - pattern: /\{%.+?%\}/, - inside: { - delimiter: { - pattern: /^\{%|%\}$/, - alias: 'tag' - }, - rest: Prism.languages.crystal - } - } - ] - }); - -}(Prism)); - Prism.languages.lua = { 'comment': /^#!.+|--(?:\[(=*)\[[\s\S]*?\]\1\]|.*)/m, // \z may be used to skip the following space @@ -2109,67 +2144,6 @@ Prism.languages.lua = { ], 'punctuation': /[\[\](){},;]|\.+|:+/ }; -// Django/Jinja2 syntax definition for Prism.js syntax highlighter. -// Mostly it works OK but can paint code incorrectly on complex html/template tag combinations. - -(function (Prism) { - - Prism.languages.django = { - 'comment': /^{#[\s\S]*?#}$/, - 'tag': { - pattern: /(^{%[+-]?\s*)\w+/, - lookbehind: true, - alias: 'keyword' - }, - 'delimiter': { - pattern: /^{[{%][+-]?|[+-]?[}%]}$/, - alias: 'punctuation' - }, - 'string': { - pattern: /("|')(?:\\.|(?!\1)[^\\\r\n])*\1/, - greedy: true - }, - 'filter': { - pattern: /(\|)\w+/, - lookbehind: true, - alias: 'function' - }, - 'test': { - pattern: /(\bis\s+(?:not\s+)?)(?!not\b)\w+/, - lookbehind: true, - alias: 'function' - }, - 'function': /\b[a-z_]\w+(?=\s*\()/i, - 'keyword': /\b(?:and|as|by|else|for|if|import|in|is|loop|not|or|recursive|with|without)\b/, - 'operator': /[-+*/%=]=?|!=|\*\*?=?|\/\/?=?|<[<=>]?|>[=>]?|[&|^~]/, - 'number': /\b\d+(?:\.\d+)?\b/, - 'boolean': /[Tt]rue|[Ff]alse|[Nn]one/, - 'variable': /\b\w+?\b/, - 'punctuation': /[{}[\](),.:;]/ - }; - - - var pattern = /{{[\s\S]*?}}|{%[\s\S]*?%}|{#[\s\S]*?#}/g; - var markupTemplating = Prism.languages['markup-templating']; - - Prism.hooks.add('before-tokenize', function (env) { - markupTemplating.buildPlaceholders(env, 'django', pattern); - }); - Prism.hooks.add('after-tokenize', function (env) { - markupTemplating.tokenizePlaceholders(env, 'django'); - }); - - // Add an Jinja2 alias - Prism.languages.jinja2 = Prism.languages.django; - Prism.hooks.add('before-tokenize', function (env) { - markupTemplating.buildPlaceholders(env, 'jinja2', pattern); - }); - Prism.hooks.add('after-tokenize', function (env) { - markupTemplating.tokenizePlaceholders(env, 'jinja2'); - }); - -})(Prism); - Prism.languages.matlab = { 'comment': [ /%\{[\s\S]*?\}%/, @@ -2186,14 +2160,6 @@ Prism.languages.matlab = { 'operator': /\.?[*^\/\\']|[+\-:@]|[<>=~]=?|&&?|\|\|?/, 'punctuation': /\.{3}|[.,;\[\](){}!]/ }; -Prism.languages.typescript = Prism.languages.extend('javascript', { - // From JavaScript Prism keyword list and TypeScript language spec: https://github.com/Microsoft/TypeScript/blob/master/doc/spec.md#221-reserved-words - 'keyword': /\b(?:abstract|as|async|await|break|case|catch|class|const|constructor|continue|debugger|declare|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|is|keyof|let|module|namespace|new|null|of|package|private|protected|public|readonly|return|require|set|static|super|switch|this|throw|try|type|typeof|var|void|while|with|yield)\b/, - 'builtin': /\b(?:string|Function|any|number|boolean|Array|symbol|console|Promise|unknown|never)\b/, -}); - -Prism.languages.ts = Prism.languages.typescript; - Prism.languages.nginx = Prism.languages.extend('clike', { 'comment': { pattern: /(^|[^"{\\])#.*/, @@ -2388,7 +2354,7 @@ Prism.languages.perl = { // the same line from being highlighted as regex. // This does not support multi-line regex. { - pattern: /\/(?:[^\/\\\r\n]|\\.)*\/[msixpodualngc]*(?=\s*(?:$|[\r\n,.;})&|\-+*~<>!?^]|(lt|gt|le|ge|eq|ne|cmp|not|and|or|xor|x)\b))/, + pattern: /\/(?:[^\/\\\r\n]|\\.)*\/[msixpodualngc]*(?=\s*(?:$|[\r\n,.;})&|\-+*~<>!?^]|(?:lt|gt|le|ge|eq|ne|cmp|not|and|or|xor|x)\b))/, greedy: true } ], @@ -2431,108 +2397,136 @@ Prism.languages.perl = { 'punctuation': /[{}[\];(),:]/ }; -Prism.languages.sql = { - 'comment': { - pattern: /(^|[^\\])(?:\/\*[\s\S]*?\*\/|(?:--|\/\/|#).*)/, - lookbehind: true - }, - 'variable': [ - { - pattern: /@(["'`])(?:\\[\s\S]|(?!\1)[^\\])+\1/, - greedy: true +/** + * 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 + */ +(function (Prism) { + Prism.languages.php = Prism.languages.extend('clike', { + 'keyword': /\b(?:__halt_compiler|abstract|and|array|as|break|callable|case|catch|class|clone|const|continue|declare|default|die|do|echo|else|elseif|empty|enddeclare|endfor|endforeach|endif|endswitch|endwhile|eval|exit|extends|final|finally|for|foreach|function|global|goto|if|implements|include|include_once|instanceof|insteadof|interface|isset|list|namespace|new|or|parent|print|private|protected|public|require|require_once|return|static|switch|throw|trait|try|unset|use|var|while|xor|yield)\b/i, + 'boolean': { + pattern: /\b(?:false|true)\b/i, + alias: 'constant' }, - /@[\w.$]+/ - ], - 'string': { - pattern: /(^|[^@\\])("|')(?:\\[\s\S]|(?!\2)[^\\]|\2\2)*\2/, - greedy: true, - lookbehind: true - }, - 'function': /\b(?:AVG|COUNT|FIRST|FORMAT|LAST|LCASE|LEN|MAX|MID|MIN|MOD|NOW|ROUND|SUM|UCASE)(?=\s*\()/i, // Should we highlight user defined functions too? - 'keyword': /\b(?:ACTION|ADD|AFTER|ALGORITHM|ALL|ALTER|ANALYZE|ANY|APPLY|AS|ASC|AUTHORIZATION|AUTO_INCREMENT|BACKUP|BDB|BEGIN|BERKELEYDB|BIGINT|BINARY|BIT|BLOB|BOOL|BOOLEAN|BREAK|BROWSE|BTREE|BULK|BY|CALL|CASCADED?|CASE|CHAIN|CHAR(?:ACTER|SET)?|CHECK(?:POINT)?|CLOSE|CLUSTERED|COALESCE|COLLATE|COLUMNS?|COMMENT|COMMIT(?:TED)?|COMPUTE|CONNECT|CONSISTENT|CONSTRAINT|CONTAINS(?:TABLE)?|CONTINUE|CONVERT|CREATE|CROSS|CURRENT(?:_DATE|_TIME|_TIMESTAMP|_USER)?|CURSOR|CYCLE|DATA(?:BASES?)?|DATE(?:TIME)?|DAY|DBCC|DEALLOCATE|DEC|DECIMAL|DECLARE|DEFAULT|DEFINER|DELAYED|DELETE|DELIMITERS?|DENY|DESC|DESCRIBE|DETERMINISTIC|DISABLE|DISCARD|DISK|DISTINCT|DISTINCTROW|DISTRIBUTED|DO|DOUBLE|DROP|DUMMY|DUMP(?:FILE)?|DUPLICATE|ELSE(?:IF)?|ENABLE|ENCLOSED|END|ENGINE|ENUM|ERRLVL|ERRORS|ESCAPED?|EXCEPT|EXEC(?:UTE)?|EXISTS|EXIT|EXPLAIN|EXTENDED|FETCH|FIELDS|FILE|FILLFACTOR|FIRST|FIXED|FLOAT|FOLLOWING|FOR(?: EACH ROW)?|FORCE|FOREIGN|FREETEXT(?:TABLE)?|FROM|FULL|FUNCTION|GEOMETRY(?:COLLECTION)?|GLOBAL|GOTO|GRANT|GROUP|HANDLER|HASH|HAVING|HOLDLOCK|HOUR|IDENTITY(?:_INSERT|COL)?|IF|IGNORE|IMPORT|INDEX|INFILE|INNER|INNODB|INOUT|INSERT|INT|INTEGER|INTERSECT|INTERVAL|INTO|INVOKER|ISOLATION|ITERATE|JOIN|KEYS?|KILL|LANGUAGE|LAST|LEAVE|LEFT|LEVEL|LIMIT|LINENO|LINES|LINESTRING|LOAD|LOCAL|LOCK|LONG(?:BLOB|TEXT)|LOOP|MATCH(?:ED)?|MEDIUM(?:BLOB|INT|TEXT)|MERGE|MIDDLEINT|MINUTE|MODE|MODIFIES|MODIFY|MONTH|MULTI(?:LINESTRING|POINT|POLYGON)|NATIONAL|NATURAL|NCHAR|NEXT|NO|NONCLUSTERED|NULLIF|NUMERIC|OFF?|OFFSETS?|ON|OPEN(?:DATASOURCE|QUERY|ROWSET)?|OPTIMIZE|OPTION(?:ALLY)?|ORDER|OUT(?:ER|FILE)?|OVER|PARTIAL|PARTITION|PERCENT|PIVOT|PLAN|POINT|POLYGON|PRECEDING|PRECISION|PREPARE|PREV|PRIMARY|PRINT|PRIVILEGES|PROC(?:EDURE)?|PUBLIC|PURGE|QUICK|RAISERROR|READS?|REAL|RECONFIGURE|REFERENCES|RELEASE|RENAME|REPEAT(?:ABLE)?|REPLACE|REPLICATION|REQUIRE|RESIGNAL|RESTORE|RESTRICT|RETURNS?|REVOKE|RIGHT|ROLLBACK|ROUTINE|ROW(?:COUNT|GUIDCOL|S)?|RTREE|RULE|SAVE(?:POINT)?|SCHEMA|SECOND|SELECT|SERIAL(?:IZABLE)?|SESSION(?:_USER)?|SET(?:USER)?|SHARE|SHOW|SHUTDOWN|SIMPLE|SMALLINT|SNAPSHOT|SOME|SONAME|SQL|START(?:ING)?|STATISTICS|STATUS|STRIPED|SYSTEM_USER|TABLES?|TABLESPACE|TEMP(?:ORARY|TABLE)?|TERMINATED|TEXT(?:SIZE)?|THEN|TIME(?:STAMP)?|TINY(?:BLOB|INT|TEXT)|TOP?|TRAN(?:SACTIONS?)?|TRIGGER|TRUNCATE|TSEQUAL|TYPES?|UNBOUNDED|UNCOMMITTED|UNDEFINED|UNION|UNIQUE|UNLOCK|UNPIVOT|UNSIGNED|UPDATE(?:TEXT)?|USAGE|USE|USER|USING|VALUES?|VAR(?:BINARY|CHAR|CHARACTER|YING)|VIEW|WAITFOR|WARNINGS|WHEN|WHERE|WHILE|WITH(?: ROLLUP|IN)?|WORK|WRITE(?:TEXT)?|YEAR)\b/i, - 'boolean': /\b(?:TRUE|FALSE|NULL)\b/i, - 'number': /\b0x[\da-f]+\b|\b\d+\.?\d*|\B\.\d+\b/i, - 'operator': /[-+*\/=%^~]|&&?|\|\|?|!=?|<(?:=>?|<|>)?|>[>=]?|\b(?:AND|BETWEEN|IN|LIKE|NOT|OR|IS|DIV|REGEXP|RLIKE|SOUNDS LIKE|XOR)\b/i, - 'punctuation': /[;[\]()`,.]/ -}; + 'constant': [ + /\b[A-Z_][A-Z0-9_]*\b/, + /\b(?:null)\b/i, + ], + 'comment': { + pattern: /(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/, + lookbehind: true + } + }); -Prism.languages.scss = Prism.languages.extend('css', { - 'comment': { - pattern: /(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/, - lookbehind: true - }, - 'atrule': { - pattern: /@[\w-]+(?:\([^()]+\)|[^(])*?(?=\s+[{;])/, - inside: { - 'rule': /@[\w-]+/ - // See rest below + Prism.languages.insertBefore('php', 'string', { + 'shell-comment': { + pattern: /(^|[^\\])#.*/, + lookbehind: true, + alias: 'comment' } - }, - // 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('php', 'comment', { + 'delimiter': { + pattern: /\?>$|^<\?(?:php(?=\s)|=)?/i, + alias: 'important' } - }, - 'property': { - pattern: /(?:[\w-]|\$[-\w]+|#\{\$[-\w]+\})+(?=\s*:)/, - inside: { - 'variable': /\$[-\w]+|#\{\$[-\w]+\}/ + }); + + Prism.languages.insertBefore('php', 'keyword', { + 'variable': /\$+(?:\w+\b|(?={))/i, + 'package': { + pattern: /(\\|namespace\s+|use\s+)[\w\\]+/, + lookbehind: true, + inside: { + punctuation: /\\/ + } } - } -}); + }); -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)(?= )/, + // Must be defined after the function pattern + Prism.languages.insertBefore('php', 'operator', { + 'property': { + pattern: /(->)[\w]+/, lookbehind: true } - ] -}); + }); -Prism.languages.insertBefore('scss', 'important', { - // var and interpolated vars - 'variable': /\$[-\w]+|#\{\$[-\w]+\}/ -}); + var string_interpolation = { + pattern: /{\$(?:{(?:{[^{}]+}|[^{}]+)}|[^{}])+}|(^|[^\\{])\$+(?:\w+(?:\[.+?]|->\w+)*)/, + lookbehind: true, + inside: Prism.languages.php + }; -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': { - pattern: /\bnull\b/, - alias: 'keyword' - }, - 'operator': { - pattern: /(\s)(?:[-+*\/%]|[=!]=|<=?|>=?|and|or|not)(?=\s)/, - lookbehind: true - } -}); + Prism.languages.insertBefore('php', 'string', { + 'nowdoc-string': { + pattern: /<<<'([^']+)'(?:\r\n?|\n)(?:.*(?:\r\n?|\n))*?\1;/, + greedy: true, + alias: 'string', + inside: { + 'delimiter': { + pattern: /^<<<'[^']+'|[a-z_]\w*;$/i, + alias: 'symbol', + inside: { + 'punctuation': /^<<<'?|[';]$/ + } + } + } + }, + 'heredoc-string': { + pattern: /<<<(?:"([^"]+)"(?:\r\n?|\n)(?:.*(?:\r\n?|\n))*?\1;|([a-z_]\w*)(?:\r\n?|\n)(?:.*(?:\r\n?|\n))*?\2;)/i, + greedy: true, + alias: 'string', + inside: { + 'delimiter': { + pattern: /^<<<(?:"[^"]+"|[a-z_]\w*)|[a-z_]\w*;$/i, + alias: 'symbol', + inside: { + 'punctuation': /^<<<"?|[";]$/ + } + }, + 'interpolation': string_interpolation // See below + } + }, + 'single-quoted-string': { + pattern: /'(?:\\[\s\S]|[^\\'])*'/, + greedy: true, + alias: 'string' + }, + 'double-quoted-string': { + pattern: /"(?:\\[\s\S]|[^\\"])*"/, + greedy: true, + alias: 'string', + inside: { + 'interpolation': string_interpolation // See below + } + } + }); + // The different types of PHP strings "replace" the C-like standard string + delete Prism.languages.php['string']; -Prism.languages.scss['atrule'].inside.rest = Prism.languages.scss; + Prism.hooks.add('before-tokenize', function(env) { + if (!/<\?/.test(env.code)) { + return; + } + + var phpPattern = /<\?(?:[^"'/#]|\/(?![*/])|("|')(?:\\[\s\S]|(?!\1)[^\\])*\1|(?:\/\/|#)(?:[^?\n\r]|\?(?!>))*(?=$|\?>|[\r\n])|\/\*[\s\S]*?(?:\*\/|$))*?(?:\?>|$)/ig; + Prism.languages['markup-templating'].buildPlaceholders(env, 'php', phpPattern); + }); + + Prism.hooks.add('after-tokenize', function(env) { + Prism.languages['markup-templating'].tokenizePlaceholders(env, 'php'); + }); + +}(Prism)); Prism.languages.python = { 'comment': { @@ -2580,7 +2574,7 @@ Prism.languages.python = { lookbehind: true }, 'decorator': { - pattern: /(^\s*)@\w+(?:\.\w+)*/i, + pattern: /(^\s*)@\w+(?:\.\w+)*/im, lookbehind: true, alias: ['annotation', 'punctuation'], inside: { @@ -2598,138 +2592,139 @@ Prism.languages.python = { Prism.languages.python['string-interpolation'].inside['interpolation'].inside.rest = Prism.languages.python; Prism.languages.py = Prism.languages.python; + (function(Prism) { - var javascript = Prism.util.clone(Prism.languages.javascript); +var javascript = Prism.util.clone(Prism.languages.javascript); - Prism.languages.jsx = Prism.languages.extend('markup', javascript); - Prism.languages.jsx.tag.pattern= /<\/?(?:[\w.:-]+\s*(?:\s+(?:[\w.:-]+(?:=(?:("|')(?:\\[\s\S]|(?!\1)[^\\])*\1|[^\s{'">=]+|\{(?:\{(?:\{[^}]*\}|[^{}])*\}|[^{}])+\}))?|\{\.{3}[a-z_$][\w$]*(?:\.[a-z_$][\w$]*)*\}))*\s*\/?)?>/i; +Prism.languages.jsx = Prism.languages.extend('markup', javascript); +Prism.languages.jsx.tag.pattern= /<\/?(?:[\w.:-]+\s*(?:\s+(?:[\w.:$-]+(?:=(?:("|')(?:\\[\s\S]|(?!\1)[^\\])*\1|[^\s{'">=]+|\{(?:\{(?:\{[^}]*\}|[^{}])*\}|[^{}])+\}))?|\{\s*\.{3}\s*[a-z_$][\w$]*(?:\.[a-z_$][\w$]*)*\s*\}))*\s*\/?)?>/i; - Prism.languages.jsx.tag.inside['tag'].pattern = /^<\/?[^\s>\/]*/i; - Prism.languages.jsx.tag.inside['attr-value'].pattern = /=(?!\{)(?:("|')(?:\\[\s\S]|(?!\1)[^\\])*\1|[^\s'">]+)/i; - Prism.languages.jsx.tag.inside['tag'].inside['class-name'] = /^[A-Z]\w*(?:\.[A-Z]\w*)*$/; +Prism.languages.jsx.tag.inside['tag'].pattern = /^<\/?[^\s>\/]*/i; +Prism.languages.jsx.tag.inside['attr-value'].pattern = /=(?!\{)(?:("|')(?:\\[\s\S]|(?!\1)[^\\])*\1|[^\s'">]+)/i; +Prism.languages.jsx.tag.inside['tag'].inside['class-name'] = /^[A-Z]\w*(?:\.[A-Z]\w*)*$/; - Prism.languages.insertBefore('inside', 'attr-name', { - 'spread': { - pattern: /\{\.{3}[a-z_$][\w$]*(?:\.[a-z_$][\w$]*)*\}/, - inside: { - 'punctuation': /\.{3}|[{}.]/, - 'attr-value': /\w+/ - } +Prism.languages.insertBefore('inside', 'attr-name', { + 'spread': { + pattern: /\{\s*\.{3}\s*[a-z_$][\w$]*(?:\.[a-z_$][\w$]*)*\s*\}/, + inside: { + 'punctuation': /\.{3}|[{}.]/, + 'attr-value': /\w+/ } - }, Prism.languages.jsx.tag); + } +}, Prism.languages.jsx.tag); - Prism.languages.insertBefore('inside', 'attr-value',{ - 'script': { - // Allow for two levels of nesting - pattern: /=(\{(?:\{(?:\{[^}]*\}|[^}])*\}|[^}])+\})/i, - inside: { - 'script-punctuation': { - pattern: /^=(?={)/, - alias: 'punctuation' - }, - rest: Prism.languages.jsx +Prism.languages.insertBefore('inside', 'attr-value',{ + 'script': { + // Allow for two levels of nesting + pattern: /=(?:\{(?:\{(?:\{[^}]*\}|[^}])*\}|[^}])+\})/i, + inside: { + 'script-punctuation': { + pattern: /^=(?={)/, + alias: 'punctuation' }, - 'alias': 'language-javascript' - } - }, Prism.languages.jsx.tag); + rest: Prism.languages.jsx + }, + 'alias': 'language-javascript' + } +}, Prism.languages.jsx.tag); // The following will handle plain text inside tags - var stringifyToken = function (token) { - if (!token) { - return ''; - } - if (typeof token === 'string') { - return token; - } - if (typeof token.content === 'string') { - return token.content; - } - return token.content.map(stringifyToken).join(''); - }; +var stringifyToken = function (token) { + if (!token) { + return ''; + } + if (typeof token === 'string') { + return token; + } + if (typeof token.content === 'string') { + return token.content; + } + return token.content.map(stringifyToken).join(''); +}; - var walkTokens = function (tokens) { - var openedTags = []; - for (var i = 0; i < tokens.length; i++) { - var token = tokens[i]; - var notTagNorBrace = false; - - if (typeof token !== 'string') { - if (token.type === 'tag' && token.content[0] && token.content[0].type === 'tag') { - // We found a tag, now find its kind - - if (token.content[0].content[0].content === ' 0 && openedTags[openedTags.length - 1].tagName === stringifyToken(token.content[0].content[1])) { - // Pop matching opening tag - openedTags.pop(); - } +var walkTokens = function (tokens) { + var openedTags = []; + for (var i = 0; i < tokens.length; i++) { + var token = tokens[i]; + var notTagNorBrace = false; + + if (typeof token !== 'string') { + if (token.type === 'tag' && token.content[0] && token.content[0].type === 'tag') { + // We found a tag, now find its kind + + if (token.content[0].content[0].content === ' 0 && openedTags[openedTags.length - 1].tagName === stringifyToken(token.content[0].content[1])) { + // Pop matching opening tag + openedTags.pop(); + } + } else { + if (token.content[token.content.length - 1].content === '/>') { + // Autoclosed tag, ignore } else { - if (token.content[token.content.length - 1].content === '/>') { - // Autoclosed tag, ignore - } else { - // Opening tag - openedTags.push({ - tagName: stringifyToken(token.content[0].content[1]), - openedBraces: 0 - }); - } + // Opening tag + openedTags.push({ + tagName: stringifyToken(token.content[0].content[1]), + openedBraces: 0 + }); } - } else if (openedTags.length > 0 && token.type === 'punctuation' && token.content === '{') { + } + } else if (openedTags.length > 0 && token.type === 'punctuation' && token.content === '{') { - // Here we might have entered a JSX context inside a tag - openedTags[openedTags.length - 1].openedBraces++; + // Here we might have entered a JSX context inside a tag + openedTags[openedTags.length - 1].openedBraces++; - } else if (openedTags.length > 0 && openedTags[openedTags.length - 1].openedBraces > 0 && token.type === 'punctuation' && token.content === '}') { + } else if (openedTags.length > 0 && openedTags[openedTags.length - 1].openedBraces > 0 && token.type === 'punctuation' && token.content === '}') { - // Here we might have left a JSX context inside a tag - openedTags[openedTags.length - 1].openedBraces--; + // Here we might have left a JSX context inside a tag + openedTags[openedTags.length - 1].openedBraces--; - } else { - notTagNorBrace = true - } + } else { + notTagNorBrace = true } - if (notTagNorBrace || typeof token === 'string') { - if (openedTags.length > 0 && openedTags[openedTags.length - 1].openedBraces === 0) { - // Here we are inside a tag, and not inside a JSX context. - // That's plain text: drop any tokens matched. - var plainText = stringifyToken(token); - - // And merge text with adjacent text - if (i < tokens.length - 1 && (typeof tokens[i + 1] === 'string' || tokens[i + 1].type === 'plain-text')) { - plainText += stringifyToken(tokens[i + 1]); - tokens.splice(i + 1, 1); - } - if (i > 0 && (typeof tokens[i - 1] === 'string' || tokens[i - 1].type === 'plain-text')) { - plainText = stringifyToken(tokens[i - 1]) + plainText; - tokens.splice(i - 1, 1); - i--; - } + } + if (notTagNorBrace || typeof token === 'string') { + if (openedTags.length > 0 && openedTags[openedTags.length - 1].openedBraces === 0) { + // Here we are inside a tag, and not inside a JSX context. + // That's plain text: drop any tokens matched. + var plainText = stringifyToken(token); - tokens[i] = new Prism.Token('plain-text', plainText, null, plainText); + // And merge text with adjacent text + if (i < tokens.length - 1 && (typeof tokens[i + 1] === 'string' || tokens[i + 1].type === 'plain-text')) { + plainText += stringifyToken(tokens[i + 1]); + tokens.splice(i + 1, 1); + } + if (i > 0 && (typeof tokens[i - 1] === 'string' || tokens[i - 1].type === 'plain-text')) { + plainText = stringifyToken(tokens[i - 1]) + plainText; + tokens.splice(i - 1, 1); + i--; } - } - if (token.content && typeof token.content !== 'string') { - walkTokens(token.content); + tokens[i] = new Prism.Token('plain-text', plainText, null, plainText); } } - }; - Prism.hooks.add('after-tokenize', function (env) { - if (env.language !== 'jsx' && env.language !== 'tsx') { - return; + if (token.content && typeof token.content !== 'string') { + walkTokens(token.content); } - walkTokens(env.tokens); - }); + } +}; + +Prism.hooks.add('after-tokenize', function (env) { + if (env.language !== 'jsx' && env.language !== 'tsx') { + return; + } + walkTokens(env.tokens); +}); }(Prism)); /* TODO - Add support for Markdown notation inside doc comments - Add support for nested block comments... - Match closure params even when not followed by dash or brace - Add better support for macro definition + Add support for Markdown notation inside doc comments + Add support for nested block comments... + Match closure params even when not followed by dash or brace + Add better support for macro definition */ Prism.languages.rust = { @@ -2780,7 +2775,7 @@ Prism.languages.rust = { }, // Hex, oct, bin, dec numbers with visual separators and type suffix - 'number': /\b(?:0x[\dA-Fa-f](?:_?[\dA-Fa-f])*|0o[0-7](?:_?[0-7])*|0b[01](?:_?[01])*|(\d(?:_?\d)*)?\.?\d(?:_?\d)*(?:[Ee][+-]?\d+)?)(?:_?(?:[iu](?:8|16|32|64)?|f32|f64))?\b/, + 'number': /\b(?:0x[\dA-Fa-f](?:_?[\dA-Fa-f])*|0o[0-7](?:_?[0-7])*|0b[01](?:_?[01])*|(?:\d(?:_?\d)*)?\.?\d(?:_?\d)*(?:[Ee][+-]?\d+)?)(?:_?(?:[iu](?:8|16|32|64)?|f32|f64))?\b/, // Closure params should not be confused with bitwise OR | 'closure-params': { @@ -2794,6 +2789,160 @@ Prism.languages.rust = { 'operator': /[-+*\/%!^]=?|=[=>]?|&[&=]?|\|[|=]?|<>?=?|[@?]/ }; +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]+\}/ + } + }, + 'property': { + pattern: /(?:[\w-]|\$[-\w]+|#\{\$[-\w]+\})+(?=\s*:)/, + inside: { + '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.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': { + pattern: /\bnull\b/, + alias: 'keyword' + }, + 'operator': { + pattern: /(\s)(?:[-+*\/%]|[=!]=|<=?|>=?|and|or|not)(?=\s)/, + lookbehind: true + } +}); + +Prism.languages.scss['atrule'].inside.rest = Prism.languages.scss; + +(function (Prism) { + + // CAREFUL! + // The following patterns are concatenated, so the group referenced by a back reference is non-obvious! + + var strings = [ + // normal string + // 1 capturing group + /(["'])(?:\\[\s\S]|\$\([^)]+\)|`[^`]+`|(?!\1)[^\\])*\1/.source, + + // here doc + // 1 capturing group + /<<-?\s*(\w+?)\s*(?:\r?\n|\r)[\s\S]*?(?:\r?\n|\r)\2/.source, + + // here doc quoted + // 2 capturing group + /<<-?\s*(["'])(\w+)\3\s*(?:\r?\n|\r)[\s\S]*?(?:\r?\n|\r)\4/.source + ].join('|'); + + Prism.languages['shell-session'] = { + 'command': { + pattern: RegExp(/\$(?:[^\r\n'"<]|<>)+/.source.replace(/<>/g, strings)), + inside: { + 'bash': { + pattern: /(\$\s*)[\s\S]+/, + lookbehind: true, + alias: 'language-bash', + inside: Prism.languages.bash + }, + 'sh': { + pattern: /^\$/, + alias: 'important' + } + } + }, + 'output': { + pattern: /.(?:.*(?:\r\n?|\n|.$))*/ + // output highlighting? + } + }; + +}(Prism)); + +Prism.languages.sql = { + 'comment': { + pattern: /(^|[^\\])(?:\/\*[\s\S]*?\*\/|(?:--|\/\/|#).*)/, + lookbehind: true + }, + 'variable': [ + { + pattern: /@(["'`])(?:\\[\s\S]|(?!\1)[^\\])+\1/, + greedy: true + }, + /@[\w.$]+/ + ], + 'string': { + pattern: /(^|[^@\\])("|')(?:\\[\s\S]|(?!\2)[^\\]|\2\2)*\2/, + greedy: true, + lookbehind: true + }, + 'function': /\b(?:AVG|COUNT|FIRST|FORMAT|LAST|LCASE|LEN|MAX|MID|MIN|MOD|NOW|ROUND|SUM|UCASE)(?=\s*\()/i, // Should we highlight user defined functions too? + 'keyword': /\b(?:ACTION|ADD|AFTER|ALGORITHM|ALL|ALTER|ANALYZE|ANY|APPLY|AS|ASC|AUTHORIZATION|AUTO_INCREMENT|BACKUP|BDB|BEGIN|BERKELEYDB|BIGINT|BINARY|BIT|BLOB|BOOL|BOOLEAN|BREAK|BROWSE|BTREE|BULK|BY|CALL|CASCADED?|CASE|CHAIN|CHAR(?:ACTER|SET)?|CHECK(?:POINT)?|CLOSE|CLUSTERED|COALESCE|COLLATE|COLUMNS?|COMMENT|COMMIT(?:TED)?|COMPUTE|CONNECT|CONSISTENT|CONSTRAINT|CONTAINS(?:TABLE)?|CONTINUE|CONVERT|CREATE|CROSS|CURRENT(?:_DATE|_TIME|_TIMESTAMP|_USER)?|CURSOR|CYCLE|DATA(?:BASES?)?|DATE(?:TIME)?|DAY|DBCC|DEALLOCATE|DEC|DECIMAL|DECLARE|DEFAULT|DEFINER|DELAYED|DELETE|DELIMITERS?|DENY|DESC|DESCRIBE|DETERMINISTIC|DISABLE|DISCARD|DISK|DISTINCT|DISTINCTROW|DISTRIBUTED|DO|DOUBLE|DROP|DUMMY|DUMP(?:FILE)?|DUPLICATE|ELSE(?:IF)?|ENABLE|ENCLOSED|END|ENGINE|ENUM|ERRLVL|ERRORS|ESCAPED?|EXCEPT|EXEC(?:UTE)?|EXISTS|EXIT|EXPLAIN|EXTENDED|FETCH|FIELDS|FILE|FILLFACTOR|FIRST|FIXED|FLOAT|FOLLOWING|FOR(?: EACH ROW)?|FORCE|FOREIGN|FREETEXT(?:TABLE)?|FROM|FULL|FUNCTION|GEOMETRY(?:COLLECTION)?|GLOBAL|GOTO|GRANT|GROUP|HANDLER|HASH|HAVING|HOLDLOCK|HOUR|IDENTITY(?:_INSERT|COL)?|IF|IGNORE|IMPORT|INDEX|INFILE|INNER|INNODB|INOUT|INSERT|INT|INTEGER|INTERSECT|INTERVAL|INTO|INVOKER|ISOLATION|ITERATE|JOIN|KEYS?|KILL|LANGUAGE|LAST|LEAVE|LEFT|LEVEL|LIMIT|LINENO|LINES|LINESTRING|LOAD|LOCAL|LOCK|LONG(?:BLOB|TEXT)|LOOP|MATCH(?:ED)?|MEDIUM(?:BLOB|INT|TEXT)|MERGE|MIDDLEINT|MINUTE|MODE|MODIFIES|MODIFY|MONTH|MULTI(?:LINESTRING|POINT|POLYGON)|NATIONAL|NATURAL|NCHAR|NEXT|NO|NONCLUSTERED|NULLIF|NUMERIC|OFF?|OFFSETS?|ON|OPEN(?:DATASOURCE|QUERY|ROWSET)?|OPTIMIZE|OPTION(?:ALLY)?|ORDER|OUT(?:ER|FILE)?|OVER|PARTIAL|PARTITION|PERCENT|PIVOT|PLAN|POINT|POLYGON|PRECEDING|PRECISION|PREPARE|PREV|PRIMARY|PRINT|PRIVILEGES|PROC(?:EDURE)?|PUBLIC|PURGE|QUICK|RAISERROR|READS?|REAL|RECONFIGURE|REFERENCES|RELEASE|RENAME|REPEAT(?:ABLE)?|REPLACE|REPLICATION|REQUIRE|RESIGNAL|RESTORE|RESTRICT|RETURNS?|REVOKE|RIGHT|ROLLBACK|ROUTINE|ROW(?:COUNT|GUIDCOL|S)?|RTREE|RULE|SAVE(?:POINT)?|SCHEMA|SECOND|SELECT|SERIAL(?:IZABLE)?|SESSION(?:_USER)?|SET(?:USER)?|SHARE|SHOW|SHUTDOWN|SIMPLE|SMALLINT|SNAPSHOT|SOME|SONAME|SQL|START(?:ING)?|STATISTICS|STATUS|STRIPED|SYSTEM_USER|TABLES?|TABLESPACE|TEMP(?:ORARY|TABLE)?|TERMINATED|TEXT(?:SIZE)?|THEN|TIME(?:STAMP)?|TINY(?:BLOB|INT|TEXT)|TOP?|TRAN(?:SACTIONS?)?|TRIGGER|TRUNCATE|TSEQUAL|TYPES?|UNBOUNDED|UNCOMMITTED|UNDEFINED|UNION|UNIQUE|UNLOCK|UNPIVOT|UNSIGNED|UPDATE(?:TEXT)?|USAGE|USE|USER|USING|VALUES?|VAR(?:BINARY|CHAR|CHARACTER|YING)|VIEW|WAITFOR|WARNINGS|WHEN|WHERE|WHILE|WITH(?: ROLLUP|IN)?|WORK|WRITE(?:TEXT)?|YEAR)\b/i, + 'boolean': /\b(?:TRUE|FALSE|NULL)\b/i, + 'number': /\b0x[\da-f]+\b|\b\d+\.?\d*|\B\.\d+\b/i, + 'operator': /[-+*\/=%^~]|&&?|\|\|?|!=?|<(?:=>?|<|>)?|>[>=]?|\b(?:AND|BETWEEN|IN|LIKE|NOT|OR|IS|DIV|REGEXP|RLIKE|SOUNDS LIKE|XOR)\b/i, + 'punctuation': /[;[\]()`,.]/ +}; + +Prism.languages.typescript = Prism.languages.extend('javascript', { + // From JavaScript Prism keyword list and TypeScript language spec: https://github.com/Microsoft/TypeScript/blob/master/doc/spec.md#221-reserved-words + 'keyword': /\b(?:abstract|as|async|await|break|case|catch|class|const|constructor|continue|debugger|declare|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|is|keyof|let|module|namespace|new|null|of|package|private|protected|public|readonly|return|require|set|static|super|switch|this|throw|try|type|typeof|undefined|var|void|while|with|yield)\b/, + 'builtin': /\b(?:string|Function|any|number|boolean|Array|symbol|console|Promise|unknown|never)\b/, +}); + +Prism.languages.ts = Prism.languages.typescript; + Prism.languages.yaml = { 'scalar': { pattern: /([\-:]\s*(?:![^\s]+)?[ \t]*[|>])[ \t]*(?:((?:\r?\n|\r)[ \t]+)[^\r\n]+(?:\2[^\r\n]+)*)/,