help3xsl/README.prism.js.txt |    5 
 help3xsl/default.css         |    7 
 help3xsl/prism.css           |    6 
 help3xsl/prism.js            | 1069 ++++++++++++++++++++++++++++---------------
 4 files changed, 711 insertions(+), 376 deletions(-)

New commits:
commit ebbd4ee99be8172c6c62b8d6963feb7f7b72bfa1
Author:     Olivier Hallot <olivier.hal...@libreoffice.org>
AuthorDate: Fri May 29 16:45:56 2020 -0300
Commit:     Olivier Hallot <olivier.hal...@libreoffice.org>
CommitDate: Wed Jun 3 14:32:34 2020 +0200

    Update prism.js to latest version
    
    Update prism.js and companion css to latest version
    Fixes the Currency and Type keyword highlight
    Fixes line numbering interference with a11y-toggle.js
    
    Change-Id: Ibbb5c95790e1366f0a1dbc497d8741e69a0a3957
    Reviewed-on: https://gerrit.libreoffice.org/c/help/+/95173
    Tested-by: Jenkins
    Reviewed-by: Olivier Hallot <olivier.hal...@libreoffice.org>
    (cherry picked from commit 0c721f4ecf55911d125e33e3afea534d1ffe42b2)
    Reviewed-on: https://gerrit.libreoffice.org/c/help/+/95129
    Reviewed-by: Ilmari Lauhakangas <ilmari.lauhakan...@libreoffice.org>

diff --git a/help3xsl/README.prism.js.txt b/help3xsl/README.prism.js.txt
index 581a1fe71..fe0acc0d2 100644
--- a/help3xsl/README.prism.js.txt
+++ b/help3xsl/README.prism.js.txt
@@ -1,3 +1,7 @@
+Latest download version
+
+PrismJS 1.20.0
+
 Using prism.js for Basic code highlight
 
 http://prismjs.com
@@ -37,3 +41,4 @@ Add class 'language-visual-basic' and 'line-numbers' to 
<code> as in
     <div class="bascode" itemscope="true" 
itemtype="http://schema.org/SoftwareSourceCode"; itemprop="codeSampleType" 
content="snippet">
    <pre><code class="language-visual-basic line-numbers"><xsl:apply-templates 
/></code></pre></div>
 </xsl:template>
+
diff --git a/help3xsl/default.css b/help3xsl/default.css
index 0ae386088..76bf71c66 100644
--- a/help3xsl/default.css
+++ b/help3xsl/default.css
@@ -361,10 +361,11 @@ header {
     height: 60px;
     margin-right: 10px;
 }
-[aria-hidden='true'],
-[data-a11y-toggle]:not([aria-controls]) {
+
+[data-a11y-toggle]:not([aria-controls]){
   display: none;
 }
+
 #langs-nav:not([aria-hidden='true']), #modules-nav:not([aria-hidden='true']) {
     z-index: 100;
     /* line them up horizontally */
@@ -739,7 +740,7 @@ li.disabled a {
     }
 }
 @media screen and (min-width: 960px) {
-    #langs-nav {
+    #langs-nav, #modules-nav {
         display: none;
     }
     #langs-nav a {
diff --git a/help3xsl/prism.css b/help3xsl/prism.css
index 6e31d4d8f..8bd96d9cc 100644
--- a/help3xsl/prism.css
+++ b/help3xsl/prism.css
@@ -1,4 +1,4 @@
-/* PrismJS 1.15.0
+/* PrismJS 1.20.0
 
https://prismjs.com/download.html#themes=prism-coy&languages=markup+css+clike+javascript+python+visual-basic&plugins=line-numbers+normalize-whitespace
 */
 /**
  * prism.js Coy theme for JavaScript, CoffeeScript, CSS and HTML
@@ -11,6 +11,7 @@ pre[class*="language-"] {
        color: black;
        background: none;
        font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
+       font-size: 1em;
        text-align: left;
        white-space: pre;
        word-spacing: normal;
@@ -179,7 +180,7 @@ pre[class*="language-"]:after {
        cursor: help;
 }
 
-.namespace {
+.token.namespace {
        opacity: .7;
 }
 
@@ -255,7 +256,6 @@ pre[class*="language-"].line-numbers > code {
 }
 
        .line-numbers-rows > span {
-               pointer-events: none;
                display: block;
                counter-increment: linenumber;
        }
diff --git a/help3xsl/prism.js b/help3xsl/prism.js
index c085b09b0..108011888 100644
--- a/help3xsl/prism.js
+++ b/help3xsl/prism.js
@@ -1,4 +1,4 @@
-/* PrismJS 1.15.0
+/* PrismJS 1.20.0
 
https://prismjs.com/download.html#themes=prism-coy&languages=markup+css+clike+javascript+python+visual-basic&plugins=line-numbers+normalize-whitespace
 */
 var _self = (typeof window !== 'undefined')
        ? window   // if in browser
@@ -14,21 +14,22 @@ var _self = (typeof window !== 'undefined')
  * @author Lea Verou http://lea.verou.me
  */
 
-var Prism = (function(){
+var Prism = (function (_self){
 
 // Private helper vars
 var lang = /\blang(?:uage)?-([\w-]+)\b/i;
 var uniqueId = 0;
 
-var _ = _self.Prism = {
+
+var _ = {
        manual: _self.Prism && _self.Prism.manual,
        disableWorkerMessageHandler: _self.Prism && 
_self.Prism.disableWorkerMessageHandler,
        util: {
-               encode: function (tokens) {
+               encode: function encode(tokens) {
                        if (tokens instanceof Token) {
-                               return new Token(tokens.type, 
_.util.encode(tokens.content), tokens.alias);
-                       } else if (_.util.type(tokens) === 'Array') {
-                               return tokens.map(_.util.encode);
+                               return new Token(tokens.type, 
encode(tokens.content), tokens.alias);
+                       } else if (Array.isArray(tokens)) {
+                               return tokens.map(encode);
                        } else {
                                return tokens.replace(/&/g, 
'&amp;').replace(/</g, '&lt;').replace(/\u00a0/g, ' ');
                        }
@@ -46,41 +47,104 @@ var _ = _self.Prism = {
                },
 
                // Deep clone a language definition (e.g. to extend it)
-               clone: function (o, visited) {
-                       var type = _.util.type(o);
+               clone: function deepClone(o, visited) {
+                       var clone, id, type = _.util.type(o);
                        visited = visited || {};
 
                        switch (type) {
                                case 'Object':
-                                       if (visited[_.util.objId(o)]) {
-                                               return visited[_.util.objId(o)];
+                                       id = _.util.objId(o);
+                                       if (visited[id]) {
+                                               return visited[id];
                                        }
-                                       var clone = {};
-                                       visited[_.util.objId(o)] = clone;
+                                       clone = {};
+                                       visited[id] = clone;
 
                                        for (var key in o) {
                                                if (o.hasOwnProperty(key)) {
-                                                       clone[key] = 
_.util.clone(o[key], visited);
+                                                       clone[key] = 
deepClone(o[key], visited);
                                                }
                                        }
 
                                        return clone;
 
                                case 'Array':
-                                       if (visited[_.util.objId(o)]) {
-                                               return visited[_.util.objId(o)];
+                                       id = _.util.objId(o);
+                                       if (visited[id]) {
+                                               return visited[id];
                                        }
-                                       var clone = [];
-                                       visited[_.util.objId(o)] = clone;
+                                       clone = [];
+                                       visited[id] = clone;
 
                                        o.forEach(function (v, i) {
-                                               clone[i] = _.util.clone(v, 
visited);
+                                               clone[i] = deepClone(v, 
visited);
                                        });
 
                                        return clone;
+
+                               default:
+                                       return o;
                        }
+               },
 
-                       return o;
+               /**
+                * Returns the Prism language of the given element set by a 
`language-xxxx` or `lang-xxxx` class.
+                *
+                * If no language is set for the element or the element is 
`null` or `undefined`, `none` will be returned.
+                *
+                * @param {Element} element
+                * @returns {string}
+                */
+               getLanguage: function (element) {
+                       while (element && !lang.test(element.className)) {
+                               element = element.parentElement;
+                       }
+                       if (element) {
+                               return (element.className.match(lang) || [, 
'none'])[1].toLowerCase();
+                       }
+                       return 'none';
+               },
+
+               /**
+                * Returns the script element that is currently executing.
+                *
+                * This does __not__ work for line script element.
+                *
+                * @returns {HTMLScriptElement | null}
+                */
+               currentScript: function () {
+                       if (typeof document === 'undefined') {
+                               return null;
+                       }
+                       if ('currentScript' in document) {
+                               return document.currentScript;
+                       }
+
+                       // IE11 workaround
+                       // we'll get the src of the current script by parsing 
IE11's error stack trace
+                       // this will not work for inline scripts
+
+                       try {
+                               throw new Error();
+                       } catch (err) {
+                               // Get file src url from stack. Specifically 
works with the format of stack traces in IE.
+                               // A stack will look like this:
+                               //
+                               // Error
+                               //    at _.util.currentScript 
(http://localhost/components/prism-core.js:119:5)
+                               //    at Global code 
(http://localhost/components/prism-core.js:606:1)
+
+                               var src = (/at 
[^(\r\n]*\((.*):.+:.+\)$/i.exec(err.stack) || [])[1];
+                               if (src) {
+                                       var scripts = 
document.getElementsByTagName('script');
+                                       for (var i in scripts) {
+                                               if (scripts[i].src == src) {
+                                                       return scripts[i];
+                                               }
+                                       }
+                               }
+                               return null;
+                       }
                }
        },
 
@@ -98,45 +162,32 @@ 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];
+                                       }
                                }
                        }
 
@@ -154,19 +205,25 @@ var _ = _self.Prism = {
                },
 
                // Traverse a language definition with Depth First Search
-               DFS: function(o, callback, type, visited) {
+               DFS: function DFS(o, callback, type, visited) {
                        visited = visited || {};
+
+                       var objId = _.util.objId;
+
                        for (var i in o) {
                                if (o.hasOwnProperty(i)) {
                                        callback.call(o, i, o[i], type || i);
 
-                                       if (_.util.type(o[i]) === 'Object' && 
!visited[_.util.objId(o[i])]) {
-                                               visited[_.util.objId(o[i])] = 
true;
-                                               _.languages.DFS(o[i], callback, 
null, visited);
+                                       var property = o[i],
+                                           propertyType = 
_.util.type(property);
+
+                                       if (propertyType === 'Object' && 
!visited[objId(property)]) {
+                                               visited[objId(property)] = true;
+                                               DFS(property, callback, null, 
visited);
                                        }
-                                       else if (_.util.type(o[i]) === 'Array' 
&& !visited[_.util.objId(o[i])]) {
-                                               visited[_.util.objId(o[i])] = 
true;
-                                               _.languages.DFS(o[i], callback, 
i, visited);
+                                       else if (propertyType === 'Array' && 
!visited[objId(property)]) {
+                                               visited[objId(property)] = true;
+                                               DFS(property, callback, i, 
visited);
                                        }
                                }
                        }
@@ -181,41 +238,33 @@ var _ = _self.Prism = {
        highlightAllUnder: function(container, async, callback) {
                var env = {
                        callback: callback,
+                       container: container,
                        selector: 'code[class*="language-"], 
[class*="language-"] code, code[class*="lang-"], [class*="lang-"] code'
                };
 
-               _.hooks.run("before-highlightall", env);
+               _.hooks.run('before-highlightall', env);
 
-               var elements = env.elements || 
container.querySelectorAll(env.selector);
+               env.elements = 
Array.prototype.slice.apply(env.container.querySelectorAll(env.selector));
 
-               for (var i=0, element; element = elements[i++];) {
+               _.hooks.run('before-all-elements-highlight', env);
+
+               for (var i = 0, element; element = env.elements[i++];) {
                        _.highlightElement(element, async === true, 
env.callback);
                }
        },
 
        highlightElement: function(element, async, callback) {
                // Find language
-               var language, grammar, parent = element;
-
-               while (parent && !lang.test(parent.className)) {
-                       parent = parent.parentNode;
-               }
-
-               if (parent) {
-                       language = (parent.className.match(lang) || 
[,''])[1].toLowerCase();
-                       grammar = _.languages[language];
-               }
+               var language = _.util.getLanguage(element);
+               var grammar = _.languages[language];
 
                // Set language on the element, if not present
                element.className = element.className.replace(lang, 
'').replace(/\s+/g, ' ') + ' language-' + language;
 
-               if (element.parentNode) {
-                       // Set language on the parent, for styling
-                       parent = element.parentNode;
-
-                       if (/pre/i.test(parent.nodeName)) {
-                               parent.className = 
parent.className.replace(lang, '').replace(/\s+/g, ' ') + ' language-' + 
language;
-                       }
+               // Set language on the parent, for styling
+               var parent = element.parentNode;
+               if (parent && parent.nodeName.toLowerCase() === 'pre') {
+                       parent.className = parent.className.replace(lang, 
'').replace(/\s+/g, ' ') + ' language-' + language;
                }
 
                var code = element.textContent;
@@ -227,33 +276,38 @@ var _ = _self.Prism = {
                        code: code
                };
 
+               function insertHighlightedCode(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);
+                       callback && callback.call(env.element);
                        return;
                }
 
                _.hooks.run('before-highlight', env);
 
+               if (!env.grammar) {
+                       insertHighlightedCode(_.util.encode(env.code));
+                       return;
+               }
+
                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;
-
-                               _.hooks.run('after-highlight', env);
-                               _.hooks.run('complete', env);
-                               callback && callback.call(env.element);
+                               insertHighlightedCode(evt.data);
                        };
 
                        worker.postMessage(JSON.stringify({
@@ -263,17 +317,7 @@ var _ = _self.Prism = {
                        }));
                }
                else {
-                       env.highlightedCode = _.highlight(env.code, 
env.grammar, env.language);
-
-                       _.hooks.run('before-insert', env);
-
-                       env.element.innerHTML = env.highlightedCode;
-
-                       _.hooks.run('after-highlight', env);
-
-                       _.hooks.run('complete', env);
-
-                       callback && callback.call(element);
+                       insertHighlightedCode(_.highlight(env.code, 
env.grammar, env.language));
                }
        },
 
@@ -289,139 +333,8 @@ var _ = _self.Prism = {
                return Token.stringify(_.util.encode(env.tokens), env.language);
        },
 
-       matchGrammar: function (text, strarr, grammar, index, startPos, 
oneshot, target) {
-               var Token = _.Token;
-
-               for (var token in grammar) {
-                       if(!grammar.hasOwnProperty(token) || !grammar[token]) {
-                               continue;
-                       }
-
-                       if (token == target) {
-                               return;
-                       }
-
-                       var patterns = grammar[token];
-                       patterns = (_.util.type(patterns) === "Array") ? 
patterns : [patterns];
-
-                       for (var j = 0; j < patterns.length; ++j) {
-                               var pattern = patterns[j],
-                                       inside = pattern.inside,
-                                       lookbehind = !!pattern.lookbehind,
-                                       greedy = !!pattern.greedy,
-                                       lookbehindLength = 0,
-                                       alias = pattern.alias;
-
-                               if (greedy && !pattern.pattern.global) {
-                                       // Without the global flag, lastIndex 
won't work
-                                       var flags = 
pattern.pattern.toString().match(/[imuy]*$/)[0];
-                                       pattern.pattern = 
RegExp(pattern.pattern.source, flags + "g");
-                               }
-
-                               pattern = pattern.pattern || pattern;
-
-                               // Don’t cache length as it changes during the 
loop
-                               for (var i = index, pos = startPos; i < 
strarr.length; pos += strarr[i].length, ++i) {
-
-                                       var str = strarr[i];
-
-                                       if (strarr.length > text.length) {
-                                               // Something went terribly 
wrong, ABORT, ABORT!
-                                               return;
-                                       }
-
-                                       if (str instanceof Token) {
-                                               continue;
-                                       }
-
-                                       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),
-                                                   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;
-                                               }
-
-                                               // 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;
-                                               }
-
-                                               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];
-
-                                       if (before) {
-                                               ++i;
-                                               pos += before.length;
-                                               args.push(before);
-                                       }
-
-                                       var wrapped = new Token(token, inside? 
_.tokenize(match, inside) : match, alias, match, greedy);
-
-                                       args.push(wrapped);
-
-                                       if (after) {
-                                               args.push(after);
-                                       }
-
-                                       Array.prototype.splice.apply(strarr, 
args);
-
-                                       if (delNum != 1)
-                                               _.matchGrammar(text, strarr, 
grammar, i, pos, true, token);
-
-                                       if (oneshot)
-                                               break;
-                               }
-                       }
-               }
-       },
-
-       tokenize: function(text, grammar, language) {
-               var strarr = [text];
-
+       tokenize: function(text, grammar) {
                var rest = grammar.rest;
-
                if (rest) {
                        for (var token in rest) {
                                grammar[token] = rest[token];
@@ -430,9 +343,12 @@ var _ = _self.Prism = {
                        delete grammar.rest;
                }
 
-               _.matchGrammar(text, strarr, grammar, 0, 0, false);
+               var tokenList = new LinkedList();
+               addAfter(tokenList, tokenList.head, text);
+
+               matchGrammar(text, tokenList, grammar, tokenList.head, 0);
 
-               return strarr;
+               return toArray(tokenList);
        },
 
        hooks: {
@@ -457,58 +373,290 @@ var _ = _self.Prism = {
                                callback(env);
                        }
                }
-       }
+       },
+
+       Token: Token
 };
 
-var Token = _.Token = function(type, content, alias, matchedStr, greedy) {
+_self.Prism = _;
+
+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.length = (matchedStr || '').length|0;
        this.greedy = !!greedy;
-};
+}
 
-Token.stringify = function(o, language, parent) {
+Token.stringify = function stringify(o, language) {
        if (typeof o == 'string') {
                return o;
        }
-
-       if (_.util.type(o) === 'Array') {
-               return o.map(function(element) {
-                       return Token.stringify(element, language, o);
-               }).join('');
+       if (Array.isArray(o)) {
+               var s = '';
+               o.forEach(function (e) {
+                       s += stringify(e, language);
+               });
+               return s;
        }
 
        var env = {
                type: o.type,
-               content: Token.stringify(o.content, language, parent),
+               content: stringify(o.content, language),
                tag: 'span',
                classes: ['token', o.type],
                attributes: {},
-               language: language,
-               parent: parent
+               language: language
        };
 
-       if (o.alias) {
-               var aliases = _.util.type(o.alias) === 'Array' ? o.alias : 
[o.alias];
-               Array.prototype.push.apply(env.classes, aliases);
+       var aliases = o.alias;
+       if (aliases) {
+               if (Array.isArray(aliases)) {
+                       Array.prototype.push.apply(env.classes, aliases);
+               } else {
+                       env.classes.push(aliases);
+               }
        }
 
        _.hooks.run('wrap', env);
 
-       var attributes = Object.keys(env.attributes).map(function(name) {
-               return name + '="' + (env.attributes[name] || '').replace(/"/g, 
'&quot;') + '"';
-       }).join(' ');
-
-       return '<' + env.tag + ' class="' + env.classes.join(' ') + '"' + 
(attributes ? ' ' + attributes : '') + '>' + env.content + '</' + env.tag + '>';
+       var attributes = '';
+       for (var name in env.attributes) {
+               attributes += ' ' + name + '="' + (env.attributes[name] || 
'').replace(/"/g, '&quot;') + '"';
+       }
 
+       return '<' + env.tag + ' class="' + env.classes.join(' ') + '"' + 
attributes + '>' + env.content + '</' + env.tag + '>';
 };
 
+/**
+ * @param {string} text
+ * @param {LinkedList<string | Token>} tokenList
+ * @param {any} grammar
+ * @param {LinkedListNode<string | Token>} startNode
+ * @param {number} startPos
+ * @param {boolean} [oneshot=false]
+ * @param {string} [target]
+ */
+function matchGrammar(text, tokenList, grammar, startNode, startPos, oneshot, 
target) {
+       for (var token in grammar) {
+               if (!grammar.hasOwnProperty(token) || !grammar[token]) {
+                       continue;
+               }
+
+               var patterns = grammar[token];
+               patterns = Array.isArray(patterns) ? patterns : [patterns];
+
+               for (var j = 0; j < patterns.length; ++j) {
+                       if (target && target == token + ',' + j) {
+                               return;
+                       }
+
+                       var pattern = patterns[j],
+                               inside = pattern.inside,
+                               lookbehind = !!pattern.lookbehind,
+                               greedy = !!pattern.greedy,
+                               lookbehindLength = 0,
+                               alias = pattern.alias;
+
+                       if (greedy && !pattern.pattern.global) {
+                               // Without the global flag, lastIndex won't work
+                               var flags = 
pattern.pattern.toString().match(/[imsuy]*$/)[0];
+                               pattern.pattern = 
RegExp(pattern.pattern.source, flags + 'g');
+                       }
+
+                       pattern = pattern.pattern || pattern;
+
+                       for ( // iterate the token list and keep track of the 
current token/string position
+                               var currentNode = startNode.next, pos = 
startPos;
+                               currentNode !== tokenList.tail;
+                               pos += currentNode.value.length, currentNode = 
currentNode.next
+                       ) {
+
+                               var str = currentNode.value;
+
+                               if (tokenList.length > text.length) {
+                                       // Something went terribly wrong, 
ABORT, ABORT!
+                                       return;
+                               }
+
+                               if (str instanceof Token) {
+                                       continue;
+                               }
+
+                               var removeCount = 1; // this is the to 
parameter of removeBetween
+
+                               if (greedy && currentNode != 
tokenList.tail.prev) {
+                                       pattern.lastIndex = pos;
+                                       var match = pattern.exec(text);
+                                       if (!match) {
+                                               break;
+                                       }
+
+                                       var from = match.index + (lookbehind && 
match[1] ? match[1].length : 0);
+                                       var to = match.index + match[0].length;
+                                       var p = pos;
+
+                                       // find the node that contains the match
+                                       p += currentNode.value.length;
+                                       while (from >= p) {
+                                               currentNode = currentNode.next;
+                                               p += currentNode.value.length;
+                                       }
+                                       // adjust pos (and p)
+                                       p -= currentNode.value.length;
+                                       pos = p;
+
+                                       // the current node is a Token, then 
the match starts inside another Token, which is invalid
+                                       if (currentNode.value instanceof Token) 
{
+                                               continue;
+                                       }
+
+                                       // find the last node which is affected 
by this match
+                                       for (
+                                               var k = currentNode;
+                                               k !== tokenList.tail && (p < to 
|| (typeof k.value === 'string' && !k.prev.value.greedy));
+                                               k = k.next
+                                       ) {
+                                               removeCount++;
+                                               p += k.value.length;
+                                       }
+                                       removeCount--;
+
+                                       // replace with the new match
+                                       str = text.slice(pos, p);
+                                       match.index -= pos;
+                               } else {
+                                       pattern.lastIndex = 0;
+
+                                       var match = pattern.exec(str);
+                               }
+
+                               if (!match) {
+                                       if (oneshot) {
+                                               break;
+                                       }
+
+                                       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 removeFrom = currentNode.prev;
+
+                               if (before) {
+                                       removeFrom = addAfter(tokenList, 
removeFrom, before);
+                                       pos += before.length;
+                               }
+
+                               removeRange(tokenList, removeFrom, removeCount);
+
+                               var wrapped = new Token(token, inside ? 
_.tokenize(match, inside) : match, alias, match, greedy);
+                               currentNode = addAfter(tokenList, removeFrom, 
wrapped);
+
+                               if (after) {
+                                       addAfter(tokenList, currentNode, after);
+                               }
+
+
+                               if (removeCount > 1)
+                                       matchGrammar(text, tokenList, grammar, 
currentNode.prev, pos, true, token + ',' + j);
+
+                               if (oneshot)
+                                       break;
+                       }
+               }
+       }
+}
+
+/**
+ * @typedef LinkedListNode
+ * @property {T} value
+ * @property {LinkedListNode<T> | null} prev The previous node.
+ * @property {LinkedListNode<T> | null} next The next node.
+ * @template T
+ */
+
+/**
+ * @template T
+ */
+function LinkedList() {
+       /** @type {LinkedListNode<T>} */
+       var head = { value: null, prev: null, next: null };
+       /** @type {LinkedListNode<T>} */
+       var tail = { value: null, prev: head, next: null };
+       head.next = tail;
+
+       /** @type {LinkedListNode<T>} */
+       this.head = head;
+       /** @type {LinkedListNode<T>} */
+       this.tail = tail;
+       this.length = 0;
+}
+
+/**
+ * Adds a new node with the given value to the list.
+ * @param {LinkedList<T>} list
+ * @param {LinkedListNode<T>} node
+ * @param {T} value
+ * @returns {LinkedListNode<T>} The added node.
+ * @template T
+ */
+function addAfter(list, node, value) {
+       // assumes that node != list.tail && values.length >= 0
+       var next = node.next;
+
+       var newNode = { value: value, prev: node, next: next };
+       node.next = newNode;
+       next.prev = newNode;
+       list.length++;
+
+       return newNode;
+}
+/**
+ * Removes `count` nodes after the given node. The given node will not be 
removed.
+ * @param {LinkedList<T>} list
+ * @param {LinkedListNode<T>} node
+ * @param {number} count
+ * @template T
+ */
+function removeRange(list, node, count) {
+       var next = node.next;
+       for (var i = 0; i < count && next !== list.tail; i++) {
+               next = next.next;
+       }
+       node.next = next;
+       next.prev = node;
+       list.length -= i;
+}
+/**
+ * @param {LinkedList<T>} list
+ * @returns {T[]}
+ * @template T
+ */
+function toArray(list) {
+       var array = [];
+       var node = list.head.next;
+       while (node !== list.tail) {
+               array.push(node.value);
+               node = node.next;
+       }
+       return array;
+}
+
+
 if (!_self.document) {
        if (!_self.addEventListener) {
                // in Node.js
-               return _self.Prism;
+               return _;
        }
 
        if (!_.disableWorkerMessageHandler) {
@@ -526,32 +674,48 @@ if (!_self.document) {
                }, false);
        }
 
-       return _self.Prism;
+       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 (!_.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;
+       }
+}
+
+function highlightAutomaticallyCallback() {
+       if (!_.manual) {
+               _.highlightAll();
+       }
+}
+
+if (!_.manual) {
+       // 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.Prism;
+return _;
 
-})();
+})(_self);
 
 if (typeof module !== 'undefined' && module.exports) {
        module.exports = Prism;
@@ -565,28 +729,47 @@ if (typeof global !== 'undefined') {
 Prism.languages.markup = {
        'comment': /<!--[\s\S]*?-->/,
        'prolog': /<\?[\s\S]+?\?>/,
-       'doctype': /<!DOCTYPE[\s\S]+?>/i,
+       'doctype': {
+               // https://www.w3.org/TR/xml/#NT-doctypedecl
+               pattern: 
/<!DOCTYPE(?:[^>"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|<!--(?:[^-]|-(?!->))*-->)*\]\s*)?>/i,
+               greedy: true,
+               inside: {
+                       'internal-subset': {
+                               pattern: /(\[)[\s\S]+(?=\]>$)/,
+                               lookbehind: true,
+                               greedy: true,
+                               inside: null // see below
+                       },
+                       'string': {
+                               pattern: /"[^"]*"|'[^']*'/,
+                               greedy: true
+                       },
+                       'punctuation': /^<!|>$|[[\]]/,
+                       'doctype-tag': /^DOCTYPE/,
+                       'name': /[^\s<>'"]+/
+               }
+       },
        'cdata': /<!\[CDATA\[[\s\S]*?]]>/i,
        'tag': {
-               pattern: 
/<\/?(?!\d)[^\s>\/=$<%]+(?:\s+[^\s>\/=]+(?:=(?:("|')(?:\\[\s\S]|(?!\1)[^\\])*\1|[^\s'">=]+))?)*\s*\/?>/i,
+               pattern: 
/<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,
                greedy: true,
                inside: {
                        'tag': {
-                               pattern: /^<\/?[^\s>\/]+/i,
+                               pattern: /^<\/?[^\s>\/]+/,
                                inside: {
                                        'punctuation': /^<\/?/,
                                        'namespace': /^[^\s>\/:]+:/
                                }
                        },
                        'attr-value': {
-                               pattern: 
/=(?:("|')(?:\\[\s\S]|(?!\1)[^\\])*\1|[^\s'">=]+)/i,
+                               pattern: /=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,
                                inside: {
                                        'punctuation': [
-                                               /^=/,
                                                {
-                                                       pattern: 
/(^|[^\\])["']/,
-                                                       lookbehind: true
-                                               }
+                                                       pattern: /^=/,
+                                                       alias: 'attr-equals'
+                                               },
+                                               /"|'/
                                        ]
                                }
                        },
@@ -600,78 +783,144 @@ Prism.languages.markup = {
 
                }
        },
-       'entity': /&#?[\da-z]{1,8};/i
+       'entity': [
+               {
+                       pattern: /&[\da-z]{1,8};/i,
+                       alias: 'named-entity'
+               },
+               /&#x?[\da-f]{1,8};/i
+       ]
 };
 
 Prism.languages.markup['tag'].inside['attr-value'].inside['entity'] =
        Prism.languages.markup['entity'];
+Prism.languages.markup['doctype'].inside['internal-subset'].inside = 
Prism.languages.markup;
 
 // Plugin to make entity title show the real entity, idea by Roman Komarov
-Prism.hooks.add('wrap', function(env) {
+Prism.hooks.add('wrap', function (env) {
 
        if (env.type === 'entity') {
                env.attributes['title'] = env.content.replace(/&amp;/, '&');
        }
 });
 
-Prism.languages.xml = Prism.languages.markup;
+Object.defineProperty(Prism.languages.markup.tag, 'addInlined', {
+       /**
+        * Adds an inlined language to markup.
+        *
+        * An example of an inlined language is CSS with `<style>` tags.
+        *
+        * @param {string} tagName The name of the tag that contains the 
inlined language. This name will be treated as
+        * case insensitive.
+        * @param {string} lang The language key.
+        * @example
+        * addInlined('style', 'css');
+        */
+       value: function addInlined(tagName, lang) {
+               var includedCdataInside = {};
+               includedCdataInside['language-' + lang] = {
+                       pattern: /(^<!\[CDATA\[)[\s\S]+?(?=\]\]>$)/i,
+                       lookbehind: true,
+                       inside: Prism.languages[lang]
+               };
+               includedCdataInside['cdata'] = /^<!\[CDATA\[|\]\]>$/i;
+
+               var inside = {
+                       'included-cdata': {
+                               pattern: /<!\[CDATA\[[\s\S]*?\]\]>/i,
+                               inside: includedCdataInside
+                       }
+               };
+               inside['language-' + lang] = {
+                       pattern: /[\s\S]+/,
+                       inside: Prism.languages[lang]
+               };
+
+               var def = {};
+               def[tagName] = {
+                       pattern: 
RegExp(/(<__[\s\S]*?>)(?:<!\[CDATA\[(?:[^\]]|\](?!\]>))*\]\]>|(?!<!\[CDATA\[)[\s\S])*?(?=<\/__>)/.source.replace(/__/g,
 function () { return tagName; }), 'i'),
+                       lookbehind: true,
+                       greedy: true,
+                       inside: inside
+               };
+
+               Prism.languages.insertBefore('markup', 'cdata', def);
+       }
+});
+
 Prism.languages.html = Prism.languages.markup;
 Prism.languages.mathml = Prism.languages.markup;
 Prism.languages.svg = Prism.languages.markup;
 
-Prism.languages.css = {
-       'comment': /\/\*[\s\S]*?\*\//,
-       'atrule': {
-               pattern: /@[\w-]+?.*?(?:;|(?=\s*\{))/i,
-               inside: {
-                       'rule': /@[\w-]+/
-                       // See rest below
-               }
-       },
-       'url': /url\((?:(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1|.*?)\)/i,
-       'selector': /[^{}\s][^{};]*?(?=\s*\{)/,
-       'string': {
-               pattern: /("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,
-               greedy: true
-       },
-       'property': /[-_a-z\xA0-\uFFFF][-\w\xA0-\uFFFF]*(?=\s*:)/i,
-       'important': /!important\b/i,
-       'function': /[-a-z0-9]+(?=\()/i,
-       'punctuation': /[(){};:]/
-};
+Prism.languages.xml = Prism.languages.extend('markup', {});
+Prism.languages.ssml = Prism.languages.xml;
+Prism.languages.atom = Prism.languages.xml;
+Prism.languages.rss = Prism.languages.xml;
 
-Prism.languages.css['atrule'].inside.rest = Prism.languages.css;
+(function (Prism) {
 
-if (Prism.languages.markup) {
-       Prism.languages.insertBefore('markup', 'tag', {
-               'style': {
-                       pattern: /(<style[\s\S]*?>)[\s\S]*?(?=<\/style>)/i,
-                       lookbehind: true,
-                       inside: Prism.languages.css,
-                       alias: 'language-css',
-                       greedy: true
-               }
-       });
+       var string = /("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/;
 
-       Prism.languages.insertBefore('inside', 'attr-value', {
-               'style-attr': {
-                       pattern: /\s*style=("|')(?:\\[\s\S]|(?!\1)[^\\])*\1/i,
+       Prism.languages.css = {
+               'comment': /\/\*[\s\S]*?\*\//,
+               'atrule': {
+                       pattern: /@[\w-]+[\s\S]*?(?:;|(?=\s*\{))/,
                        inside: {
-                               'attr-name': {
-                                       pattern: /^\s*style/i,
-                                       inside: 
Prism.languages.markup.tag.inside
-                               },
-                               'punctuation': /^\s*=\s*['"]|['"]\s*$/,
-                               'attr-value': {
-                                       pattern: /.+/i,
-                                       inside: Prism.languages.css
+                               'rule': /^@[\w-]+/,
+                               'selector-function-argument': {
+                                       pattern: 
/(\bselector\s*\((?!\s*\))\s*)(?:[^()]|\((?:[^()]|\([^()]*\))*\))+?(?=\s*\))/,
+                                       lookbehind: true,
+                                       alias: 'selector'
                                }
-                       },
-                       alias: 'language-css'
-               }
-       }, Prism.languages.markup.tag);
-}
-;
+                               // See rest below
+                       }
+               },
+               'url': {
+                       pattern: RegExp('url\\((?:' + string.source + 
'|[^\n\r()]*)\\)', 'i'),
+                       greedy: true,
+                       inside: {
+                               'function': /^url/i,
+                               'punctuation': /^\(|\)$/
+                       }
+               },
+               'selector': RegExp('[^{}\\s](?:[^{};"\']|' + string.source + 
')*?(?=\\s*\\{)'),
+               'string': {
+                       pattern: string,
+                       greedy: true
+               },
+               'property': /[-_a-z\xA0-\uFFFF][-\w\xA0-\uFFFF]*(?=\s*:)/i,
+               'important': /!important\b/i,
+               'function': /[-a-z0-9]+(?=\()/i,
+               'punctuation': /[(){};:,]/
+       };
+
+       Prism.languages.css['atrule'].inside.rest = Prism.languages.css;
+
+       var markup = Prism.languages.markup;
+       if (markup) {
+               markup.tag.addInlined('style', 'css');
+
+               Prism.languages.insertBefore('inside', 'attr-value', {
+                       'style-attr': {
+                               pattern: 
/\s*style=("|')(?:\\[\s\S]|(?!\1)[^\\])*\1/i,
+                               inside: {
+                                       'attr-name': {
+                                               pattern: /^\s*style/i,
+                                               inside: markup.tag.inside
+                                       },
+                                       'punctuation': /^\s*=\s*['"]|['"]\s*$/,
+                                       'attr-value': {
+                                               pattern: /.+/i,
+                                               inside: Prism.languages.css
+                                       }
+                               },
+                               alias: 'language-css'
+                       }
+               }, markup.tag);
+       }
+
+}(Prism));
+
 Prism.languages.clike = {
        'comment': [
                {
@@ -689,17 +938,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': /[{}[\];(),.:]/
 };
 
@@ -716,37 +965,66 @@ Prism.languages.javascript = 
Prism.languages.extend('clike', {
                        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/
+               {
+                       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|set)(?=\s*[\[$\w\xA0-\uFFFF])|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,
+                       lookbehind: true
+               },
        ],
-       '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+)?/,
+       '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*\(|\.(?:apply|bind|call)\()/,
-       'operator': 
/-[-=]?|\+[+=]?|!=?=?|<<?=?|>>?>?=?|=(?:==?|>)?|&[&=]?|\|[|=]?|\*\*?=?|\/=?|~|\^=?|%=?|\?|\.{3}/
+       'function': 
/#?[_$a-zA-Z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,
+       'operator': 
/--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/
 });
 
-Prism.languages.javascript['class-name'][0].pattern = 
/(\b(?:class|interface|extends|implements|instanceof|new)\s+)[\w.\\]+/
+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])+\/[gimyus]{0,6}(?=(?:\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-zA-Z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|[_$a-zA-Z\xA0-\uFFFF][$\w\xA0-\uFFFF]*)\s*=>))/,
                alias: 'function'
        },
-       'constant': /\b[A-Z][A-Z\d_]*\b/
+       'parameter': [
+               {
+                       pattern: 
/(function(?:\s+[_$A-Za-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*=>)/i,
+                       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|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:[_$A-Za-z\xA0-\uFFFF][$\w\xA0-\uFFFF]*\s*)\(\s*|\]\s*\(\s*)(?!\s)(?:[^()]|\([^()]*\))+?(?=\s*\)\s*\{)/,
+                       lookbehind: true,
+                       inside: Prism.languages.javascript
+               }
+       ],
+       'constant': /\b[A-Z](?:[A-Z_]|\dx?)*\b/
 });
 
 Prism.languages.insertBefore('javascript', 'string', {
        'template-string': {
-               pattern: /`(?:\\[\s\S]|\${[^}]+}|[^\\`])*`/,
+               pattern: 
/`(?:\\[\s\S]|\${(?:[^{}]|{(?:[^{}]|{[^}]*})*})+}|(?!\${)[^\\`])*`/,
                greedy: true,
                inside: {
+                       'template-punctuation': {
+                               pattern: /^`|`$/,
+                               alias: 'string'
+                       },
                        'interpolation': {
-                               pattern: /\${[^}]+}/,
+                               pattern: 
/((?:^|[^\\])(?:\\{2})*)\${(?:[^{}]|{(?:[^{}]|{[^}]*})*})+}/,
+                               lookbehind: true,
                                inside: {
                                        'interpolation-punctuation': {
                                                pattern: /^\${|}$/,
@@ -761,15 +1039,7 @@ Prism.languages.insertBefore('javascript', 'string', {
 });
 
 if (Prism.languages.markup) {
-       Prism.languages.insertBefore('markup', 'tag', {
-               'script': {
-                       pattern: /(<script[\s\S]*?>)[\s\S]*?(?=<\/script>)/i,
-                       lookbehind: true,
-                       inside: Prism.languages.javascript,
-                       alias: 'language-javascript',
-                       greedy: true
-               }
-       });
+       Prism.languages.markup.tag.addInlined('script', 'javascript');
 }
 
 Prism.languages.js = Prism.languages.javascript;
@@ -779,13 +1049,36 @@ Prism.languages.python = {
                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': {
@@ -796,17 +1089,29 @@ Prism.languages.python = {
                pattern: /(\bclass\s+)\w+/i,
                lookbehind: true
        },
+       'decorator': {
+               pattern: /(^\s*)@\w+(?:\.\w+)*/im,
+               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/,
+       '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': /[-+%=]=?|!=|\*\*?=?|\/\/?=?|<[<=>]?|>[=>]?|[&|^~]/,
        'punctuation': /[{}[\];(),.:]/
 };
 
+Prism.languages.python['string-interpolation'].inside['interpolation'].inside.rest
 = Prism.languages.python;
+
+Prism.languages.py = Prism.languages.python;
+
 Prism.languages['visual-basic'] = {
        'comment': {
-               pattern: /(?:['‘’]|REM\b).*/i,
+               pattern: /(?:['‘’]|REM\b)(?:[^\r\n_]|_(?:\r\n?|\n)?)*/i,
                inside: {
                        'keyword': /^REM/i
                }
@@ -817,7 +1122,7 @@ Prism.languages['visual-basic'] = {
                greedy: true
        },
        'string': {
-               pattern: /["“”](?:["“”]{2}|[^"“”])*["“”]C?/i,
+               pattern: /\$?["“”](?:["“”]{2}|[^"“”])*["“”]C?/i,
                greedy: true
        },
        'date': {
@@ -826,7 +1131,7 @@ Prism.languages['visual-basic'] = {
        },
        'number': 
/(?:(?:\b\d+(?:\.\d+)?|\.\d+)(?:E[+-]?\d+)?|&[HO][\dA-F]+)(?:U?[ILS]|[FRD])?/i,
        'boolean': /\b(?:True|False|Nothing)\b/i,
-       'keyword': 
/\b(?:AddHandler|AddressOf|Alias|And(?:Also)?|As|Boolean|ByRef|Byte|ByVal|Call|Case|Catch|C(?:Bool|Byte|Char|Date|Dbl|Dec|Int|Lng|Obj|SByte|Short|Sng|Str|Type|UInt|ULng|UShort)|Char|Class|Const|Continue|Date|Decimal|Declare|Default|Delegate|Dim|DirectCast|Do|Double|Each|Else(?:If)?|End(?:If)?|Enum|Erase|Error|Event|Exit|Finally|For|Friend|Function|Get(?:Type|XMLNamespace)?|Global|GoSub|GoTo|Handles|If|Implements|Imports|In|Inherits|Integer|Interface|Is|IsNot|Let|Lib|Like|Long|Loop|Me|Mod|Module|Must(?:Inherit|Override)|My(?:Base|Class)|Namespace|Narrowing|New|Next|Not(?:Inheritable|Overridable)?|Object|Of|On|Operator|Option(?:al)?|Or(?:Else)?|Out|Overloads|Overridable|Overrides|ParamArray|Partial|Private|Property|Protected|Public|RaiseEvent|ReadOnly|ReDim|RemoveHandler|Resume|Return|SByte|Select|Set|Shadows|Shared|short|Single|Static|Step|Stop|String|Structure|Sub|SyncLock|Then|Throw|To|Try|TryCast|TypeOf|U(?:Integer|Long|Short)|Using|Variant|Wend|When|While|Widening|Wit
 h(?:Events)?|WriteOnly|Xor)\b/i,
+       'keyword': 
/\b(?:AddHandler|AddressOf|Alias|And(?:Also)?|As|Boolean|ByRef|Byte|ByVal|Call|Case|Catch|C(?:Bool|Byte|Char|Date|Dbl|Dec|Int|Lng|Obj|SByte|Short|Sng|Str|Type|UInt|ULng|UShort)|Char|Class|Const|Continue|Currency|Date|Decimal|Declare|Default|Delegate|Dim|DirectCast|Do|Double|Each|Else(?:If)?|End(?:If)?|Enum|Erase|Error|Event|Exit|Finally|For|Friend|Function|Get(?:Type|XMLNamespace)?|Global|GoSub|GoTo|Handles|If|Implements|Imports|In|Inherits|Integer|Interface|Is|IsNot|Let|Lib|Like|Long|Loop|Me|Mod|Module|Must(?:Inherit|Override)|My(?:Base|Class)|Namespace|Narrowing|New|Next|Not(?:Inheritable|Overridable)?|Object|Of|On|Operator|Option(?:al)?|Or(?:Else)?|Out|Overloads|Overridable|Overrides|ParamArray|Partial|Private|Property|Protected|Public|RaiseEvent|ReadOnly|ReDim|RemoveHandler|Resume|Return|SByte|Select|Set|Shadows|Shared|short|Single|Static|Step|Stop|String|Structure|Sub|SyncLock|Then|Throw|To|Try|TryCast|Type|TypeOf|U(?:Integer|Long|Short)|Using|Variant|Wend|When|Whil
 e|Widening|With(?:Events)?|WriteOnly|Xor)\b/i,
        'operator': [
                /[+\-*/\\^<=>&#@$%!]/,
                {
@@ -838,6 +1143,7 @@ Prism.languages['visual-basic'] = {
 };
 
 Prism.languages.vb = Prism.languages['visual-basic'];
+
 (function () {
 
        if (typeof self === 'undefined' || !self.Prism || !self.document) {
@@ -867,6 +1173,9 @@ Prism.languages.vb = Prism.languages['visual-basic'];
                if (whiteSpace === 'pre-wrap' || whiteSpace === 'pre-line') {
                        var codeElement = element.querySelector('code');
                        var lineNumbersWrapper = 
element.querySelector('.line-numbers-rows');
+                       if (!codeElement || !lineNumbersWrapper) {
+                               return;
+                       }
                        var lineNumberSizer = 
element.querySelector('.line-numbers-sizer');
                        var codeLines = 
codeElement.textContent.split(NEW_LINE_EXP);
 
@@ -911,28 +1220,38 @@ Prism.languages.vb = Prism.languages['visual-basic'];
                        return;
                }
 
+               var code = env.element;
+               var pre = code.parentNode;
+
                // works only for <code> wrapped inside <pre> (not inline)
-               var pre = env.element.parentNode;
-               var clsReg = /\s*\bline-numbers\b\s*/;
-               if (
-                       !pre || !/pre/i.test(pre.nodeName) ||
-                       // Abort only if nor the <pre> nor the <code> have the 
class
-                       (!clsReg.test(pre.className) && 
!clsReg.test(env.element.className))
-               ) {
+               if (!pre || !/pre/i.test(pre.nodeName)) {
                        return;
                }
 
-               if (env.element.querySelector('.line-numbers-rows')) {
-                       // Abort if line numbers already exists
+               // Abort if line numbers already exists
+               if (code.querySelector('.line-numbers-rows')) {
                        return;
                }
 
-               if (clsReg.test(env.element.className)) {
-                       // Remove the class 'line-numbers' from the <code>
-                       env.element.className = 
env.element.className.replace(clsReg, ' ');
+               var addLineNumbers = false;
+               var lineNumbersRegex = /(?:^|\s)line-numbers(?:\s|$)/;
+
+               for (var element = code; element; element = element.parentNode) 
{
+                       if (lineNumbersRegex.test(element.className)) {
+                               addLineNumbers = true;
+                               break;
+                       }
+               }
+
+               // only add line numbers if <code> or one of its ancestors has 
the `line-numbers` class
+               if (!addLineNumbers) {
+                       return;
                }
-               if (!clsReg.test(pre.className)) {
-                       // Add the class 'line-numbers' to the <pre>
+
+               // Remove the class 'line-numbers' from the <code>
+               code.className = code.className.replace(lineNumbersRegex, ' ');
+               // Add the class 'line-numbers' to the <pre>
+               if (!lineNumbersRegex.test(pre.className)) {
                        pre.className += ' line-numbers';
                }
 
@@ -940,8 +1259,7 @@ Prism.languages.vb = Prism.languages['visual-basic'];
                var linesNum = match ? match.length + 1 : 1;
                var lineNumbersWrapper;
 
-               var lines = new Array(linesNum + 1);
-               lines = lines.join('<span></span>');
+               var lines = new Array(linesNum + 1).join('<span></span>');
 
                lineNumbersWrapper = document.createElement('span');
                lineNumbersWrapper.setAttribute('aria-hidden', 'true');
@@ -969,10 +1287,10 @@ Prism.languages.vb = Prism.languages['visual-basic'];
         */
        Prism.plugins.lineNumbers = {
                /**
-                * Get node for provided line number
-                * @param {Element} element pre element
-                * @param {Number} number line number
-                * @return {Element|undefined}
+                * Returns the node of the given line number in the given 
element.
+                * @param {Element} element A `<pre>` element with line numbers.
+                * @param {Number} number
+                * @returns {Element | undefined}
                 */
                getLine: function (element, number) {
                        if (element.tagName !== 'PRE' || 
!element.classList.contains(PLUGIN_NAME)) {
@@ -993,10 +1311,21 @@ Prism.languages.vb = Prism.languages['visual-basic'];
                        var lineIndex = number - lineNumberStart;
 
                        return lineNumberRows.children[lineIndex];
+               },
+               /**
+                * Resizes the line numbers of the given element.
+                *
+                * This function will not add line numbers. It will only resize 
existing ones.
+                * @param {Element} element A `<pre>` element with line numbers.
+                * @returns {void}
+                */
+               resize: function (element) {
+                       _resizeElement(element);
                }
        };
 
 }());
+
 (function() {
 
 var assign = Object.assign || function (obj1, obj2) {
@@ -1147,7 +1476,7 @@ Prism.hooks.add('before-sanity-check', function (env) {
 
        // Normal mode
        var pre = env.element.parentNode;
-       var clsReg = /\bno-whitespace-normalization\b/;
+       var clsReg = /(?:^|\s)no-whitespace-normalization(?:\s|$)/;
        if (!env.code || !pre || pre.nodeName.toLowerCase() !== 'pre' ||
                        clsReg.test(pre.className) || 
clsReg.test(env.element.className))
                return;
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to