[devdocsgjs/main: 563/1867] Update Prism.js to support Groovy syntax highlighting




commit b7964605efa3fabbd858756f2a67e88ace06a879
Author: Jasper van Merle <jaspervmerle gmail com>
Date:   Sun Jan 27 16:22:06 2019 +0100

    Update Prism.js to support Groovy syntax highlighting

 assets/javascripts/vendor/prism.js | 545 +++++++++++++++++++++++++------------
 1 file changed, 364 insertions(+), 181 deletions(-)
---
diff --git a/assets/javascripts/vendor/prism.js b/assets/javascripts/vendor/prism.js
index 09d6df87..50b344be 100644
--- a/assets/javascripts/vendor/prism.js
+++ b/assets/javascripts/vendor/prism.js
@@ -1,5 +1,5 @@
 /* PrismJS 1.15.0
-https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript+c+bash+cpp+coffeescript+ruby+d+dart+django+elixir+markup-templating+erlang+go+java+json+kotlin+lua+crystal+nginx+nim+perl+php+sql+scss+python+jsx+typescript+rust+yaml
 */
+https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript+c+bash+cpp+coffeescript+ruby+d+dart+django+elixir+markup-templating+erlang+go+groovy+java+json+kotlin+lua+crystal+nginx+nim+perl+php+sql+scss+python+jsx+typescript+rust+yaml
 */
 var _self = (typeof window !== 'undefined')
        ? window   // if in browser
        : (
@@ -35,7 +35,7 @@ var _ = _self.Prism = {
                },
 
                type: function (o) {
-                       return Object.prototype.toString.call(o).match(/\[object (\w+)\]/)[1];
+                       return Object.prototype.toString.call(o).slice(8, -1);
                },
 
                objId: function (obj) {
@@ -98,56 +98,46 @@ var _ = _self.Prism = {
                /**
                 * 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.
+                * we cannot just provide an object, we need an object 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 before The key to insert before.
                 * @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];
+                                       // Do not insert token which also occur in insert. See #1525
+                                       if (!insert.hasOwnProperty(token)) {
+                                               ret[token] = grammar[token];
+                                       }
                                }
                        }
 
+                       var old = root[inside];
+                       root[inside] = ret;
+
                        // Update references in other language definitions
                        _.languages.DFS(_.languages, function(key, value) {
-                               if (value === root[inside] && key != inside) {
+                               if (value === old && key != inside) {
                                        this[key] = ret;
                                }
                        });
 
-                       return root[inside] = ret;
+                       return ret;
                },
 
                // Traverse a language definition with Depth First Search
@@ -224,53 +214,48 @@ var _ = _self.Prism = {
                        code: code
                };
 
+               var insertHighlightedCode = function (highlightedCode) {
+                       env.highlightedCode = highlightedCode;
+
+                       _.hooks.run('before-insert', env);
+
+                       env.element.innerHTML = env.highlightedCode;
+
+                       _.hooks.run('after-highlight', env);
+                       _.hooks.run('complete', env);
+                       callback && callback.call(env.element);
+               }
+
                _.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);
-                       }
+               if (!env.code) {
                        _.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);
+               if (!env.grammar) {
+                       insertHighlightedCode(_.util.encode(env.code));
+                       return;
+               }
 
-                       env.element.innerHTML = env.highlightedCode;
+               if (async && _self.Worker) {
+                       var worker = new Worker(_.filename);
 
-                       callback && callback.call(element);
+                       worker.onmessage = function(evt) {
+                               insertHighlightedCode(evt.data);
+                       };
 
-                       _.hooks.run('after-highlight', env);
-                       _.hooks.run('complete', env);
-               // }
+                       worker.postMessage(JSON.stringify({
+                               language: env.language,
+                               code: env.code,
+                               immediateClose: true
+                       }));
+               }
+               else {
+                       insertHighlightedCode(_.highlight(env.code, env.grammar, env.language));
+               }
        },
 
        highlight: function (text, grammar, language) {
@@ -413,7 +398,7 @@ var _ = _self.Prism = {
                }
        },
 
-       tokenize: function(text, grammar, language) {
+       tokenize: function(text, grammar) {
                var strarr = [text];
 
                var rest = grammar.rest;
@@ -501,49 +486,49 @@ Token.stringify = function(o, language, parent) {
 
 };
 
-// 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);
-//             }
-//     }
-// }
+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;
 
@@ -610,7 +595,7 @@ Prism.hooks.add('wrap', function(env) {
        }
 });
 
-Prism.languages.xml = Prism.languages.markup;
+Prism.languages.xml = Prism.languages.extend('markup', {});
 Prism.languages.html = Prism.languages.markup;
 Prism.languages.mathml = Prism.languages.markup;
 Prism.languages.svg = Prism.languages.markup;
@@ -618,7 +603,7 @@ Prism.languages.svg = Prism.languages.markup;
 Prism.languages.css = {
        'comment': /\/\*[\s\S]*?\*\//,
        'atrule': {
-               pattern: /@[\w-]+?.*?(?:;|(?=\s*\{))/i,
+               pattern: /@[\w-]+?[\s\S]*?(?:;|(?=\s*\{))/i,
                inside: {
                        'rule': /@[\w-]+/
                        // See rest below
@@ -631,9 +616,9 @@ Prism.languages.css = {
                greedy: true
        },
        'property': /[-_a-z\xA0-\uFFFF][-\w\xA0-\uFFFF]*(?=\s*:)/i,
-       'important': /\B!important\b/i,
+       'important': /!important\b/i,
        'function': /[-a-z0-9]+(?=\()/i,
-       'punctuation': /[(){};:]/
+       'punctuation': /[(){};:,]/
 };
 
 Prism.languages.css['atrule'].inside.rest = Prism.languages.css;
@@ -666,7 +651,8 @@ if (Prism.languages.markup) {
                        alias: 'language-css'
                }
        }, Prism.languages.markup.tag);
-};
+}
+;
 Prism.languages.clike = {
        'comment': [
                {
@@ -692,31 +678,67 @@ Prism.languages.clike = {
        },
        '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,
+       'function': /\w+(?=\()/,
        'number': /\b0x[\da-f]+\b|(?:\b\d+\.?\d*|\B\.\d+)(?:e[+-]?\d+)?/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]+|NaN|Infinity)\b|(?:\b\d+\.?\d*|\B\.\d+)(?:[Ee][+-]?\d+)?/,
+       'class-name': [
+               Prism.languages.clike['class-name'],
+               {
+                       pattern: 
/(^|[^$\w\xA0-\uFFFF])[_$A-Z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\.(?:prototype|constructor))/,
+                       lookbehind: true
+               }
+       ],
+       'keyword': [
+               {
+                       pattern: /((?:^|})\s*)(?:catch|finally)\b/,
+                       lookbehind: true
+               },
+               
/\b(?:as|async|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|var|void|while|with|yield)\b/
+       ],
+       'number': 
/\b(?:(?:0[xX][\dA-Fa-f]+|0[bB][01]+|0[oO][0-7]+)n?|\d+n|NaN|Infinity)\b|(?:\b\d+\.?\d*|\B\.\d+)(?:[Ee][+-]?\d+)?/,
        // Allow for all non-ASCII characters (See http://stackoverflow.com/a/2008444)
-       'function': /[_$a-z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\s*\()/i,
+       'function': /[_$a-zA-Z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\s*\(|\.(?:apply|bind|call)\()/,
        '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])+\/[gimyu]{0,5}(?=\s*($|[\r\n,.;})\]]))/,
+               pattern: 
/((?:^|[^$\w\xA0-\uFFFF."'\])\s])\s*)\/(\[(?:[^\]\\\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-z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\s*=\s*(?:function\b|(?:\([^()]*\)|[_$a-z\xA0-\uFFFF][$\w\xA0-\uFFFF]*)\s*=>))/i,
+               pattern: 
/[_$a-z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\([^()]*\)|[_$a-z\xA0-\uFFFF][$\w\xA0-\uFFFF]*)\s*=>))/i,
                alias: 'function'
        },
+       'parameter': [
+               {
+                       pattern: 
/(function(?:\s+[_$a-z\xA0-\uFFFF][$\w\xA0-\uFFFF]*)?\s*\(\s*)[^\s()][^()]*?(?=\s*\))/,
+                       lookbehind: true,
+                       inside: Prism.languages.javascript
+               },
+               {
+                       pattern: /[_$a-z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\s*=>)/,
+                       inside: Prism.languages.javascript
+               },
+               {
+                       pattern: /(\(\s*)[^\s()][^()]*?(?=\s*\)\s*=>)/,
+                       lookbehind: true,
+                       inside: Prism.languages.javascript
+               },
+               {
+                       pattern: 
/((?:\b|\s|^)(?!(?: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)(?![$\w\xA0-\uFFFF]))(?:[_$a-z\xA0-\uFFFF][$\w\xA0-\uFFFF]*\s*)\(\s*)[^\s()][^()]*?(?=\s*\)\s*\{)/,
+                       lookbehind: true,
+                       inside: Prism.languages.javascript
+               }
+       ],
        'constant': /\b[A-Z][A-Z\d_]*\b/
 });
 
@@ -732,14 +754,13 @@ Prism.languages.insertBefore('javascript', 'string', {
                                                pattern: /^\${|}$/,
                                                alias: 'punctuation'
                                        },
-                                       rest: null // See below
+                                       rest: Prism.languages.javascript
                                }
                        },
                        'string': /[\s\S]+/
                }
        }
 });
-Prism.languages.javascript['template-string'].inside['interpolation'].inside.rest = 
Prism.languages.javascript;
 
 if (Prism.languages.markup) {
        Prism.languages.insertBefore('markup', 'tag', {
@@ -756,9 +777,13 @@ 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': /-[>-]?|\+\+?|!=?|<<?=?|>>?=?|==?|&&?|\|\|?|[~^%?*\/]/,
-       'number': /(?:\b0x[\da-f]+|(?:\b\d+\.?\d*|\B\.\d+)(?:e[+-]?\d+)?)[ful]*/i
+       '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', {
@@ -786,7 +811,6 @@ Prism.languages.insertBefore('c', 'string', {
        'constant': 
/\b(?:__FILE__|__LINE__|__DATE__|__TIME__|__TIMESTAMP__|__func__|EOF|NULL|SEEK_CUR|SEEK_END|SEEK_SET|stdin|stdout|stderr)\b/
 });
 
-delete Prism.languages.c['class-name'];
 delete Prism.languages.c['boolean'];
 
 (function(Prism) {
@@ -848,7 +872,7 @@ delete Prism.languages.c['boolean'];
                '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|curl|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|r
 
sync|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;|&])/,
+                       pattern: 
/(^|[\s;|&])(?:alias|apropos|apt|apt-cache|apt-get|aptitude|aspell|automysqlbackup|awk|basename|bash|bc|bconsole|bg|builtin|bzip2|cal|cat|cd|cfdisk|chgrp|chkconfig|chmod|chown|chroot|cksum|clear|cmp|comm|command|cp|cron|crontab|csplit|curl|cut|date|dc|dd|ddrescue|debootstrap|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|gparted|grep|groupadd|groupdel|groupmod|groups|grub-mkconfig|gzip|halt|hash|head|help|hg|history|host|hostname|htop|iconv|id|ifconfig|ifdown|ifup|import|install|ip|jobs|join|kill|killall|less|link|ln|locate|logname|logout|logrotate|look|lpc|lpr|lprint|lprintd|lprintq|lprm|ls|lsof|lynx|make|man|mc|mdadm|mkconfig|mkdir|mke2fs|mkfifo|mkfs|mkisofs|mknod|mkswap|mmv|more|most|mount|mtools|mtr|mutt|mv|nano|nc|netstat|nice|nl|nohup|notify-send|npm|nslookup|op|open|parted|passwd|paste|pathchk|ping|pkill|p
 
opd|pr|printcap|printenv|printf|ps|pushd|pv|pwd|quota|quotacheck|quotactl|ram|rar|rcp|read|readarray|readonly|reboot|remsync|rename|renice|rev|rm|rmdir|rpm|rsync|scp|screen|sdiff|sed|sendmail|seq|service|sftp|shift|shopt|shutdown|sleep|slocate|sort|source|split|ssh|stat|strace|su|sudo|sum|suspend|swapon|sync|tail|tar|tee|test|time|timeout|times|top|touch|tr|traceroute|trap|tsort|tty|type|ulimit|umask|umount|unalias|uname|unexpand|uniq|units|unrar|unshar|unzip|update-grub|uptime|useradd|userdel|usermod|users|uudecode|uuencode|vdir|vi|vim|virsh|vmstat|wait|watch|wc|wget|whereis|which|who|whoami|write|xargs|xdg-open|yes|zip|zypper)(?=$|[\s;|&])/,
                        lookbehind: true
                },
                'keyword': {
@@ -875,16 +899,13 @@ delete Prism.languages.c['boolean'];
 })(Prism);
 
 Prism.languages.cpp = Prism.languages.extend('c', {
-       'keyword': 
/\b(?:alignas|alignof|asm|auto|bool|break|case|catch|char|char16_t|char32_t|class|compl|const|constexpr|const_cast|continue|decltype|default|delete|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/,
-       'boolean': /\b(?:true|false)\b/,
-       'operator': 
/--?|\+\+?|!=?|<{1,2}=?|>{1,2}=?|->|:{1,2}|={1,2}|\^|~|%|&{1,2}|\|\|?|\?|\*|\/|\b(?:and|and_eq|bitand|bitor|not|not_eq|or|or_eq|xor|xor_eq)\b/
-});
-
-Prism.languages.insertBefore('cpp', 'keyword', {
        'class-name': {
-               pattern: /(class\s+)\w+/i,
+               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/,
+       'boolean': /\b(?:true|false)\b/,
+       'operator': 
/>>=?|<<=?|->|([-+&|:])\1|[?:~]|[-+*/%&|^!=<>]=?|\b(?:and|and_eq|bitand|bitor|not|not_eq|or|or_eq|xor|xor_eq)\b/
 });
 
 Prism.languages.insertBefore('cpp', 'string', {
@@ -985,6 +1006,7 @@ Prism.languages.insertBefore('coffeescript', 'keyword', {
 
 delete Prism.languages.coffeescript['template-string'];
 
+Prism.languages.coffee = Prism.languages.coffeescript;
 }(Prism));
 /**
  * Original by Samuel Flores
@@ -1015,6 +1037,8 @@ delete Prism.languages.coffeescript['template-string'];
                }
        };
 
+       delete Prism.languages.ruby.function;
+
        Prism.languages.insertBefore('ruby', 'keyword', {
                'regex': [
                        {
@@ -1063,6 +1087,14 @@ delete Prism.languages.coffeescript['template-string'];
                'symbol': {
                        pattern: /(^|[^:]):[a-zA-Z_]\w*(?:[?!]|\b)/,
                        lookbehind: true
+               },
+               'method-definition': {
+                       pattern: /(\bdef\s+)[\w.]+/,
+                       lookbehind: true,
+                       inside: {
+                               'function': /\w+$/,
+                               rest: Prism.languages.ruby
+                       }
                }
        });
 
@@ -1116,7 +1148,10 @@ delete Prism.languages.coffeescript['template-string'];
                        }
                }
        ];
+
+       Prism.languages.rb = Prism.languages.ruby;
 }(Prism));
+
 Prism.languages.d = Prism.languages.extend('clike', {
        'string': [
                // r"", x""
@@ -1487,16 +1522,38 @@ Prism.languages.go = Prism.languages.extend('clike', {
 });
 delete Prism.languages.go['class-name'];
 
-Prism.languages.java = Prism.languages.extend('clike', {
-       'keyword': 
/\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)\b/,
-       'number': /\b0b[01]+\b|\b0x[\da-f]*\.?[\da-fp-]+\b|(?:\b\d+\.?\d*|\B\.\d+)(?:e[+-]?\d+)?[df]?/i,
+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])*?\/\$/,
+                       greedy: true
+               },
+               {
+                       pattern: /(["'\/])(?:\\.|(?!\1)[^\\\r\n])*\1/,
+                       greedy: true
+               }
+       ],
+       'number': 
/\b(?:0b[01_]+|0x[\da-f_]+(?:\.[\da-f_p\-]+)?|[\d_]+(?:\.[\d_]+)?(?:e[+-]?[\d]+)?)[glidf]?\b/i,
        'operator': {
-               pattern: 
/(^|[^.])(?:\+[+=]?|-[-=]?|!=?|<<?=?|>>?>?=?|==?|&[&=]?|\|[|=]?|\*=?|\/=?|%=?|\^=?|[?:~])/m,
+               pattern: 
/(^|[^.])(?:~|==?~?|\?[.:]?|\*(?:[.=]|\*=?)?|\.[@&]|\.\.<|\.{1,2}(?!\.)|-[-=>]?|\+[+=]?|!=?|<(?:<=?|=>?)?|>(?:>>?=?|=)?|&[&=]?|\|[|=]?|\/=?|\^=?|%=?)/,
                lookbehind: true
+       },
+       'punctuation': /\.+|[{}[\];(),:$]/
+});
+
+Prism.languages.insertBefore('groovy', 'string', {
+       'shebang': {
+               pattern: /#!.+/,
+               alias: 'comment'
        }
 });
 
-Prism.languages.insertBefore('java','function', {
+Prism.languages.insertBefore('groovy', 'punctuation', {
+       'spock-block': /\b(?:setup|given|when|then|and|cleanup|expect|where):/
+});
+
+Prism.languages.insertBefore('groovy', 'function', {
        'annotation': {
                alias: 'punctuation',
                pattern: /(^|[^.])@\w+/,
@@ -1504,28 +1561,103 @@ Prism.languages.insertBefore('java','function', {
        }
 });
 
-Prism.languages.insertBefore('java', 'class-name', {
-       'generics': {
-               pattern: /<\s*\w+(?:\.\w+)?(?:\s*,\s*\w+(?:\.\w+)?)*>/i,
-               alias: 'function',
-               inside: {
-                       keyword: Prism.languages.java.keyword,
-                       punctuation: /[<>(),.:]/
+// Handle string interpolation
+Prism.hooks.add('wrap', function(env) {
+       if (env.language === 'groovy' && env.type === 'string') {
+               var delimiter = env.content[0];
+
+               if (delimiter != "'") {
+                       var pattern = /([^\\])(?:\$(?:\{.*?\}|[\w.]+))/;
+                       if (delimiter === '$') {
+                               pattern = /([^\$])(?:\$(?:\{.*?\}|[\w.]+))/;
+                       }
+
+                       // To prevent double HTML-encoding we have to decode env.content first
+                       env.content = env.content.replace(/&lt;/g, '<').replace(/&amp;/g, '&');
+
+                       env.content = Prism.highlight(env.content, {
+                               'expression': {
+                                       pattern: pattern,
+                                       lookbehind: true,
+                                       inside: Prism.languages.groovy
+                               }
+                       });
+
+                       env.classes.push(delimiter === '/' ? 'regex' : 'gstring');
                }
        }
 });
 
+(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/;
+
+       // based on the java naming conventions
+       var className = /\b[A-Z](?:\w*[a-z]\w*)?\b/;
+
+       Prism.languages.java = Prism.languages.extend('clike', {
+               'class-name': [
+                       className,
+
+                       // variables and parameters
+                       // this to support class names (or generic parameters) which do not contain a lower 
case letter (also works for methods)
+                       /\b[A-Z]\w*(?=\s+\w+\s*[;,=())])/
+               ],
+               'keyword': keywords,
+               'function': [
+                       Prism.languages.clike.function,
+                       {
+                               pattern: /(\:\:)[a-z_]\w*/,
+                               lookbehind: true
+                       }
+               ],
+               '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,
+                       lookbehind: true
+               }
+       });
+
+       Prism.languages.insertBefore('java', 'class-name', {
+               'annotation': {
+                       alias: 'punctuation',
+                       pattern: /(^|[^.])@\w+/,
+                       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*)+/,
+                       lookbehind: true,
+                       inside: {
+                               'punctuation': /\./,
+                       }
+               },
+               'generics': {
+                       pattern: /<(?:[\w\s,.&?]|<(?:[\w\s,.&?]|<(?:[\w\s,.&?]|<[\w\s,.&?]*>)*>)*>)*>/,
+                       inside: {
+                               'class-name': className,
+                               'keyword': keywords,
+                               'punctuation': /[<>(),.:]/,
+                               'operator': /[?&|]/
+                       }
+               }
+       });
+}(Prism));
+
 Prism.languages.json = {
-       'property': /"(?:\\.|[^\\"\r\n])*"(?=\s*:)/i,
+       'comment': /\/\/.*|\/\*[\s\S]*?(?:\*\/|$)/,
+       'property': {
+               pattern: /"(?:\\.|[^\\"\r\n])*"(?=\s*:)/,
+               greedy: true
+       },
        'string': {
                pattern: /"(?:\\.|[^\\"\r\n])*"(?!\s*:)/,
                greedy: true
        },
-       'number': /-?\d+\.?\d*([Ee][+-]?\d+)?/,
+       'number': /-?\d+\.?\d*(e[+-]?\d+)?/i,
        'punctuation': /[{}[\],]/,
-       'operator': /:/g,
-       'boolean': /\b(?:true|false)\b/i,
-       'null': /\bnull\b/i
+       'operator': /:/,
+       'boolean': /\b(?:true|false)\b/,
+       'null': /\bnull\b/
 };
 
 Prism.languages.jsonp = Prism.languages.json;
@@ -1670,12 +1802,13 @@ Prism.languages.nginx = Prism.languages.extend('clike', {
                pattern: /(^|[^"{\\])#.*/,
                lookbehind: true
        },
-       'keyword': 
/\b(?:CONTENT_|DOCUMENT_|GATEWAY_|HTTP_|HTTPS|if_not_empty|PATH_|QUERY_|REDIRECT_|REMOTE_|REQUEST_|SCGI|SCRIPT_|SERVER_|http|events|accept_mutex|accept_mutex_delay|access_log|add_after_body|add_before_body|add_header|addition_types|aio|alias|allow|ancient_browser|ancient_browser_value|auth|auth_basic|auth_basic_user_file|auth_http|auth_http_header|auth_http_timeout|autoindex|autoindex_exact_size|autoindex_localtime|break|charset|charset_map|charset_types|chunked_transfer_encoding|client_body_buffer_size|client_body_in_file_only|client_body_in_single_buffer|client_body_temp_path|client_body_timeout|client_header_buffer_size|client_header_timeout|client_max_body_size|connection_pool_size|create_full_put_path|daemon|dav_access|dav_methods|debug_connection|debug_points|default_type|deny|devpoll_changes|devpoll_events|directio|directio_alignment|disable_symlinks|empty_gif|env|epoll_events|error_log|error_page|expires|fastcgi_buffer_size|fastcgi_buffers|fastcgi_busy_buffers_si
 
ze|fastcgi_cache|fastcgi_cache_bypass|fastcgi_cache_key|fastcgi_cache_lock|fastcgi_cache_lock_timeout|fastcgi_cache_methods|fastcgi_cache_min_uses|fastcgi_cache_path|fastcgi_cache_purge|fastcgi_cache_use_stale|fastcgi_cache_valid|fastcgi_connect_timeout|fastcgi_hide_header|fastcgi_ignore_client_abort|fastcgi_ignore_headers|fastcgi_index|fastcgi_intercept_errors|fastcgi_keep_conn|fastcgi_max_temp_file_size|fastcgi_next_upstream|fastcgi_no_cache|fastcgi_param|fastcgi_pass|fastcgi_pass_header|fastcgi_read_timeout|fastcgi_redirect_errors|fastcgi_send_timeout|fastcgi_split_path_info|fastcgi_store|fastcgi_store_access|fastcgi_temp_file_write_size|fastcgi_temp_path|flv|geo|geoip_city|geoip_country|google_perftools_profiles|gzip|gzip_buffers|gzip_comp_level|gzip_disable|gzip_http_version|gzip_min_length|gzip_proxied|gzip_static|gzip_types|gzip_vary|if|if_modified_since|ignore_invalid_headers|image_filter|image_filter_buffer|image_filter_jpeg_quality|image_filter_sharpen|image_filter_transpa
 
rency|imap_capabilities|imap_client_buffer|include|index|internal|ip_hash|keepalive|keepalive_disable|keepalive_requests|keepalive_timeout|kqueue_changes|kqueue_events|large_client_header_buffers|limit_conn|limit_conn_log_level|limit_conn_zone|limit_except|limit_rate|limit_rate_after|limit_req|limit_req_log_level|limit_req_zone|limit_zone|lingering_close|lingering_time|lingering_timeout|listen|location|lock_file|log_format|log_format_combined|log_not_found|log_subrequest|map|map_hash_bucket_size|map_hash_max_size|master_process|max_ranges|memcached_buffer_size|memcached_connect_timeout|memcached_next_upstream|memcached_pass|memcached_read_timeout|memcached_send_timeout|merge_slashes|min_delete_depth|modern_browser|modern_browser_value|mp4|mp4_buffer_size|mp4_max_buffer_size|msie_padding|msie_refresh|multi_accept|open_file_cache|open_file_cache_errors|open_file_cache_min_uses|open_file_cache_valid|open_log_file_cache|optimize_server_names|override_charset|pcre_jit|perl|perl_modules|p
 
erl_require|perl_set|pid|pop3_auth|pop3_capabilities|port_in_redirect|post_action|postpone_output|protocol|proxy|proxy_buffer|proxy_buffer_size|proxy_buffering|proxy_buffers|proxy_busy_buffers_size|proxy_cache|proxy_cache_bypass|proxy_cache_key|proxy_cache_lock|proxy_cache_lock_timeout|proxy_cache_methods|proxy_cache_min_uses|proxy_cache_path|proxy_cache_use_stale|proxy_cache_valid|proxy_connect_timeout|proxy_cookie_domain|proxy_cookie_path|proxy_headers_hash_bucket_size|proxy_headers_hash_max_size|proxy_hide_header|proxy_http_version|proxy_ignore_client_abort|proxy_ignore_headers|proxy_intercept_errors|proxy_max_temp_file_size|proxy_method|proxy_next_upstream|proxy_no_cache|proxy_pass|proxy_pass_error_message|proxy_pass_header|proxy_pass_request_body|proxy_pass_request_headers|proxy_read_timeout|proxy_redirect|proxy_redirect_errors|proxy_send_lowat|proxy_send_timeout|proxy_set_body|proxy_set_header|proxy_ssl_session_reuse|proxy_store|proxy_store_access|proxy_temp_file_write_size|pr
 
oxy_temp_path|proxy_timeout|proxy_upstream_fail_timeout|proxy_upstream_max_fails|random_index|read_ahead|real_ip_header|recursive_error_pages|request_pool_size|reset_timedout_connection|resolver|resolver_timeout|return|rewrite|root|rtsig_overflow_events|rtsig_overflow_test|rtsig_overflow_threshold|rtsig_signo|satisfy|satisfy_any|secure_link_secret|send_lowat|send_timeout|sendfile|sendfile_max_chunk|server|server_name|server_name_in_redirect|server_names_hash_bucket_size|server_names_hash_max_size|server_tokens|set|set_real_ip_from|smtp_auth|smtp_capabilities|so_keepalive|source_charset|split_clients|ssi|ssi_silent_errors|ssi_types|ssi_value_length|ssl|ssl_certificate|ssl_certificate_key|ssl_ciphers|ssl_client_certificate|ssl_crl|ssl_dhparam|ssl_engine|ssl_prefer_server_ciphers|ssl_protocols|ssl_session_cache|ssl_session_timeout|ssl_verify_client|ssl_verify_depth|starttls|stub_status|sub_filter|sub_filter_once|sub_filter_types|tcp_nodelay|tcp_nopush|timeout|timer_resolution|try_files
 
|types|types_hash_bucket_size|types_hash_max_size|underscores_in_headers|uninitialized_variable_warn|upstream|use|user|userid|userid_domain|userid_expires|userid_name|userid_p3p|userid_path|userid_service|valid_referers|variables_hash_bucket_size|variables_hash_max_size|worker_connections|worker_cpu_affinity|worker_priority|worker_processes|worker_rlimit_core|worker_rlimit_nofile|worker_rlimit_sigpending|working_directory|xclient|xml_entities|xslt_entities|xslt_stylesheet|xslt_types)\b/i
+       'keyword': 
/\b(?:CONTENT_|DOCUMENT_|GATEWAY_|HTTP_|HTTPS|if_not_empty|PATH_|QUERY_|REDIRECT_|REMOTE_|REQUEST_|SCGI|SCRIPT_|SERVER_|http|events|accept_mutex|accept_mutex_delay|access_log|add_after_body|add_before_body|add_header|addition_types|aio|alias|allow|ancient_browser|ancient_browser_value|auth|auth_basic|auth_basic_user_file|auth_http|auth_http_header|auth_http_timeout|autoindex|autoindex_exact_size|autoindex_localtime|break|charset|charset_map|charset_types|chunked_transfer_encoding|client_body_buffer_size|client_body_in_file_only|client_body_in_single_buffer|client_body_temp_path|client_body_timeout|client_header_buffer_size|client_header_timeout|client_max_body_size|connection_pool_size|create_full_put_path|daemon|dav_access|dav_methods|debug_connection|debug_points|default_type|deny|devpoll_changes|devpoll_events|directio|directio_alignment|disable_symlinks|empty_gif|env|epoll_events|error_log|error_page|expires|fastcgi_buffer_size|fastcgi_buffers|fastcgi_busy_buffers_si
 
ze|fastcgi_cache|fastcgi_cache_bypass|fastcgi_cache_key|fastcgi_cache_lock|fastcgi_cache_lock_timeout|fastcgi_cache_methods|fastcgi_cache_min_uses|fastcgi_cache_path|fastcgi_cache_purge|fastcgi_cache_use_stale|fastcgi_cache_valid|fastcgi_connect_timeout|fastcgi_hide_header|fastcgi_ignore_client_abort|fastcgi_ignore_headers|fastcgi_index|fastcgi_intercept_errors|fastcgi_keep_conn|fastcgi_max_temp_file_size|fastcgi_next_upstream|fastcgi_no_cache|fastcgi_param|fastcgi_pass|fastcgi_pass_header|fastcgi_read_timeout|fastcgi_redirect_errors|fastcgi_send_timeout|fastcgi_split_path_info|fastcgi_store|fastcgi_store_access|fastcgi_temp_file_write_size|fastcgi_temp_path|flv|geo|geoip_city|geoip_country|google_perftools_profiles|gzip|gzip_buffers|gzip_comp_level|gzip_disable|gzip_http_version|gzip_min_length|gzip_proxied|gzip_static|gzip_types|gzip_vary|if|if_modified_since|ignore_invalid_headers|image_filter|image_filter_buffer|image_filter_jpeg_quality|image_filter_sharpen|image_filter_transpa
 
rency|imap_capabilities|imap_client_buffer|include|index|internal|ip_hash|keepalive|keepalive_disable|keepalive_requests|keepalive_timeout|kqueue_changes|kqueue_events|large_client_header_buffers|limit_conn|limit_conn_log_level|limit_conn_zone|limit_except|limit_rate|limit_rate_after|limit_req|limit_req_log_level|limit_req_zone|limit_zone|lingering_close|lingering_time|lingering_timeout|listen|location|lock_file|log_format|log_format_combined|log_not_found|log_subrequest|map|map_hash_bucket_size|map_hash_max_size|master_process|max_ranges|memcached_buffer_size|memcached_connect_timeout|memcached_next_upstream|memcached_pass|memcached_read_timeout|memcached_send_timeout|merge_slashes|min_delete_depth|modern_browser|modern_browser_value|mp4|mp4_buffer_size|mp4_max_buffer_size|msie_padding|msie_refresh|multi_accept|open_file_cache|open_file_cache_errors|open_file_cache_min_uses|open_file_cache_valid|open_log_file_cache|optimize_server_names|override_charset|pcre_jit|perl|perl_modules|p
 
erl_require|perl_set|pid|pop3_auth|pop3_capabilities|port_in_redirect|post_action|postpone_output|protocol|proxy|proxy_buffer|proxy_buffer_size|proxy_buffering|proxy_buffers|proxy_busy_buffers_size|proxy_cache|proxy_cache_bypass|proxy_cache_key|proxy_cache_lock|proxy_cache_lock_timeout|proxy_cache_methods|proxy_cache_min_uses|proxy_cache_path|proxy_cache_use_stale|proxy_cache_valid|proxy_connect_timeout|proxy_cookie_domain|proxy_cookie_path|proxy_headers_hash_bucket_size|proxy_headers_hash_max_size|proxy_hide_header|proxy_http_version|proxy_ignore_client_abort|proxy_ignore_headers|proxy_intercept_errors|proxy_max_temp_file_size|proxy_method|proxy_next_upstream|proxy_no_cache|proxy_pass|proxy_pass_error_message|proxy_pass_header|proxy_pass_request_body|proxy_pass_request_headers|proxy_read_timeout|proxy_redirect|proxy_redirect_errors|proxy_send_lowat|proxy_send_timeout|proxy_set_body|proxy_set_header|proxy_ssl_session_reuse|proxy_store|proxy_store_access|proxy_temp_file_write_size|pr
 
oxy_temp_path|proxy_timeout|proxy_upstream_fail_timeout|proxy_upstream_max_fails|random_index|read_ahead|real_ip_header|recursive_error_pages|request_pool_size|reset_timedout_connection|resolver|resolver_timeout|return|rewrite|root|rtsig_overflow_events|rtsig_overflow_test|rtsig_overflow_threshold|rtsig_signo|satisfy|satisfy_any|secure_link_secret|send_lowat|send_timeout|sendfile|sendfile_max_chunk|server|server_name|server_name_in_redirect|server_names_hash_bucket_size|server_names_hash_max_size|server_tokens|set|set_real_ip_from|smtp_auth|smtp_capabilities|so_keepalive|source_charset|split_clients|ssi|ssi_silent_errors|ssi_types|ssi_value_length|ssl|ssl_certificate|ssl_certificate_key|ssl_ciphers|ssl_client_certificate|ssl_crl|ssl_dhparam|ssl_engine|ssl_prefer_server_ciphers|ssl_protocols|ssl_session_cache|ssl_session_timeout|ssl_verify_client|ssl_verify_depth|starttls|stub_status|sub_filter|sub_filter_once|sub_filter_types|tcp_nodelay|tcp_nopush|timeout|timer_resolution|try_files
 
|types|types_hash_bucket_size|types_hash_max_size|underscores_in_headers|uninitialized_variable_warn|upstream|use|user|userid|userid_domain|userid_expires|userid_name|userid_p3p|userid_path|userid_service|valid_referers|variables_hash_bucket_size|variables_hash_max_size|worker_connections|worker_cpu_affinity|worker_priority|worker_processes|worker_rlimit_core|worker_rlimit_nofile|worker_rlimit_sigpending|working_directory|xclient|xml_entities|xslt_entities|xslt_stylesheet|xslt_types|ssl_session_tickets|ssl_stapling|ssl_stapling_verify|ssl_ecdh_curve|ssl_trusted_certificate|more_set_headers|ssl_early_data)\b/i
 });
 
 Prism.languages.insertBefore('nginx', 'keyword', {
        'variable': /\$[a-z_]+/i
 });
+
 Prism.languages.nim = {
        'comment': /#.*/,
        // Double-quoted strings can be prefixed by an identifier (Generalized raw string literals)
@@ -1915,8 +2048,15 @@ Prism.languages.perl = {
  */
 (function (Prism) {
        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/,
+               '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
@@ -1954,6 +2094,14 @@ Prism.languages.perl = {
                }
        });
 
+       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;/,
@@ -1981,7 +2129,7 @@ Prism.languages.perl = {
                                                'punctuation': /^<<<"?|[";]$/
                                        }
                                },
-                               'interpolation': null // See below
+                               'interpolation': string_interpolation // See below
                        }
                },
                'single-quoted-string': {
@@ -1994,23 +2142,13 @@ Prism.languages.perl = {
                        greedy: true,
                        alias: 'string',
                        inside: {
-                               'interpolation': null // See below
+                               'interpolation': string_interpolation // See below
                        }
                }
        });
        // The different types of PHP strings "replace" the C-like standard string
        delete Prism.languages.php['string'];
 
-       var string_interpolation = {
-               pattern: /{\$(?:{(?:{[^{}]+}|[^{}]+)}|[^{}])+}|(^|[^\\{])\$+(?:\w+(?:\[.+?]|->\w+)*)/,
-               lookbehind: true,
-               inside: {
-                       rest: Prism.languages.php
-               }
-       };
-       Prism.languages.php['heredoc-string'].inside['interpolation'] = string_interpolation;
-       Prism.languages.php['double-quoted-string'].inside['interpolation'] = string_interpolation;
-
        Prism.hooks.add('before-tokenize', function(env) {
                if (!/(?:<\?php|<\?)/ig.test(env.code)) {
                        return;
@@ -2025,17 +2163,23 @@ Prism.languages.perl = {
        });
 
 }(Prism));
-Prism.languages.sql= {
+Prism.languages.sql = {
        'comment': {
                pattern: /(^|[^\\])(?:\/\*[\s\S]*?\*\/|(?:--|\/\/|#).*)/,
                lookbehind: true
        },
-       'string' : {
-               pattern: /(^|[^@\\])("|')(?:\\[\s\S]|(?!\2)[^\\])*\2/,
+       'variable': [
+               {
+                       pattern: /@(["'`])(?:\\[\s\S]|(?!\1)[^\\])+\1/,
+                       greedy: true
+               },
+               /@[\w.$]+/
+       ],
+       'string': {
+               pattern: /(^|[^@\\])("|')(?:\\[\s\S]|(?!\2)[^\\]|\2\2)*\2/,
                greedy: true,
                lookbehind: true
        },
-       'variable': /@[\w.$]+|@(["'`])(?:\\[\s\S]|(?!\1)[^\\])+\1/,
        '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,
@@ -2043,6 +2187,7 @@ Prism.languages.sql= {
        'operator': 
/[-+*\/=%^~]|&&?|\|\|?|!=?|<(?:=>?|<|>)?|>[>=]?|\b(?:AND|BETWEEN|IN|LIKE|NOT|OR|IS|DIV|REGEXP|RLIKE|SOUNDS 
LIKE|XOR)\b/i,
        'punctuation': /[;[\]()`,.]/
 };
+
 Prism.languages.scss = Prism.languages.extend('css', {
        'comment': {
                pattern: /(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/,
@@ -2066,7 +2211,7 @@ Prism.languages.scss = Prism.languages.extend('css', {
        // 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,
+               pattern: /(?=\S)[^@;{}()]?(?:[^@;{}()]|#\{\$[-\w]+\})+(?=\s*\{(?:\}|\s|[^}]+[:{][^}]+))/m,
                inside: {
                        'parent': {
                                pattern: /&/,
@@ -2075,6 +2220,12 @@ Prism.languages.scss = Prism.languages.extend('css', {
                        'placeholder': /%[-\w]+/,
                        'variable': /\$[-\w]+|#\{\$[-\w]+\}/
                }
+       },
+       'property': {
+               pattern: /(?:[\w-]|\$[-\w]+|#\{\$[-\w]+\})+(?=\s*:)/,
+               inside: {
+                       'variable': /\$[-\w]+|#\{\$[-\w]+\}/
+               }
        }
 });
 
@@ -2088,13 +2239,6 @@ Prism.languages.insertBefore('scss', 'atrule', {
        ]
 });
 
-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]+\}/
@@ -2118,18 +2262,42 @@ Prism.languages.insertBefore('scss', 'function', {
 });
 
 Prism.languages.scss['atrule'].inside.rest = Prism.languages.scss;
+
 Prism.languages.python = {
        'comment': {
                pattern: /(^|[^\\])#.*/,
                lookbehind: true
        },
+       'string-interpolation': {
+               pattern: /(?:f|rf|fr)(?:("""|''')[\s\S]+?\1|("|')(?:\\.|(?!\2)[^\\\r\n])*\2)/i,
+               greedy: true,
+               inside: {
+                       'interpolation': {
+                               // "{" <expression> <optional "!s", "!r", or "!a"> <optional ":" format 
specifier> "}"
+                               pattern: 
/((?:^|[^{])(?:{{)*){(?!{)(?:[^{}]|{(?!{)(?:[^{}]|{(?!{)(?:[^{}])+})+})+}/,
+                               lookbehind: true,
+                               inside: {
+                                       'format-spec': {
+                                               pattern: /(:)[^:(){}]+(?=}$)/,
+                                               lookbehind: true
+                                       },
+                                       'conversion-option': {
+                                               pattern: /![sra](?=[:}]$)/,
+                                               alias: 'punctuation'
+                                       },
+                                       rest: null
+                               }
+                       },
+                       'string': /[\s\S]+/
+               }
+       },
        'triple-quoted-string': {
-               pattern: /("""|''')[\s\S]+?\1/,
+               pattern: /(?:[rub]|rb|br)?("""|''')[\s\S]+?\1/i,
                greedy: true,
                alias: 'string'
        },
        'string': {
-               pattern: /("|')(?:\\.|(?!\1)[^\\\r\n])*\1/,
+               pattern: /(?:[rub]|rb|br)?("|')(?:\\.|(?!\1)[^\\\r\n])*\1/i,
                greedy: true
        },
        'function': {
@@ -2140,14 +2308,25 @@ Prism.languages.python = {
                pattern: /(\bclass\s+)\w+/i,
                lookbehind: true
        },
-       'keyword': 
/\b(?:as|assert|async|await|break|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|nonlocal|pass|print|raise|return|try|while|with|yield)\b/,
-       
'builtin':/\b(?:__import__|abs|all|any|apply|ascii|basestring|bin|bool|buffer|bytearray|bytes|callable|chr|classmethod|cmp|coerce|compile|complex|delattr|dict|dir|divmod|enumerate|eval|execfile|file|filter|float|format|frozenset|getattr|globals|hasattr|hash|help|hex|id|input|int|intern|isinstance|issubclass|iter|len|list|locals|long|map|max|memoryview|min|next|object|oct|open|ord|pow|property|range|raw_input|reduce|reload|repr|reversed|round|set|setattr|slice|sorted|staticmethod|str|sum|super|tuple|type|unichr|unicode|vars|xrange|zip)\b/,
+       'decorator': {
+               pattern: /(^\s*)@\w+(?:\.\w+)*/i,
+               lookbehind: true,
+               alias: ['annotation', 'punctuation'],
+               inside: {
+                       'punctuation': /\./
+               }
+       },
+       'keyword': 
/\b(?:and|as|assert|async|await|break|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|nonlocal|not|or|pass|print|raise|return|try|while|with|yield)\b/,
+       'builtin': 
/\b(?:__import__|abs|all|any|apply|ascii|basestring|bin|bool|buffer|bytearray|bytes|callable|chr|classmethod|cmp|coerce|compile|complex|delattr|dict|dir|divmod|enumerate|eval|execfile|file|filter|float|format|frozenset|getattr|globals|hasattr|hash|help|hex|id|input|int|intern|isinstance|issubclass|iter|len|list|locals|long|map|max|memoryview|min|next|object|oct|open|ord|pow|property|range|raw_input|reduce|reload|repr|reversed|round|set|setattr|slice|sorted|staticmethod|str|sum|super|tuple|type|unichr|unicode|vars|xrange|zip)\b/,
        'boolean': /\b(?:True|False|None)\b/,
        'number': 
/(?:\b(?=\d)|\B(?=\.))(?:0[bo])?(?:(?:\d|0x[\da-f])[\da-f]*\.?\d*|\.\d+)(?:e[+-]?\d+)?j?\b/i,
-       'operator': /[-+%=]=?|!=|\*\*?=?|\/\/?=?|<[<=>]?|>[=>]?|[&|^~]|\b(?:or|and|not)\b/,
+       'operator': /[-+%=]=?|!=|\*\*?=?|\/\/?=?|<[<=>]?|>[=>]?|[&|^~]/,
        'punctuation': /[{}[\];(),.:]/
 };
 
+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);
@@ -2157,6 +2336,7 @@ Prism.languages.jsx.tag.pattern= /<\/?(?:[\w.:-]+\s*(?:\s+(?:[\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*$/;
 
 Prism.languages.insertBefore('inside', 'attr-name', {
        'spread': {
@@ -2276,11 +2456,12 @@ Prism.hooks.add('after-tokenize', function (env) {
 
 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(?: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|module|declare|constructor|namespace|abstract|require|type)\b/,
-       'builtin': /\b(?:string|Function|any|number|boolean|Array|symbol|console)\b/,
+       '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;
+
 /* TODO
        Add support for Markdown notation inside doc comments
        Add support for nested block comments...
@@ -2317,7 +2498,7 @@ Prism.languages.rust = {
                pattern: /'[^\s>']+/,
                alias: 'symbol'
        },
-       'keyword': 
/\b(?:abstract|alignof|as|be|box|break|const|continue|crate|do|else|enum|extern|false|final|fn|for|if|impl|in|let|loop|match|mod|move|mut|offsetof|once|override|priv|pub|pure|ref|return|sizeof|static|self|struct|super|true|trait|type|typeof|unsafe|unsized|use|virtual|where|while|yield)\b/,
+       'keyword': 
/\b(?:abstract|alignof|as|be|box|break|const|continue|crate|do|dyn|else|enum|extern|false|final|fn|for|if|impl|in|let|loop|match|mod|move|mut|offsetof|once|override|priv|pub|pure|ref|return|sizeof|static|self|Self|struct|super|true|trait|type|typeof|union|unsafe|unsized|use|virtual|where|while|yield)\b/,
 
        'attribute': {
                pattern: /#!?\[.+?\]/,
@@ -2382,7 +2563,7 @@ Prism.languages.yaml = {
                alias: 'important'
        },
        'string': {
-               pattern: /([:\-,[{]\s*(?:![^\s]+)?[ \t]*)("|')(?:(?!\2)[^\\\r\n]|\\.)*\2(?=[ 
\t]*(?:$|,|]|}))/m,
+               pattern: /([:\-,[{]\s*(?:![^\s]+)?[ \t]*)("|')(?:(?!\2)[^\\\r\n]|\\.)*\2(?=[ 
\t]*(?:$|,|]|}|\s*#))/m,
                lookbehind: true,
                greedy: true
        },
@@ -2394,3 +2575,5 @@ Prism.languages.yaml = {
        'important': /[&*][\w]+/,
        'punctuation': /---|[:[\]{}\-,|>?]|\.\.\./
 };
+
+Prism.languages.yml = Prism.languages.yaml;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]