History

Merge pull request #1236 from seirl/ocaml

Add documentation for OCaml

Simon Legner committed 5 years ago

Commit 9d164922 parents c0290b8 a0f6ea29 files · +3148 −2689Browse files

Unified · Split

9 files
  1. assets/javascripts/templates/pages/about_tmpl.coffee +5 −0
  2. assets/javascripts/vendor/prism.js +3007 −2691
  3. docs/file-scrapers.md +12 −0
  4. lib/docs/filters/ocaml/clean_html.rb +35 −0
  5. lib/docs/filters/ocaml/entries.rb +59 −0
  6. lib/docs/scrapers/ocaml.rb +30 −0
  7. public/icons/docs/ocaml/16.png +0 −0
  8. public/icons/docs/ocaml/16@2x.png +0 −0
  9. public/icons/docs/ocaml/SOURCE +2 −0
assets/javascripts/templates/pages/about_tmpl.coffee+5−0
@@ -576,6 +576,11 @@ credits = [ · 575 unmodified lines
576576 '2005-2019 NumPy Developers',
577577 'BSD',
578578 'https://raw.githubusercontent.com/numpy/numpy/master/LICENSE.txt'
579+ ], [
580+ 'OCaml',
581+ '1995-2020 Inria',
582+ 'CC BY-SA',
583+ 'https://ocaml.org/docs/'
579584 ], [
580585 'Octave',
581586 '1996-2018 John W. Eaton',
assets/javascripts/vendor/prism.js+3007−2691
@@ -1,12 +1,12 @@
1−/* PrismJS 1.19.0
2−https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript+bash+c+cpp+coffeescript+crystal+d+dart+django+elixir+erlang+go+groovy+java+json+julia+kotlin+lua+markup-templating+matlab+nginx+nim+perl+php+python+jsx+ruby+rust+scss+shell-session+sql+typescript+yaml */
1+/* PrismJS 1.20.0
2+https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript+bash+c+cpp+coffeescript+crystal+d+dart+django+elixir+erlang+go+groovy+java+json+julia+kotlin+lua+markup-templating+matlab+nginx+nim+ocaml+perl+php+python+jsx+ruby+rust+scss+shell-session+sql+typescript+yaml */
33 var _self = (typeof window !== 'undefined')
4− ? window // if in browser
5− : (
6− (typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope)
7− ? self // if in worker
8− : {} // if in node js
9− );
4+ ? window // if in browser
5+ : (
6+ (typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope)
7+ ? self // if in worker
8+ : {} // if in node js
9+ );
1010
1111 /**
1212 * Prism: Lightweight, robust, elegant syntax highlighting
@@ -22,591 +22,695 @@ var uniqueId = 0; · 9 unmodified lines
2222
2323
2424 var _ = {
25− manual: _self.Prism && _self.Prism.manual,
26− disableWorkerMessageHandler: _self.Prism && _self.Prism.disableWorkerMessageHandler,
27− util: {
28− encode: function (tokens) {
29− if (tokens instanceof Token) {
30− return new Token(tokens.type, _.util.encode(tokens.content), tokens.alias);
31− } else if (Array.isArray(tokens)) {
32− return tokens.map(_.util.encode);
33− } else {
34− return tokens.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/\u00a0/g, ' ');
35− }
36− },
37−
38− type: function (o) {
39− return Object.prototype.toString.call(o).slice(8, -1);
40− },
41−
42− objId: function (obj) {
43− if (!obj['__id']) {
44− Object.defineProperty(obj, '__id', { value: ++uniqueId });
45− }
46− return obj['__id'];
47− },
48−
49− // Deep clone a language definition (e.g. to extend it)
50− clone: function deepClone(o, visited) {
51− var clone, id, type = _.util.type(o);
52− visited = visited || {};
53−
54− switch (type) {
55− case 'Object':
56− id = _.util.objId(o);
57− if (visited[id]) {
58− return visited[id];
59− }
60− clone = {};
61− visited[id] = clone;
62−
63− for (var key in o) {
64− if (o.hasOwnProperty(key)) {
65− clone[key] = deepClone(o[key], visited);
66− }
67− }
68−
69− return clone;
70−
71− case 'Array':
72− id = _.util.objId(o);
73− if (visited[id]) {
74− return visited[id];
75− }
76− clone = [];
77− visited[id] = clone;
78−
79− o.forEach(function (v, i) {
80− clone[i] = deepClone(v, visited);
81− });
82−
83− return clone;
84−
85− default:
86− return o;
87− }
88− },
89−
90− /**
91− * Returns the Prism language of the given element set by a `language-xxxx` or `lang-xxxx` class.
92− *
93− * If no language is set for the element or the element is `null` or `undefined`, `none` will be returned.
94− *
95− * @param {Element} element
96− * @returns {string}
97− */
98− getLanguage: function (element) {
99− while (element && !lang.test(element.className)) {
100− element = element.parentElement;
101− }
102− if (element) {
103− return (element.className.match(lang) || [, 'none'])[1].toLowerCase();
104− }
105− return 'none';
106− },
107−
108− /**
109− * Returns the script element that is currently executing.
110− *
111− * This does __not__ work for line script element.
112− *
113− * @returns {HTMLScriptElement | null}
114− */
115− currentScript: function () {
116− if (typeof document === 'undefined') {
117− return null;
118− }
119− if ('currentScript' in document) {
120− return document.currentScript;
121− }
122−
123− // IE11 workaround
124− // we'll get the src of the current script by parsing IE11's error stack trace
125− // this will not work for inline scripts
126−
127− try {
128− throw new Error();
129− } catch (err) {
130− // Get file src url from stack. Specifically works with the format of stack traces in IE.
131− // A stack will look like this:
132− //
133− // Error
134− // at _.util.currentScript (http://localhost/components/prism-core.js:119:5)
135− // at Global code (http://localhost/components/prism-core.js:606:1)
136−
137− var src = (/at [^(\r\n]*\((.*):.+:.+\)$/i.exec(err.stack) || [])[1];
138− if (src) {
139− var scripts = document.getElementsByTagName('script');
140− for (var i in scripts) {
141− if (scripts[i].src == src) {
142− return scripts[i];
143− }
144− }
145− }
146− return null;
147− }
148− }
149− },
150−
151− languages: {
152− extend: function (id, redef) {
153− var lang = _.util.clone(_.languages[id]);
154−
155− for (var key in redef) {
156− lang[key] = redef[key];
157− }
158−
159− return lang;
160− },
161−
162− /**
163− * Insert a token before another token in a language literal
164− * As this needs to recreate the object (we cannot actually insert before keys in object literals),
165− * we cannot just provide an object, we need an object and a key.
166− * @param inside The key (or language id) of the parent
167− * @param before The key to insert before.
168− * @param insert Object with the key/value pairs to insert
169− * @param root The object that contains `inside`. If equal to Prism.languages, it can be omitted.
170− */
171− insertBefore: function (inside, before, insert, root) {
172− root = root || _.languages;
173− var grammar = root[inside];
174− var ret = {};
175−
176− for (var token in grammar) {
177− if (grammar.hasOwnProperty(token)) {
178−
179− if (token == before) {
180− for (var newToken in insert) {
181− if (insert.hasOwnProperty(newToken)) {
182− ret[newToken] = insert[newToken];
183− }
184− }
185− }
186−
187− // Do not insert token which also occur in insert. See #1525
188− if (!insert.hasOwnProperty(token)) {
189− ret[token] = grammar[token];
190− }
191− }
192− }
193−
194− var old = root[inside];
195− root[inside] = ret;
196−
197− // Update references in other language definitions
198− _.languages.DFS(_.languages, function(key, value) {
199− if (value === old && key != inside) {
200− this[key] = ret;
201− }
202− });
203−
204− return ret;
205− },
206−
207− // Traverse a language definition with Depth First Search
208− DFS: function DFS(o, callback, type, visited) {
209− visited = visited || {};
210−
211− var objId = _.util.objId;
212−
213− for (var i in o) {
214− if (o.hasOwnProperty(i)) {
215− callback.call(o, i, o[i], type || i);
216−
217− var property = o[i],
218− propertyType = _.util.type(property);
219−
220− if (propertyType === 'Object' && !visited[objId(property)]) {
221− visited[objId(property)] = true;
222− DFS(property, callback, null, visited);
223− }
224− else if (propertyType === 'Array' && !visited[objId(property)]) {
225− visited[objId(property)] = true;
226− DFS(property, callback, i, visited);
227− }
228− }
229− }
230− }
231− },
232− plugins: {},
233−
234− highlightAll: function(async, callback) {
235− _.highlightAllUnder(document, async, callback);
236− },
237−
238− highlightAllUnder: function(container, async, callback) {
239− var env = {
240− callback: callback,
241− container: container,
242− selector: 'code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code'
243− };
244−
245− _.hooks.run('before-highlightall', env);
246−
247− env.elements = Array.prototype.slice.apply(env.container.querySelectorAll(env.selector));
248−
249− _.hooks.run('before-all-elements-highlight', env);
250−
251− for (var i = 0, element; element = env.elements[i++];) {
252− _.highlightElement(element, async === true, env.callback);
253− }
254− },
255−
256− highlightElement: function(element, async, callback) {
257− // Find language
258− var language = _.util.getLanguage(element);
259− var grammar = _.languages[language];
260−
261− // Set language on the element, if not present
262− element.className = element.className.replace(lang, '').replace(/\s+/g, ' ') + ' language-' + language;
263−
264− // Set language on the parent, for styling
265− var parent = element.parentNode;
266− if (parent && parent.nodeName.toLowerCase() === 'pre') {
267− parent.className = parent.className.replace(lang, '').replace(/\s+/g, ' ') + ' language-' + language;
268− }
269−
270− var code = element.textContent;
271−
272− var env = {
273− element: element,
274− language: language,
275− grammar: grammar,
276− code: code
277− };
278−
279− function insertHighlightedCode(highlightedCode) {
280− env.highlightedCode = highlightedCode;
281−
282− _.hooks.run('before-insert', env);
283−
284− env.element.innerHTML = env.highlightedCode;
285−
286− _.hooks.run('after-highlight', env);
287− _.hooks.run('complete', env);
288− callback && callback.call(env.element);
289− }
290−
291− _.hooks.run('before-sanity-check', env);
292−
293− if (!env.code) {
294− _.hooks.run('complete', env);
295− callback && callback.call(env.element);
296− return;
297− }
298−
299− _.hooks.run('before-highlight', env);
300−
301− if (!env.grammar) {
302− insertHighlightedCode(_.util.encode(env.code));
303− return;
304− }
305−
306− if (async && _self.Worker) {
307− var worker = new Worker(_.filename);
308−
309− worker.onmessage = function(evt) {
310− insertHighlightedCode(evt.data);
311− };
312−
313− worker.postMessage(JSON.stringify({
314− language: env.language,
315− code: env.code,
316− immediateClose: true
317− }));
318− }
319− else {
320− insertHighlightedCode(_.highlight(env.code, env.grammar, env.language));
321− }
322− },
323−
324− highlight: function (text, grammar, language) {
325− var env = {
326− code: text,
327− grammar: grammar,
328− language: language
329− };
330− _.hooks.run('before-tokenize', env);
331− env.tokens = _.tokenize(env.code, env.grammar);
332− _.hooks.run('after-tokenize', env);
333− return Token.stringify(_.util.encode(env.tokens), env.language);
334− },
335−
336− matchGrammar: function (text, strarr, grammar, index, startPos, oneshot, target) {
337− for (var token in grammar) {
338− if (!grammar.hasOwnProperty(token) || !grammar[token]) {
339− continue;
340− }
341−
342− var patterns = grammar[token];
343− patterns = Array.isArray(patterns) ? patterns : [patterns];
344−
345− for (var j = 0; j < patterns.length; ++j) {
346− if (target && target == token + ',' + j) {
347− return;
348− }
349−
350− var pattern = patterns[j],
351− inside = pattern.inside,
352− lookbehind = !!pattern.lookbehind,
353− greedy = !!pattern.greedy,
354− lookbehindLength = 0,
355− alias = pattern.alias;
356−
357− if (greedy && !pattern.pattern.global) {
358− // Without the global flag, lastIndex won't work
359− var flags = pattern.pattern.toString().match(/[imsuy]*$/)[0];
360− pattern.pattern = RegExp(pattern.pattern.source, flags + 'g');
361− }
362−
363− pattern = pattern.pattern || pattern;
364−
365− // Don’t cache length as it changes during the loop
366− for (var i = index, pos = startPos; i < strarr.length; pos += strarr[i].length, ++i) {
367−
368− var str = strarr[i];
369−
370− if (strarr.length > text.length) {
371− // Something went terribly wrong, ABORT, ABORT!
372− return;
373− }
374−
375− if (str instanceof Token) {
376− continue;
377− }
378−
379− if (greedy && i != strarr.length - 1) {
380− pattern.lastIndex = pos;
381− var match = pattern.exec(text);
382− if (!match) {
383− break;
384− }
385−
386− var from = match.index + (lookbehind && match[1] ? match[1].length : 0),
387− to = match.index + match[0].length,
388− k = i,
389− p = pos;
390−
391− for (var len = strarr.length; k < len && (p < to || (!strarr[k].type && !strarr[k - 1].greedy)); ++k) {
392− p += strarr[k].length;
393− // Move the index i to the element in strarr that is closest to from
394− if (from >= p) {
395− ++i;
396− pos = p;
397− }
398− }
399−
400− // If strarr[i] is a Token, then the match starts inside another Token, which is invalid
401− if (strarr[i] instanceof Token) {
402− continue;
403− }
404−
405− // Number of tokens to delete and replace with the new match
406− delNum = k - i;
407− str = text.slice(pos, p);
408− match.index -= pos;
409− } else {
410− pattern.lastIndex = 0;
411−
412− var match = pattern.exec(str),
413− delNum = 1;
414− }
415−
416− if (!match) {
417− if (oneshot) {
418− break;
419− }
420−
421− continue;
422− }
423−
424− if(lookbehind) {
425− lookbehindLength = match[1] ? match[1].length : 0;
426− }
427−
428− var from = match.index + lookbehindLength,
429− match = match[0].slice(lookbehindLength),
430− to = from + match.length,
431− before = str.slice(0, from),
432− after = str.slice(to);
433−
434− var args = [i, delNum];
25+ manual: _self.Prism && _self.Prism.manual,
26+ disableWorkerMessageHandler: _self.Prism && _self.Prism.disableWorkerMessageHandler,
27+ util: {
28+ encode: function encode(tokens) {
29+ if (tokens instanceof Token) {
30+ return new Token(tokens.type, encode(tokens.content), tokens.alias);
31+ } else if (Array.isArray(tokens)) {
32+ return tokens.map(encode);
33+ } else {
34+ return tokens.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/\u00a0/g, ' ');
35+ }
36+ },
37+
38+ type: function (o) {
39+ return Object.prototype.toString.call(o).slice(8, -1);
40+ },
41+
42+ objId: function (obj) {
43+ if (!obj['__id']) {
44+ Object.defineProperty(obj, '__id', { value: ++uniqueId });
45+ }
46+ return obj['__id'];
47+ },
48+
49+ // Deep clone a language definition (e.g. to extend it)
50+ clone: function deepClone(o, visited) {
51+ var clone, id, type = _.util.type(o);
52+ visited = visited || {};
53+
54+ switch (type) {
55+ case 'Object':
56+ id = _.util.objId(o);
57+ if (visited[id]) {
58+ return visited[id];
59+ }
60+ clone = {};
61+ visited[id] = clone;
62+
63+ for (var key in o) {
64+ if (o.hasOwnProperty(key)) {
65+ clone[key] = deepClone(o[key], visited);
66+ }
67+ }
68+
69+ return clone;
70+
71+ case 'Array':
72+ id = _.util.objId(o);
73+ if (visited[id]) {
74+ return visited[id];
75+ }
76+ clone = [];
77+ visited[id] = clone;
78+
79+ o.forEach(function (v, i) {
80+ clone[i] = deepClone(v, visited);
81+ });
82+
83+ return clone;
84+
85+ default:
86+ return o;
87+ }
88+ },
89+
90+ /**
91+ * Returns the Prism language of the given element set by a `language-xxxx` or `lang-xxxx` class.
92+ *
93+ * If no language is set for the element or the element is `null` or `undefined`, `none` will be returned.
94+ *
95+ * @param {Element} element
96+ * @returns {string}
97+ */
98+ getLanguage: function (element) {
99+ while (element && !lang.test(element.className)) {
100+ element = element.parentElement;
101+ }
102+ if (element) {
103+ return (element.className.match(lang) || [, 'none'])[1].toLowerCase();
104+ }
105+ return 'none';
106+ },
107+
108+ /**
109+ * Returns the script element that is currently executing.
110+ *
111+ * This does __not__ work for line script element.
112+ *
113+ * @returns {HTMLScriptElement | null}
114+ */
115+ currentScript: function () {
116+ if (typeof document === 'undefined') {
117+ return null;
118+ }
119+ if ('currentScript' in document) {
120+ return document.currentScript;
121+ }
122+
123+ // IE11 workaround
124+ // we'll get the src of the current script by parsing IE11's error stack trace
125+ // this will not work for inline scripts
126+
127+ try {
128+ throw new Error();
129+ } catch (err) {
130+ // Get file src url from stack. Specifically works with the format of stack traces in IE.
131+ // A stack will look like this:
132+ //
133+ // Error
134+ // at _.util.currentScript (http://localhost/components/prism-core.js:119:5)
135+ // at Global code (http://localhost/components/prism-core.js:606:1)
136+
137+ var src = (/at [^(\r\n]*\((.*):.+:.+\)$/i.exec(err.stack) || [])[1];
138+ if (src) {
139+ var scripts = document.getElementsByTagName('script');
140+ for (var i in scripts) {
141+ if (scripts[i].src == src) {
142+ return scripts[i];
143+ }
144+ }
145+ }
146+ return null;
147+ }
148+ }
149+ },
150+
151+ languages: {
152+ extend: function (id, redef) {
153+ var lang = _.util.clone(_.languages[id]);
154+
155+ for (var key in redef) {
156+ lang[key] = redef[key];
157+ }
158+
159+ return lang;
160+ },
161+
162+ /**
163+ * Insert a token before another token in a language literal
164+ * As this needs to recreate the object (we cannot actually insert before keys in object literals),
165+ * we cannot just provide an object, we need an object and a key.
166+ * @param inside The key (or language id) of the parent
167+ * @param before The key to insert before.
168+ * @param insert Object with the key/value pairs to insert
169+ * @param root The object that contains `inside`. If equal to Prism.languages, it can be omitted.
170+ */
171+ insertBefore: function (inside, before, insert, root) {
172+ root = root || _.languages;
173+ var grammar = root[inside];
174+ var ret = {};
175+
176+ for (var token in grammar) {
177+ if (grammar.hasOwnProperty(token)) {
178+
179+ if (token == before) {
180+ for (var newToken in insert) {
181+ if (insert.hasOwnProperty(newToken)) {
182+ ret[newToken] = insert[newToken];
183+ }
184+ }
185+ }
186+
187+ // Do not insert token which also occur in insert. See #1525
188+ if (!insert.hasOwnProperty(token)) {
189+ ret[token] = grammar[token];
190+ }
191+ }
192+ }
193+
194+ var old = root[inside];
195+ root[inside] = ret;
196+
197+ // Update references in other language definitions
198+ _.languages.DFS(_.languages, function(key, value) {
199+ if (value === old && key != inside) {
200+ this[key] = ret;
201+ }
202+ });
203+
204+ return ret;
205+ },
206+
207+ // Traverse a language definition with Depth First Search
208+ DFS: function DFS(o, callback, type, visited) {
209+ visited = visited || {};
210+
211+ var objId = _.util.objId;
212+
213+ for (var i in o) {
214+ if (o.hasOwnProperty(i)) {
215+ callback.call(o, i, o[i], type || i);
216+
217+ var property = o[i],
218+ propertyType = _.util.type(property);
219+
220+ if (propertyType === 'Object' && !visited[objId(property)]) {
221+ visited[objId(property)] = true;
222+ DFS(property, callback, null, visited);
223+ }
224+ else if (propertyType === 'Array' && !visited[objId(property)]) {
225+ visited[objId(property)] = true;
226+ DFS(property, callback, i, visited);
227+ }
228+ }
229+ }
230+ }
231+ },
232+ plugins: {},
233+
234+ highlightAll: function(async, callback) {
235+ _.highlightAllUnder(document, async, callback);
236+ },
237+
238+ highlightAllUnder: function(container, async, callback) {
239+ var env = {
240+ callback: callback,
241+ container: container,
242+ selector: 'code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code'
243+ };
244+
245+ _.hooks.run('before-highlightall', env);
246+
247+ env.elements = Array.prototype.slice.apply(env.container.querySelectorAll(env.selector));
248+
249+ _.hooks.run('before-all-elements-highlight', env);
250+
251+ for (var i = 0, element; element = env.elements[i++];) {
252+ _.highlightElement(element, async === true, env.callback);
253+ }
254+ },
255+
256+ highlightElement: function(element, async, callback) {
257+ // Find language
258+ var language = _.util.getLanguage(element);
259+ var grammar = _.languages[language];
260+
261+ // Set language on the element, if not present
262+ element.className = element.className.replace(lang, '').replace(/\s+/g, ' ') + ' language-' + language;
263+
264+ // Set language on the parent, for styling
265+ var parent = element.parentNode;
266+ if (parent && parent.nodeName.toLowerCase() === 'pre') {
267+ parent.className = parent.className.replace(lang, '').replace(/\s+/g, ' ') + ' language-' + language;
268+ }
269+
270+ var code = element.textContent;
271+
272+ var env = {
273+ element: element,
274+ language: language,
275+ grammar: grammar,
276+ code: code
277+ };
278+
279+ function insertHighlightedCode(highlightedCode) {
280+ env.highlightedCode = highlightedCode;
281+
282+ _.hooks.run('before-insert', env);
283+
284+ env.element.innerHTML = env.highlightedCode;
285+
286+ _.hooks.run('after-highlight', env);
287+ _.hooks.run('complete', env);
288+ callback && callback.call(env.element);
289+ }
290+
291+ _.hooks.run('before-sanity-check', env);
292+
293+ if (!env.code) {
294+ _.hooks.run('complete', env);
295+ callback && callback.call(env.element);
296+ return;
297+ }
298+
299+ _.hooks.run('before-highlight', env);
300+
301+ if (!env.grammar) {
302+ insertHighlightedCode(_.util.encode(env.code));
303+ return;
304+ }
305+
306+ if (async && _self.Worker) {
307+ var worker = new Worker(_.filename);
308+
309+ worker.onmessage = function(evt) {
310+ insertHighlightedCode(evt.data);
311+ };
312+
313+ worker.postMessage(JSON.stringify({
314+ language: env.language,
315+ code: env.code,
316+ immediateClose: true
317+ }));
318+ }
319+ else {
320+ insertHighlightedCode(_.highlight(env.code, env.grammar, env.language));
321+ }
322+ },
323+
324+ highlight: function (text, grammar, language) {
325+ var env = {
326+ code: text,
327+ grammar: grammar,
328+ language: language
329+ };
330+ _.hooks.run('before-tokenize', env);
331+ env.tokens = _.tokenize(env.code, env.grammar);
332+ _.hooks.run('after-tokenize', env);
333+ return Token.stringify(_.util.encode(env.tokens), env.language);
334+ },
335+
336+ tokenize: function(text, grammar) {
337+ var rest = grammar.rest;
338+ if (rest) {
339+ for (var token in rest) {
340+ grammar[token] = rest[token];
341+ }
435342
436− if (before) {
437− ++i;
438− pos += before.length;
439− args.push(before);
440− }
343+ delete grammar.rest;
344+ }
441345
442− var wrapped = new Token(token, inside? _.tokenize(match, inside) : match, alias, match, greedy);
346+ var tokenList = new LinkedList();
347+ addAfter(tokenList, tokenList.head, text);
443348
444− args.push(wrapped);
445−
446− if (after) {
447− args.push(after);
448− }
349+ matchGrammar(text, tokenList, grammar, tokenList.head, 0);
350+
351+ return toArray(tokenList);
352+ },
353+
354+ hooks: {
355+ all: {},
356+
357+ add: function (name, callback) {
358+ var hooks = _.hooks.all;
359+
360+ hooks[name] = hooks[name] || [];
361+
362+ hooks[name].push(callback);
363+ },
364+
365+ run: function (name, env) {
366+ var callbacks = _.hooks.all[name];
367+
368+ if (!callbacks || !callbacks.length) {
369+ return;
370+ }
371+
372+ for (var i=0, callback; callback = callbacks[i++];) {
373+ callback(env);
374+ }
375+ }
376+ },
449377
450− Array.prototype.splice.apply(strarr, args);
451−
452− if (delNum != 1)
453− _.matchGrammar(text, strarr, grammar, i, pos, true, token + ',' + j);
454−
455− if (oneshot)
456− break;
457− }
458− }
459− }
460− },
461−
462− tokenize: function(text, grammar) {
463− var strarr = [text];
464−
465− var rest = grammar.rest;
466−
467− if (rest) {
468− for (var token in rest) {
469− grammar[token] = rest[token];
470− }
471−
472− delete grammar.rest;
473− }
474−
475− _.matchGrammar(text, strarr, grammar, 0, 0, false);
476−
477− return strarr;
478− },
479−
480− hooks: {
481− all: {},
378+ Token: Token
379+};
482380
483− add: function (name, callback) {
484− var hooks = _.hooks.all;
381+_self.Prism = _;
485382
486− hooks[name] = hooks[name] || [];
383+function Token(type, content, alias, matchedStr, greedy) {
384+ this.type = type;
385+ this.content = content;
386+ this.alias = alias;
387+ // Copy of the full string this token was created from
388+ this.length = (matchedStr || '').length|0;
389+ this.greedy = !!greedy;
390+}
487391
488− hooks[name].push(callback);
489− },
392+Token.stringify = function stringify(o, language) {
393+ if (typeof o == 'string') {
394+ return o;
395+ }
396+ if (Array.isArray(o)) {
397+ var s = '';
398+ o.forEach(function (e) {
399+ s += stringify(e, language);
400+ });
401+ return s;
402+ }
403+
404+ var env = {
405+ type: o.type,
406+ content: stringify(o.content, language),
407+ tag: 'span',
408+ classes: ['token', o.type],
409+ attributes: {},
410+ language: language
411+ };
412+
413+ var aliases = o.alias;
414+ if (aliases) {
415+ if (Array.isArray(aliases)) {
416+ Array.prototype.push.apply(env.classes, aliases);
417+ } else {
418+ env.classes.push(aliases);
419+ }
420+ }
421+
422+ _.hooks.run('wrap', env);
423+
424+ var attributes = '';
425+ for (var name in env.attributes) {
426+ attributes += ' ' + name + '="' + (env.attributes[name] || '').replace(/"/g, '&quot;') + '"';
427+ }
428+
429+ return '<' + env.tag + ' class="' + env.classes.join(' ') + '"' + attributes + '>' + env.content + '</' + env.tag + '>';
430+};
490431
491− run: function (name, env) {
492− var callbacks = _.hooks.all[name];
432+/**
433+ * @param {string} text
434+ * @param {LinkedList<string | Token>} tokenList
435+ * @param {any} grammar
436+ * @param {LinkedListNode<string | Token>} startNode
437+ * @param {number} startPos
438+ * @param {boolean} [oneshot=false]
439+ * @param {string} [target]
440+ */
441+function matchGrammar(text, tokenList, grammar, startNode, startPos, oneshot, target) {
442+ for (var token in grammar) {
443+ if (!grammar.hasOwnProperty(token) || !grammar[token]) {
444+ continue;
445+ }
446+
447+ var patterns = grammar[token];
448+ patterns = Array.isArray(patterns) ? patterns : [patterns];
449+
450+ for (var j = 0; j < patterns.length; ++j) {
451+ if (target && target == token + ',' + j) {
452+ return;
453+ }
454+
455+ var pattern = patterns[j],
456+ inside = pattern.inside,
457+ lookbehind = !!pattern.lookbehind,
458+ greedy = !!pattern.greedy,
459+ lookbehindLength = 0,
460+ alias = pattern.alias;
461+
462+ if (greedy && !pattern.pattern.global) {
463+ // Without the global flag, lastIndex won't work
464+ var flags = pattern.pattern.toString().match(/[imsuy]*$/)[0];
465+ pattern.pattern = RegExp(pattern.pattern.source, flags + 'g');
466+ }
467+
468+ pattern = pattern.pattern || pattern;
469+
470+ for ( // iterate the token list and keep track of the current token/string position
471+ var currentNode = startNode.next, pos = startPos;
472+ currentNode !== tokenList.tail;
473+ pos += currentNode.value.length, currentNode = currentNode.next
474+ ) {
475+
476+ var str = currentNode.value;
477+
478+ if (tokenList.length > text.length) {
479+ // Something went terribly wrong, ABORT, ABORT!
480+ return;
481+ }
482+
483+ if (str instanceof Token) {
484+ continue;
485+ }
486+
487+ var removeCount = 1; // this is the to parameter of removeBetween
488+
489+ if (greedy && currentNode != tokenList.tail.prev) {
490+ pattern.lastIndex = pos;
491+ var match = pattern.exec(text);
492+ if (!match) {
493+ break;
494+ }
495+
496+ var from = match.index + (lookbehind && match[1] ? match[1].length : 0);
497+ var to = match.index + match[0].length;
498+ var p = pos;
499+
500+ // find the node that contains the match
501+ p += currentNode.value.length;
502+ while (from >= p) {
503+ currentNode = currentNode.next;
504+ p += currentNode.value.length;
505+ }
506+ // adjust pos (and p)
507+ p -= currentNode.value.length;
508+ pos = p;
509+
510+ // the current node is a Token, then the match starts inside another Token, which is invalid
511+ if (currentNode.value instanceof Token) {
512+ continue;
513+ }
514+
515+ // find the last node which is affected by this match
516+ for (
517+ var k = currentNode;
518+ k !== tokenList.tail && (p < to || (typeof k.value === 'string' && !k.prev.value.greedy));
519+ k = k.next
520+ ) {
521+ removeCount++;
522+ p += k.value.length;
523+ }
524+ removeCount--;
525+
526+ // replace with the new match
527+ str = text.slice(pos, p);
528+ match.index -= pos;
529+ } else {
530+ pattern.lastIndex = 0;
531+
532+ var match = pattern.exec(str);
533+ }
534+
535+ if (!match) {
536+ if (oneshot) {
537+ break;
538+ }
539+
540+ continue;
541+ }
542+
543+ if (lookbehind) {
544+ lookbehindLength = match[1] ? match[1].length : 0;
545+ }
546+
547+ var from = match.index + lookbehindLength,
548+ match = match[0].slice(lookbehindLength),
549+ to = from + match.length,
550+ before = str.slice(0, from),
551+ after = str.slice(to);
552+
553+ var removeFrom = currentNode.prev;
554+
555+ if (before) {
556+ removeFrom = addAfter(tokenList, removeFrom, before);
557+ pos += before.length;
558+ }
559+
560+ removeRange(tokenList, removeFrom, removeCount);
561+
562+ var wrapped = new Token(token, inside ? _.tokenize(match, inside) : match, alias, match, greedy);
563+ currentNode = addAfter(tokenList, removeFrom, wrapped);
564+
565+ if (after) {
566+ addAfter(tokenList, currentNode, after);
567+ }
568+
569+
570+ if (removeCount > 1)
571+ matchGrammar(text, tokenList, grammar, currentNode.prev, pos, true, token + ',' + j);
572+
573+ if (oneshot)
574+ break;
575+ }
576+ }
577+ }
578+}
493579
494− if (!callbacks || !callbacks.length) {
495− return;
496− }
580+/**
581+ * @typedef LinkedListNode
582+ * @property {T} value
583+ * @property {LinkedListNode<T> | null} prev The previous node.
584+ * @property {LinkedListNode<T> | null} next The next node.
585+ * @template T
586+ */
497587
498− for (var i=0, callback; callback = callbacks[i++];) {
499− callback(env);
500− }
501− }
502− },
588+/**
589+ * @template T
590+ */
591+function LinkedList() {
592+ /** @type {LinkedListNode<T>} */
593+ var head = { value: null, prev: null, next: null };
594+ /** @type {LinkedListNode<T>} */
595+ var tail = { value: null, prev: head, next: null };
596+ head.next = tail;
597+
598+ /** @type {LinkedListNode<T>} */
599+ this.head = head;
600+ /** @type {LinkedListNode<T>} */
601+ this.tail = tail;
602+ this.length = 0;
603+}
503604
504− Token: Token
505−};
605+/**
606+ * Adds a new node with the given value to the list.
607+ * @param {LinkedList<T>} list
608+ * @param {LinkedListNode<T>} node
609+ * @param {T} value
610+ * @returns {LinkedListNode<T>} The added node.
611+ * @template T
612+ */
613+function addAfter(list, node, value) {
614+ // assumes that node != list.tail && values.length >= 0
615+ var next = node.next;
506616
507−_self.Prism = _;
617+ var newNode = { value: value, prev: node, next: next };
618+ node.next = newNode;
619+ next.prev = newNode;
620+ list.length++;
508621
509−function Token(type, content, alias, matchedStr, greedy) {
510− this.type = type;
511− this.content = content;
512− this.alias = alias;
513− // Copy of the full string this token was created from
514− this.length = (matchedStr || '').length|0;
515− this.greedy = !!greedy;
622+ return newNode;
623+}
624+/**
625+ * Removes `count` nodes after the given node. The given node will not be removed.
626+ * @param {LinkedList<T>} list
627+ * @param {LinkedListNode<T>} node
628+ * @param {number} count
629+ * @template T
630+ */
631+function removeRange(list, node, count) {
632+ var next = node.next;
633+ for (var i = 0; i < count && next !== list.tail; i++) {
634+ next = next.next;
635+ }
636+ node.next = next;
637+ next.prev = node;
638+ list.length -= i;
639+}
640+/**
641+ * @param {LinkedList<T>} list
642+ * @returns {T[]}
643+ * @template T
644+ */
645+function toArray(list) {
646+ var array = [];
647+ var node = list.head.next;
648+ while (node !== list.tail) {
649+ array.push(node.value);
650+ node = node.next;
651+ }
652+ return array;
516653 }
517654
518−Token.stringify = function(o, language) {
519− if (typeof o == 'string') {
520− return o;
521− }
522−
523− if (Array.isArray(o)) {
524− return o.map(function(element) {
525− return Token.stringify(element, language);
526− }).join('');
527− }
528−
529− var env = {
530− type: o.type,
531− content: Token.stringify(o.content, language),
532− tag: 'span',
533− classes: ['token', o.type],
534− attributes: {},
535− language: language
536− };
537−
538− if (o.alias) {
539− var aliases = Array.isArray(o.alias) ? o.alias : [o.alias];
540− Array.prototype.push.apply(env.classes, aliases);
541− }
542−
543− _.hooks.run('wrap', env);
544−
545− var attributes = Object.keys(env.attributes).map(function(name) {
546− return name + '="' + (env.attributes[name] || '').replace(/"/g, '&quot;') + '"';
547− }).join(' ');
548−
549− return '<' + env.tag + ' class="' + env.classes.join(' ') + '"' + (attributes ? ' ' + attributes : '') + '>' + env.content + '</' + env.tag + '>';
550−};
551655
552656 if (!_self.document) {
553− if (!_self.addEventListener) {
554− // in Node.js
555− return _;
556− }
557−
558− if (!_.disableWorkerMessageHandler) {
559− // In worker
560− _self.addEventListener('message', function (evt) {
561− var message = JSON.parse(evt.data),
562− lang = message.language,
563− code = message.code,
564− immediateClose = message.immediateClose;
565−
566− _self.postMessage(_.highlight(code, _.languages[lang], lang));
567− if (immediateClose) {
568− _self.close();
569− }
570− }, false);
571− }
572−
573− return _;
657+ if (!_self.addEventListener) {
658+ // in Node.js
659+ return _;
660+ }
661+
662+ if (!_.disableWorkerMessageHandler) {
663+ // In worker
664+ _self.addEventListener('message', function (evt) {
665+ var message = JSON.parse(evt.data),
666+ lang = message.language,
667+ code = message.code,
668+ immediateClose = message.immediateClose;
669+
670+ _self.postMessage(_.highlight(code, _.languages[lang], lang));
671+ if (immediateClose) {
672+ _self.close();
673+ }
674+ }, false);
675+ }
676+
677+ return _;
574678 }
575679
576680 //Get current script and highlight
577681 var script = _.util.currentScript();
578682
579683 if (script) {
580− _.filename = script.src;
684+ _.filename = script.src;
685+
686+ if (script.hasAttribute('data-manual')) {
687+ _.manual = true;
688+ }
689+}
581690
582− if (script.hasAttribute('data-manual')) {
583− _.manual = true;
584− }
691+function highlightAutomaticallyCallback() {
692+ if (!_.manual) {
693+ _.highlightAll();
694+ }
585695 }
586696
587697 if (!_.manual) {
588− function highlightAutomaticallyCallback() {
589− if (!_.manual) {
590− _.highlightAll();
591− }
592− }
593−
594− // If the document state is "loading", then we'll use DOMContentLoaded.
595− // If the document state is "interactive" and the prism.js script is deferred, then we'll also use the
596− // DOMContentLoaded event because there might be some plugins or languages which have also been deferred and they
597− // might take longer one animation frame to execute which can create a race condition where only some plugins have
598− // been loaded when Prism.highlightAll() is executed, depending on how fast resources are loaded.
599− // See https://github.com/PrismJS/prism/issues/2102
600− var readyState = document.readyState;
601− if (readyState === 'loading' || readyState === 'interactive' && script && script.defer) {
602− document.addEventListener('DOMContentLoaded', highlightAutomaticallyCallback);
603− } else {
604− if (window.requestAnimationFrame) {
605− window.requestAnimationFrame(highlightAutomaticallyCallback);
606− } else {
607− window.setTimeout(highlightAutomaticallyCallback, 16);
608− }
609− }
698+ // If the document state is "loading", then we'll use DOMContentLoaded.
699+ // If the document state is "interactive" and the prism.js script is deferred, then we'll also use the
700+ // DOMContentLoaded event because there might be some plugins or languages which have also been deferred and they
701+ // might take longer one animation frame to execute which can create a race condition where only some plugins have
702+ // been loaded when Prism.highlightAll() is executed, depending on how fast resources are loaded.
703+ // See https://github.com/PrismJS/prism/issues/2102
704+ var readyState = document.readyState;
705+ if (readyState === 'loading' || readyState === 'interactive' && script && script.defer) {
706+ document.addEventListener('DOMContentLoaded', highlightAutomaticallyCallback);
707+ } else {
708+ if (window.requestAnimationFrame) {
709+ window.requestAnimationFrame(highlightAutomaticallyCallback);
710+ } else {
711+ window.setTimeout(highlightAutomaticallyCallback, 16);
712+ }
713+ }
610714 }
611715
612716 return _;
@@ -614,642 +718,724 @@ return _; · 1 unmodified line
614718 })(_self);
615719
616720 if (typeof module !== 'undefined' && module.exports) {
617− module.exports = Prism;
721+ module.exports = Prism;
618722 }
619723
620724 // hack for components to work correctly in node.js
621725 if (typeof global !== 'undefined') {
622− global.Prism = Prism;
726+ global.Prism = Prism;
623727 }
624728 ;
625729 Prism.languages.markup = {
626− 'comment': /<!--[\s\S]*?-->/,
627− 'prolog': /<\?[\s\S]+?\?>/,
628− 'doctype': {
629− pattern: /<!DOCTYPE(?:[^>"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:(?!<!--)[^"'\]]|"[^"]*"|'[^']*'|<!--[\s\S]*?-->)*\]\s*)?>/i,
630− greedy: true
631− },
632− 'cdata': /<!\[CDATA\[[\s\S]*?]]>/i,
633− 'tag': {
634− pattern: /<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/i,
635− greedy: true,
636− inside: {
637− 'tag': {
638− pattern: /^<\/?[^\s>\/]+/i,
639− inside: {
640− 'punctuation': /^<\/?/,
641− 'namespace': /^[^\s>\/:]+:/
642− }
643− },
644− 'attr-value': {
645− pattern: /=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/i,
646− inside: {
647− 'punctuation': [
648− /^=/,
649− {
650− pattern: /^(\s*)["']|["']$/,
651− lookbehind: true
652− }
653− ]
654− }
655− },
656− 'punctuation': /\/?>/,
657− 'attr-name': {
658− pattern: /[^\s>\/]+/,
659− inside: {
660− 'namespace': /^[^\s>\/:]+:/
661− }
662− }
663−
664− }
665− },
666− 'entity': /&#?[\da-z]{1,8};/i
730+ 'comment': /<!--[\s\S]*?-->/,
731+ 'prolog': /<\?[\s\S]+?\?>/,
732+ 'doctype': {
733+ // https://www.w3.org/TR/xml/#NT-doctypedecl
734+ pattern: /<!DOCTYPE(?:[^>"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|<!--(?:[^-]|-(?!->))*-->)*\]\s*)?>/i,
735+ greedy: true,
736+ inside: {
737+ 'internal-subset': {
738+ pattern: /(\[)[\s\S]+(?=\]>$)/,
739+ lookbehind: true,
740+ greedy: true,
741+ inside: null // see below
742+ },
743+ 'string': {
744+ pattern: /"[^"]*"|'[^']*'/,
745+ greedy: true
746+ },
747+ 'punctuation': /^<!|>$|[[\]]/,
748+ 'doctype-tag': /^DOCTYPE/,
749+ 'name': /[^\s<>'"]+/
750+ }
751+ },
752+ 'cdata': /<!\[CDATA\[[\s\S]*?]]>/i,
753+ 'tag': {
754+ pattern: /<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,
755+ greedy: true,
756+ inside: {
757+ 'tag': {
758+ pattern: /^<\/?[^\s>\/]+/,
759+ inside: {
760+ 'punctuation': /^<\/?/,
761+ 'namespace': /^[^\s>\/:]+:/
762+ }
763+ },
764+ 'attr-value': {
765+ pattern: /=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,
766+ inside: {
767+ 'punctuation': [
768+ {
769+ pattern: /^=/,
770+ alias: 'attr-equals'
771+ },
772+ /"|'/
773+ ]
774+ }
775+ },
776+ 'punctuation': /\/?>/,
777+ 'attr-name': {
778+ pattern: /[^\s>\/]+/,
779+ inside: {
780+ 'namespace': /^[^\s>\/:]+:/
781+ }
782+ }
783+
784+ }
785+ },
786+ 'entity': [
787+ {
788+ pattern: /&[\da-z]{1,8};/i,
789+ alias: 'named-entity'
790+ },
791+ /&#x?[\da-f]{1,8};/i
792+ ]
667793 };
668794
669795 Prism.languages.markup['tag'].inside['attr-value'].inside['entity'] =
670− Prism.languages.markup['entity'];
796+ Prism.languages.markup['entity'];
797+Prism.languages.markup['doctype'].inside['internal-subset'].inside = Prism.languages.markup;
671798
672799 // Plugin to make entity title show the real entity, idea by Roman Komarov
673−Prism.hooks.add('wrap', function(env) {
800+Prism.hooks.add('wrap', function (env) {
674801
675− if (env.type === 'entity') {
676− env.attributes['title'] = env.content.replace(/&amp;/, '&');
677− }
802+ if (env.type === 'entity') {
803+ env.attributes['title'] = env.content.replace(/&amp;/, '&');
804+ }
678805 });
679806
680807 Object.defineProperty(Prism.languages.markup.tag, 'addInlined', {
681− /**
682− * Adds an inlined language to markup.
683− *
684− * An example of an inlined language is CSS with `<style>` tags.
685− *
686− * @param {string} tagName The name of the tag that contains the inlined language. This name will be treated as
687− * case insensitive.
688− * @param {string} lang The language key.
689− * @example
690− * addInlined('style', 'css');
691− */
692− value: function addInlined(tagName, lang) {
693− var includedCdataInside = {};
694− includedCdataInside['language-' + lang] = {
695− pattern: /(^<!\[CDATA\[)[\s\S]+?(?=\]\]>$)/i,
696− lookbehind: true,
697− inside: Prism.languages[lang]
698− };
699− includedCdataInside['cdata'] = /^<!\[CDATA\[|\]\]>$/i;
700−
701− var inside = {
702− 'included-cdata': {
703− pattern: /<!\[CDATA\[[\s\S]*?\]\]>/i,
704− inside: includedCdataInside
705− }
706− };
707− inside['language-' + lang] = {
708− pattern: /[\s\S]+/,
709− inside: Prism.languages[lang]
710− };
711−
712− var def = {};
713− def[tagName] = {
714− pattern: RegExp(/(<__[\s\S]*?>)(?:<!\[CDATA\[[\s\S]*?\]\]>\s*|[\s\S])*?(?=<\/__>)/.source.replace(/__/g, tagName), 'i'),
715− lookbehind: true,
716− greedy: true,
717− inside: inside
718− };
719−
720− Prism.languages.insertBefore('markup', 'cdata', def);
721− }
808+ /**
809+ * Adds an inlined language to markup.
810+ *
811+ * An example of an inlined language is CSS with `<style>` tags.
812+ *
813+ * @param {string} tagName The name of the tag that contains the inlined language. This name will be treated as
814+ * case insensitive.
815+ * @param {string} lang The language key.
816+ * @example
817+ * addInlined('style', 'css');
818+ */
819+ value: function addInlined(tagName, lang) {
820+ var includedCdataInside = {};
821+ includedCdataInside['language-' + lang] = {
822+ pattern: /(^<!\[CDATA\[)[\s\S]+?(?=\]\]>$)/i,
823+ lookbehind: true,
824+ inside: Prism.languages[lang]
825+ };
826+ includedCdataInside['cdata'] = /^<!\[CDATA\[|\]\]>$/i;
827+
828+ var inside = {
829+ 'included-cdata': {
830+ pattern: /<!\[CDATA\[[\s\S]*?\]\]>/i,
831+ inside: includedCdataInside
832+ }
833+ };
834+ inside['language-' + lang] = {
835+ pattern: /[\s\S]+/,
836+ inside: Prism.languages[lang]
837+ };
838+
839+ var def = {};
840+ def[tagName] = {
841+ pattern: RegExp(/(<__[\s\S]*?>)(?:<!\[CDATA\[(?:[^\]]|\](?!\]>))*\]\]>|(?!<!\[CDATA\[)[\s\S])*?(?=<\/__>)/.source.replace(/__/g, function () { return tagName; }), 'i'),
842+ lookbehind: true,
843+ greedy: true,
844+ inside: inside
845+ };
846+
847+ Prism.languages.insertBefore('markup', 'cdata', def);
848+ }
722849 });
723850
724−Prism.languages.xml = Prism.languages.extend('markup', {});
725851 Prism.languages.html = Prism.languages.markup;
726852 Prism.languages.mathml = Prism.languages.markup;
727853 Prism.languages.svg = Prism.languages.markup;
728854
855+Prism.languages.xml = Prism.languages.extend('markup', {});
856+Prism.languages.ssml = Prism.languages.xml;
857+Prism.languages.atom = Prism.languages.xml;
858+Prism.languages.rss = Prism.languages.xml;
859+
729860 (function (Prism) {
730861
731− var string = /("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/;
732−
733− Prism.languages.css = {
734− 'comment': /\/\*[\s\S]*?\*\//,
735− 'atrule': {
736− pattern: /@[\w-]+[\s\S]*?(?:;|(?=\s*\{))/,
737− inside: {
738− 'rule': /@[\w-]+/
739− // See rest below
740− }
741− },
742− 'url': {
743− pattern: RegExp('url\\((?:' + string.source + '|[^\n\r()]*)\\)', 'i'),
744− inside: {
745− 'function': /^url/i,
746− 'punctuation': /^\(|\)$/
747− }
748− },
749− 'selector': RegExp('[^{}\\s](?:[^{};"\']|' + string.source + ')*?(?=\\s*\\{)'),
750− 'string': {
751− pattern: string,
752− greedy: true
753− },
754− 'property': /[-_a-z\xA0-\uFFFF][-\w\xA0-\uFFFF]*(?=\s*:)/i,
755− 'important': /!important\b/i,
756− 'function': /[-a-z0-9]+(?=\()/i,
757− 'punctuation': /[(){};:,]/
758− };
759−
760− Prism.languages.css['atrule'].inside.rest = Prism.languages.css;
761−
762− var markup = Prism.languages.markup;
763− if (markup) {
764− markup.tag.addInlined('style', 'css');
765−
766− Prism.languages.insertBefore('inside', 'attr-value', {
767− 'style-attr': {
768− pattern: /\s*style=("|')(?:\\[\s\S]|(?!\1)[^\\])*\1/i,
769− inside: {
770− 'attr-name': {
771− pattern: /^\s*style/i,
772− inside: markup.tag.inside
773− },
774− 'punctuation': /^\s*=\s*['"]|['"]\s*$/,
775− 'attr-value': {
776− pattern: /.+/i,
777− inside: Prism.languages.css
778− }
779− },
780− alias: 'language-css'
781− }
782− }, markup.tag);
783− }
862+ var string = /("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/;
863+
864+ Prism.languages.css = {
865+ 'comment': /\/\*[\s\S]*?\*\//,
866+ 'atrule': {
867+ pattern: /@[\w-]+[\s\S]*?(?:;|(?=\s*\{))/,
868+ inside: {
869+ 'rule': /^@[\w-]+/,
870+ 'selector-function-argument': {
871+ pattern: /(\bselector\s*\((?!\s*\))\s*)(?:[^()]|\((?:[^()]|\([^()]*\))*\))+?(?=\s*\))/,
872+ lookbehind: true,
873+ alias: 'selector'
874+ }
875+ // See rest below
876+ }
877+ },
878+ 'url': {
879+ pattern: RegExp('url\\((?:' + string.source + '|[^\n\r()]*)\\)', 'i'),
880+ greedy: true,
881+ inside: {
882+ 'function': /^url/i,
883+ 'punctuation': /^\(|\)$/
884+ }
885+ },
886+ 'selector': RegExp('[^{}\\s](?:[^{};"\']|' + string.source + ')*?(?=\\s*\\{)'),
887+ 'string': {
888+ pattern: string,
889+ greedy: true
890+ },
891+ 'property': /[-_a-z\xA0-\uFFFF][-\w\xA0-\uFFFF]*(?=\s*:)/i,
892+ 'important': /!important\b/i,
893+ 'function': /[-a-z0-9]+(?=\()/i,
894+ 'punctuation': /[(){};:,]/
895+ };
896+
897+ Prism.languages.css['atrule'].inside.rest = Prism.languages.css;
898+
899+ var markup = Prism.languages.markup;
900+ if (markup) {
901+ markup.tag.addInlined('style', 'css');
902+
903+ Prism.languages.insertBefore('inside', 'attr-value', {
904+ 'style-attr': {
905+ pattern: /\s*style=("|')(?:\\[\s\S]|(?!\1)[^\\])*\1/i,
906+ inside: {
907+ 'attr-name': {
908+ pattern: /^\s*style/i,
909+ inside: markup.tag.inside
910+ },
911+ 'punctuation': /^\s*=\s*['"]|['"]\s*$/,
912+ 'attr-value': {
913+ pattern: /.+/i,
914+ inside: Prism.languages.css
915+ }
916+ },
917+ alias: 'language-css'
918+ }
919+ }, markup.tag);
920+ }
784921
785922 }(Prism));
786923
787924 Prism.languages.clike = {
788− 'comment': [
789− {
790− pattern: /(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,
791− lookbehind: true
792− },
793− {
794− pattern: /(^|[^\\:])\/\/.*/,
795− lookbehind: true,
796− greedy: true
797− }
798− ],
799− 'string': {
800− pattern: /(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,
801− greedy: true
802− },
803− 'class-name': {
804− pattern: /(\b(?:class|interface|extends|implements|trait|instanceof|new)\s+|\bcatch\s+\()[\w.\\]+/i,
805− lookbehind: true,
806− inside: {
807− 'punctuation': /[.\\]/
808− }
809− },
810− 'keyword': /\b(?:if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/,
811− 'boolean': /\b(?:true|false)\b/,
812− 'function': /\w+(?=\()/,
813− 'number': /\b0x[\da-f]+\b|(?:\b\d+\.?\d*|\B\.\d+)(?:e[+-]?\d+)?/i,
814− 'operator': /[<>]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,
815− 'punctuation': /[{}[\];(),.:]/
925+ 'comment': [
926+ {
927+ pattern: /(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,
928+ lookbehind: true
929+ },
930+ {
931+ pattern: /(^|[^\\:])\/\/.*/,
932+ lookbehind: true,
933+ greedy: true
934+ }
935+ ],
936+ 'string': {
937+ pattern: /(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,
938+ greedy: true
939+ },
940+ 'class-name': {
941+ pattern: /(\b(?:class|interface|extends|implements|trait|instanceof|new)\s+|\bcatch\s+\()[\w.\\]+/i,
942+ lookbehind: true,
943+ inside: {
944+ 'punctuation': /[.\\]/
945+ }
946+ },
947+ 'keyword': /\b(?:if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/,
948+ 'boolean': /\b(?:true|false)\b/,
949+ 'function': /\w+(?=\()/,
950+ 'number': /\b0x[\da-f]+\b|(?:\b\d+\.?\d*|\B\.\d+)(?:e[+-]?\d+)?/i,
951+ 'operator': /[<>]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,
952+ 'punctuation': /[{}[\];(),.:]/
816953 };
817954
818955 Prism.languages.javascript = Prism.languages.extend('clike', {
819− 'class-name': [
820− Prism.languages.clike['class-name'],
821− {
822− pattern: /(^|[^$\w\xA0-\uFFFF])[_$A-Z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\.(?:prototype|constructor))/,
823− lookbehind: true
824− }
825− ],
826− 'keyword': [
827− {
828− pattern: /((?:^|})\s*)(?:catch|finally)\b/,
829− lookbehind: true
830− },
831− {
832− pattern: /(^|[^.]|\.\.\.\s*)\b(?:as|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,
833− lookbehind: true
834− },
835− ],
836− '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)?)+)?/,
837− // Allow for all non-ASCII characters (See http://stackoverflow.com/a/2008444)
838− 'function': /#?[_$a-zA-Z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,
839− 'operator': /--|\+\+|\*\*=?|=>|&&|\|\||[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?[.?]?|[~:]/
956+ 'class-name': [
957+ Prism.languages.clike['class-name'],
958+ {
959+ pattern: /(^|[^$\w\xA0-\uFFFF])[_$A-Z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\.(?:prototype|constructor))/,
960+ lookbehind: true
961+ }
962+ ],
963+ 'keyword': [
964+ {
965+ pattern: /((?:^|})\s*)(?:catch|finally)\b/,
966+ lookbehind: true
967+ },
968+ {
969+ pattern: /(^|[^.]|\.\.\.\s*)\b(?:as|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,
970+ lookbehind: true
971+ },
972+ ],
973+ '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)?)+)?/,
974+ // Allow for all non-ASCII characters (See http://stackoverflow.com/a/2008444)
975+ 'function': /#?[_$a-zA-Z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,
976+ 'operator': /--|\+\+|\*\*=?|=>|&&|\|\||[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?[.?]?|[~:]/
840977 });
841978
842979 Prism.languages.javascript['class-name'][0].pattern = /(\b(?:class|interface|extends|implements|instanceof|new)\s+)[\w.\\]+/;
843980
844981 Prism.languages.insertBefore('javascript', 'keyword', {
845− 'regex': {
846− pattern: /((?:^|[^$\w\xA0-\uFFFF."'\])\s])\s*)\/(?:\[(?:[^\]\\\r\n]|\\.)*]|\\.|[^/\\\[\r\n])+\/[gimyus]{0,6}(?=(?:\s|\/\*[\s\S]*?\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/,
847− lookbehind: true,
848− greedy: true
849− },
850− // This must be declared before keyword because we use "function" inside the look-forward
851− 'function-variable': {
852− pattern: /#?[_$a-zA-Z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|[_$a-zA-Z\xA0-\uFFFF][$\w\xA0-\uFFFF]*)\s*=>))/,
853− alias: 'function'
854− },
855− 'parameter': [
856− {
857− pattern: /(function(?:\s+[_$A-Za-z\xA0-\uFFFF][$\w\xA0-\uFFFF]*)?\s*\(\s*)(?!\s)(?:[^()]|\([^()]*\))+?(?=\s*\))/,
858− lookbehind: true,
859− inside: Prism.languages.javascript
860− },
861− {
862− pattern: /[_$a-z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\s*=>)/i,
863− inside: Prism.languages.javascript
864− },
865− {
866− pattern: /(\(\s*)(?!\s)(?:[^()]|\([^()]*\))+?(?=\s*\)\s*=>)/,
867− lookbehind: true,
868− inside: Prism.languages.javascript
869− },
870− {
871− 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*\{)/,
872− lookbehind: true,
873− inside: Prism.languages.javascript
874− }
875− ],
876− 'constant': /\b[A-Z](?:[A-Z_]|\dx?)*\b/
982+ 'regex': {
983+ pattern: /((?:^|[^$\w\xA0-\uFFFF."'\])\s])\s*)\/(?:\[(?:[^\]\\\r\n]|\\.)*]|\\.|[^/\\\[\r\n])+\/[gimyus]{0,6}(?=(?:\s|\/\*(?:[^*]|\*(?!\/))*\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/,
984+ lookbehind: true,
985+ greedy: true
986+ },
987+ // This must be declared before keyword because we use "function" inside the look-forward
988+ 'function-variable': {
989+ pattern: /#?[_$a-zA-Z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|[_$a-zA-Z\xA0-\uFFFF][$\w\xA0-\uFFFF]*)\s*=>))/,
990+ alias: 'function'
991+ },
992+ 'parameter': [
993+ {
994+ pattern: /(function(?:\s+[_$A-Za-z\xA0-\uFFFF][$\w\xA0-\uFFFF]*)?\s*\(\s*)(?!\s)(?:[^()]|\([^()]*\))+?(?=\s*\))/,
995+ lookbehind: true,
996+ inside: Prism.languages.javascript
997+ },
998+ {
999+ pattern: /[_$a-z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\s*=>)/i,
1000+ inside: Prism.languages.javascript
1001+ },
1002+ {
1003+ pattern: /(\(\s*)(?!\s)(?:[^()]|\([^()]*\))+?(?=\s*\)\s*=>)/,
1004+ lookbehind: true,
1005+ inside: Prism.languages.javascript
1006+ },
1007+ {
1008+ 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*\{)/,
1009+ lookbehind: true,
1010+ inside: Prism.languages.javascript
1011+ }
1012+ ],
1013+ 'constant': /\b[A-Z](?:[A-Z_]|\dx?)*\b/
8771014 });
8781015
8791016 Prism.languages.insertBefore('javascript', 'string', {
880− 'template-string': {
881− pattern: /`(?:\\[\s\S]|\${(?:[^{}]|{(?:[^{}]|{[^}]*})*})+}|(?!\${)[^\\`])*`/,
882− greedy: true,
883− inside: {
884− 'template-punctuation': {
885− pattern: /^`|`$/,
886− alias: 'string'
887− },
888− 'interpolation': {
889− pattern: /((?:^|[^\\])(?:\\{2})*)\${(?:[^{}]|{(?:[^{}]|{[^}]*})*})+}/,
890− lookbehind: true,
891− inside: {
892− 'interpolation-punctuation': {
893− pattern: /^\${|}$/,
894− alias: 'punctuation'
895− },
896− rest: Prism.languages.javascript
897− }
898− },
899− 'string': /[\s\S]+/
900− }
901− }
1017+ 'template-string': {
1018+ pattern: /`(?:\\[\s\S]|\${(?:[^{}]|{(?:[^{}]|{[^}]*})*})+}|(?!\${)[^\\`])*`/,
1019+ greedy: true,
1020+ inside: {
1021+ 'template-punctuation': {
1022+ pattern: /^`|`$/,
1023+ alias: 'string'
1024+ },
1025+ 'interpolation': {
1026+ pattern: /((?:^|[^\\])(?:\\{2})*)\${(?:[^{}]|{(?:[^{}]|{[^}]*})*})+}/,
1027+ lookbehind: true,
1028+ inside: {
1029+ 'interpolation-punctuation': {
1030+ pattern: /^\${|}$/,
1031+ alias: 'punctuation'
1032+ },
1033+ rest: Prism.languages.javascript
1034+ }
1035+ },
1036+ 'string': /[\s\S]+/
1037+ }
1038+ }
9021039 });
9031040
9041041 if (Prism.languages.markup) {
905− Prism.languages.markup.tag.addInlined('script', 'javascript');
1042+ Prism.languages.markup.tag.addInlined('script', 'javascript');
9061043 }
9071044
9081045 Prism.languages.js = Prism.languages.javascript;
9091046
9101047 (function(Prism) {
911− // $ set | grep '^[A-Z][^[:space:]]*=' | cut -d= -f1 | tr '\n' '|'
912− // + LC_ALL, RANDOM, REPLY, SECONDS.
913− // + make sure PS1..4 are here as they are not always set,
914− // - some useless things.
915− var envVars = '\\b(?:BASH|BASHOPTS|BASH_ALIASES|BASH_ARGC|BASH_ARGV|BASH_CMDS|BASH_COMPLETION_COMPAT_DIR|BASH_LINENO|BASH_REMATCH|BASH_SOURCE|BASH_VERSINFO|BASH_VERSION|COLORTERM|COLUMNS|COMP_WORDBREAKS|DBUS_SESSION_BUS_ADDRESS|DEFAULTS_PATH|DESKTOP_SESSION|DIRSTACK|DISPLAY|EUID|GDMSESSION|GDM_LANG|GNOME_KEYRING_CONTROL|GNOME_KEYRING_PID|GPG_AGENT_INFO|GROUPS|HISTCONTROL|HISTFILE|HISTFILESIZE|HISTSIZE|HOME|HOSTNAME|HOSTTYPE|IFS|INSTANCE|JOB|LANG|LANGUAGE|LC_ADDRESS|LC_ALL|LC_IDENTIFICATION|LC_MEASUREMENT|LC_MONETARY|LC_NAME|LC_NUMERIC|LC_PAPER|LC_TELEPHONE|LC_TIME|LESSCLOSE|LESSOPEN|LINES|LOGNAME|LS_COLORS|MACHTYPE|MAILCHECK|MANDATORY_PATH|NO_AT_BRIDGE|OLDPWD|OPTERR|OPTIND|ORBIT_SOCKETDIR|OSTYPE|PAPERSIZE|PATH|PIPESTATUS|PPID|PS1|PS2|PS3|PS4|PWD|RANDOM|REPLY|SECONDS|SELINUX_INIT|SESSION|SESSIONTYPE|SESSION_MANAGER|SHELL|SHELLOPTS|SHLVL|SSH_AUTH_SOCK|TERM|UID|UPSTART_EVENTS|UPSTART_INSTANCE|UPSTART_JOB|UPSTART_SESSION|USER|WINDOWID|XAUTHORITY|XDG_CONFIG_DIRS|XDG_CURRENT_DESKTOP|XDG_DATA_DIRS|XDG_GREETER_DATA_DIR|XDG_MENU_PREFIX|XDG_RUNTIME_DIR|XDG_SEAT|XDG_SEAT_PATH|XDG_SESSION_DESKTOP|XDG_SESSION_ID|XDG_SESSION_PATH|XDG_SESSION_TYPE|XDG_VTNR|XMODIFIERS)\\b';
916− var insideString = {
917− 'environment': {
918− pattern: RegExp("\\$" + envVars),
919− alias: 'constant'
920− },
921− 'variable': [
922− // [0]: Arithmetic Environment
923− {
924− pattern: /\$?\(\([\s\S]+?\)\)/,
925− greedy: true,
926− inside: {
927− // If there is a $ sign at the beginning highlight $(( and )) as variable
928− 'variable': [
929− {
930− pattern: /(^\$\(\([\s\S]+)\)\)/,
931− lookbehind: true
932− },
933− /^\$\(\(/
934− ],
935− 'number': /\b0x[\dA-Fa-f]+\b|(?:\b\d+\.?\d*|\B\.\d+)(?:[Ee]-?\d+)?/,
936− // Operators according to https://www.gnu.org/software/bash/manual/bashref.html#Shell-Arithmetic
937− 'operator': /--?|-=|\+\+?|\+=|!=?|~|\*\*?|\*=|\/=?|%=?|<<=?|>>=?|<=?|>=?|==?|&&?|&=|\^=?|\|\|?|\|=|\?|:/,
938− // If there is no $ sign at the beginning highlight (( and )) as punctuation
939− 'punctuation': /\(\(?|\)\)?|,|;/
940− }
941− },
942− // [1]: Command Substitution
943− {
944− pattern: /\$\((?:\([^)]+\)|[^()])+\)|`[^`]+`/,
945− greedy: true,
946− inside: {
947− 'variable': /^\$\(|^`|\)$|`$/
948− }
949− },
950− // [2]: Brace expansion
951− {
952− pattern: /\$\{[^}]+\}/,
953− greedy: true,
954− inside: {
955− 'operator': /:[-=?+]?|[!\/]|##?|%%?|\^\^?|,,?/,
956− 'punctuation': /[\[\]]/,
957− 'environment': {
958− pattern: RegExp("(\\{)" + envVars),
959− lookbehind: true,
960− alias: 'constant'
961− }
962− }
963− },
964− /\$(?:\w+|[#?*!@$])/
965− ],
966− // Escape sequences from echo and printf's manuals, and escaped quotes.
967− 'entity': /\\(?:[abceEfnrtv\\"]|O?[0-7]{1,3}|x[0-9a-fA-F]{1,2}|u[0-9a-fA-F]{4}|U[0-9a-fA-F]{8})/
968− };
969−
970− Prism.languages.bash = {
971− 'shebang': {
972− pattern: /^#!\s*\/.*/,
973− alias: 'important'
974− },
975− 'comment': {
976− pattern: /(^|[^"{\\$])#.*/,
977− lookbehind: true
978− },
979− 'function-name': [
980− // a) function foo {
981− // b) foo() {
982− // c) function foo() {
983− // but not “foo {”
984− {
985− // a) and c)
986− pattern: /(\bfunction\s+)\w+(?=(?:\s*\(?:\s*\))?\s*\{)/,
987− lookbehind: true,
988− alias: 'function'
989− },
990− {
991− // b)
992− pattern: /\b\w+(?=\s*\(\s*\)\s*\{)/,
993− alias: 'function'
994− }
995− ],
996− // Highlight variable names as variables in for and select beginnings.
997− 'for-or-select': {
998− pattern: /(\b(?:for|select)\s+)\w+(?=\s+in\s)/,
999− alias: 'variable',
1000− lookbehind: true
1001− },
1002− // Highlight variable names as variables in the left-hand part
1003− // of assignments (“=” and “+=”).
1004− 'assign-left': {
1005− pattern: /(^|[\s;|&]|[<>]\()\w+(?=\+?=)/,
1006− inside: {
1007− 'environment': {
1008− pattern: RegExp("(^|[\\s;|&]|[<>]\\()" + envVars),
1009− lookbehind: true,
1010− alias: 'constant'
1011− }
1012− },
1013− alias: 'variable',
1014− lookbehind: true
1015− },
1016− 'string': [
1017− // Support for Here-documents https://en.wikipedia.org/wiki/Here_document
1018− {
1019− pattern: /((?:^|[^<])<<-?\s*)(\w+?)\s*(?:\r?\n|\r)[\s\S]*?(?:\r?\n|\r)\2/,
1020− lookbehind: true,
1021− greedy: true,
1022− inside: insideString
1023− },
1024− // Here-document with quotes around the tag
1025− // → No expansion (so no “inside”).
1026− {
1027− pattern: /((?:^|[^<])<<-?\s*)(["'])(\w+)\2\s*(?:\r?\n|\r)[\s\S]*?(?:\r?\n|\r)\3/,
1028− lookbehind: true,
1029− greedy: true
1030− },
1031− // “Normal” string
1032− {
1033− pattern: /(["'])(?:\\[\s\S]|\$\([^)]+\)|`[^`]+`|(?!\1)[^\\])*\1/,
1034− greedy: true,
1035− inside: insideString
1036− }
1037− ],
1038− 'environment': {
1039− pattern: RegExp("\\$?" + envVars),
1040− alias: 'constant'
1041− },
1042− 'variable': insideString.variable,
1043− 'function': {
1044− pattern: /(^|[\s;|&]|[<>]\()(?:add|apropos|apt|aptitude|apt-cache|apt-get|aspell|automysqlbackup|awk|basename|bash|bc|bconsole|bg|bzip2|cal|cat|cfdisk|chgrp|chkconfig|chmod|chown|chroot|cksum|clear|cmp|column|comm|cp|cron|crontab|csplit|curl|cut|date|dc|dd|ddrescue|debootstrap|df|diff|diff3|dig|dir|dircolors|dirname|dirs|dmesg|du|egrep|eject|env|ethtool|expand|expect|expr|fdformat|fdisk|fg|fgrep|file|find|fmt|fold|format|free|fsck|ftp|fuser|gawk|git|gparted|grep|groupadd|groupdel|groupmod|groups|grub-mkconfig|gzip|halt|head|hg|history|host|hostname|htop|iconv|id|ifconfig|ifdown|ifup|import|install|ip|jobs|join|kill|killall|less|link|ln|locate|logname|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|pnpm|popd|pr|printcap|printenv|ps|pushd|pv|quota|quotacheck|quotactl|ram|rar|rcp|reboot|remsync|rename|renice|rev|rm|rmdir|rpm|rsync|scp|screen|sdiff|sed|sendmail|seq|service|sftp|sh|shellcheck|shuf|shutdown|sleep|slocate|sort|split|ssh|stat|strace|su|sudo|sum|suspend|swapon|sync|tac|tail|tar|tee|time|timeout|top|touch|tr|traceroute|tsort|tty|umount|uname|unexpand|uniq|units|unrar|unshar|unzip|update-grub|uptime|useradd|userdel|usermod|users|uudecode|uuencode|v|vdir|vi|vim|virsh|vmstat|wait|watch|wc|wget|whereis|which|who|whoami|write|xargs|xdg-open|yarn|yes|zenity|zip|zsh|zypper)(?=$|[)\s;|&])/,
1045− lookbehind: true
1046− },
1047− 'keyword': {
1048− pattern: /(^|[\s;|&]|[<>]\()(?:if|then|else|elif|fi|for|while|in|case|esac|function|select|do|done|until)(?=$|[)\s;|&])/,
1049− lookbehind: true
1050− },
1051− // https://www.gnu.org/software/bash/manual/html_node/Shell-Builtin-Commands.html
1052− 'builtin': {
1053− pattern: /(^|[\s;|&]|[<>]\()(?:\.|:|break|cd|continue|eval|exec|exit|export|getopts|hash|pwd|readonly|return|shift|test|times|trap|umask|unset|alias|bind|builtin|caller|command|declare|echo|enable|help|let|local|logout|mapfile|printf|read|readarray|source|type|typeset|ulimit|unalias|set|shopt)(?=$|[)\s;|&])/,
1054− lookbehind: true,
1055− // Alias added to make those easier to distinguish from strings.
1056− alias: 'class-name'
1057− },
1058− 'boolean': {
1059− pattern: /(^|[\s;|&]|[<>]\()(?:true|false)(?=$|[)\s;|&])/,
1060− lookbehind: true
1061− },
1062− 'file-descriptor': {
1063− pattern: /\B&\d\b/,
1064− alias: 'important'
1065− },
1066− 'operator': {
1067− // Lots of redirections here, but not just that.
1068− pattern: /\d?<>|>\||\+=|==?|!=?|=~|<<[<-]?|[&\d]?>>|\d?[<>]&?|&[>&]?|\|[&|]?|<=?|>=?/,
1069− inside: {
1070− 'file-descriptor': {
1071− pattern: /^\d/,
1072− alias: 'important'
1073− }
1074− }
1075− },
1076− 'punctuation': /\$?\(\(?|\)\)?|\.\.|[{}[\];\\]/,
1077− 'number': {
1078− pattern: /(^|\s)(?:[1-9]\d*|0)(?:[.,]\d+)?\b/,
1079− lookbehind: true
1080− }
1081− };
1082−
1083− /* Patterns in command substitution. */
1084− var toBeCopied = [
1085− 'comment',
1086− 'function-name',
1087− 'for-or-select',
1088− 'assign-left',
1089− 'string',
1090− 'environment',
1091− 'function',
1092− 'keyword',
1093− 'builtin',
1094− 'boolean',
1095− 'file-descriptor',
1096− 'operator',
1097− 'punctuation',
1098− 'number'
1099− ];
1100− var inside = insideString.variable[1].inside;
1101− for(var i = 0; i < toBeCopied.length; i++) {
1102− inside[toBeCopied[i]] = Prism.languages.bash[toBeCopied[i]];
1103− }
1104−
1105− Prism.languages.shell = Prism.languages.bash;
1048+ // $ set | grep '^[A-Z][^[:space:]]*=' | cut -d= -f1 | tr '\n' '|'
1049+ // + LC_ALL, RANDOM, REPLY, SECONDS.
1050+ // + make sure PS1..4 are here as they are not always set,
1051+ // - some useless things.
1052+ var envVars = '\\b(?:BASH|BASHOPTS|BASH_ALIASES|BASH_ARGC|BASH_ARGV|BASH_CMDS|BASH_COMPLETION_COMPAT_DIR|BASH_LINENO|BASH_REMATCH|BASH_SOURCE|BASH_VERSINFO|BASH_VERSION|COLORTERM|COLUMNS|COMP_WORDBREAKS|DBUS_SESSION_BUS_ADDRESS|DEFAULTS_PATH|DESKTOP_SESSION|DIRSTACK|DISPLAY|EUID|GDMSESSION|GDM_LANG|GNOME_KEYRING_CONTROL|GNOME_KEYRING_PID|GPG_AGENT_INFO|GROUPS|HISTCONTROL|HISTFILE|HISTFILESIZE|HISTSIZE|HOME|HOSTNAME|HOSTTYPE|IFS|INSTANCE|JOB|LANG|LANGUAGE|LC_ADDRESS|LC_ALL|LC_IDENTIFICATION|LC_MEASUREMENT|LC_MONETARY|LC_NAME|LC_NUMERIC|LC_PAPER|LC_TELEPHONE|LC_TIME|LESSCLOSE|LESSOPEN|LINES|LOGNAME|LS_COLORS|MACHTYPE|MAILCHECK|MANDATORY_PATH|NO_AT_BRIDGE|OLDPWD|OPTERR|OPTIND|ORBIT_SOCKETDIR|OSTYPE|PAPERSIZE|PATH|PIPESTATUS|PPID|PS1|PS2|PS3|PS4|PWD|RANDOM|REPLY|SECONDS|SELINUX_INIT|SESSION|SESSIONTYPE|SESSION_MANAGER|SHELL|SHELLOPTS|SHLVL|SSH_AUTH_SOCK|TERM|UID|UPSTART_EVENTS|UPSTART_INSTANCE|UPSTART_JOB|UPSTART_SESSION|USER|WINDOWID|XAUTHORITY|XDG_CONFIG_DIRS|XDG_CURRENT_DESKTOP|XDG_DATA_DIRS|XDG_GREETER_DATA_DIR|XDG_MENU_PREFIX|XDG_RUNTIME_DIR|XDG_SEAT|XDG_SEAT_PATH|XDG_SESSION_DESKTOP|XDG_SESSION_ID|XDG_SESSION_PATH|XDG_SESSION_TYPE|XDG_VTNR|XMODIFIERS)\\b';
1053+ var insideString = {
1054+ 'environment': {
1055+ pattern: RegExp("\\$" + envVars),
1056+ alias: 'constant'
1057+ },
1058+ 'variable': [
1059+ // [0]: Arithmetic Environment
1060+ {
1061+ pattern: /\$?\(\([\s\S]+?\)\)/,
1062+ greedy: true,
1063+ inside: {
1064+ // If there is a $ sign at the beginning highlight $(( and )) as variable
1065+ 'variable': [
1066+ {
1067+ pattern: /(^\$\(\([\s\S]+)\)\)/,
1068+ lookbehind: true
1069+ },
1070+ /^\$\(\(/
1071+ ],
1072+ 'number': /\b0x[\dA-Fa-f]+\b|(?:\b\d+\.?\d*|\B\.\d+)(?:[Ee]-?\d+)?/,
1073+ // Operators according to https://www.gnu.org/software/bash/manual/bashref.html#Shell-Arithmetic
1074+ 'operator': /--?|-=|\+\+?|\+=|!=?|~|\*\*?|\*=|\/=?|%=?|<<=?|>>=?|<=?|>=?|==?|&&?|&=|\^=?|\|\|?|\|=|\?|:/,
1075+ // If there is no $ sign at the beginning highlight (( and )) as punctuation
1076+ 'punctuation': /\(\(?|\)\)?|,|;/
1077+ }
1078+ },
1079+ // [1]: Command Substitution
1080+ {
1081+ pattern: /\$\((?:\([^)]+\)|[^()])+\)|`[^`]+`/,
1082+ greedy: true,
1083+ inside: {
1084+ 'variable': /^\$\(|^`|\)$|`$/
1085+ }
1086+ },
1087+ // [2]: Brace expansion
1088+ {
1089+ pattern: /\$\{[^}]+\}/,
1090+ greedy: true,
1091+ inside: {
1092+ 'operator': /:[-=?+]?|[!\/]|##?|%%?|\^\^?|,,?/,
1093+ 'punctuation': /[\[\]]/,
1094+ 'environment': {
1095+ pattern: RegExp("(\\{)" + envVars),
1096+ lookbehind: true,
1097+ alias: 'constant'
1098+ }
1099+ }
1100+ },
1101+ /\$(?:\w+|[#?*!@$])/
1102+ ],
1103+ // Escape sequences from echo and printf's manuals, and escaped quotes.
1104+ 'entity': /\\(?:[abceEfnrtv\\"]|O?[0-7]{1,3}|x[0-9a-fA-F]{1,2}|u[0-9a-fA-F]{4}|U[0-9a-fA-F]{8})/
1105+ };
1106+
1107+ Prism.languages.bash = {
1108+ 'shebang': {
1109+ pattern: /^#!\s*\/.*/,
1110+ alias: 'important'
1111+ },
1112+ 'comment': {
1113+ pattern: /(^|[^"{\\$])#.*/,
1114+ lookbehind: true
1115+ },
1116+ 'function-name': [
1117+ // a) function foo {
1118+ // b) foo() {
1119+ // c) function foo() {
1120+ // but not “foo {”
1121+ {
1122+ // a) and c)
1123+ pattern: /(\bfunction\s+)\w+(?=(?:\s*\(?:\s*\))?\s*\{)/,
1124+ lookbehind: true,
1125+ alias: 'function'
1126+ },
1127+ {
1128+ // b)
1129+ pattern: /\b\w+(?=\s*\(\s*\)\s*\{)/,
1130+ alias: 'function'
1131+ }
1132+ ],
1133+ // Highlight variable names as variables in for and select beginnings.
1134+ 'for-or-select': {
1135+ pattern: /(\b(?:for|select)\s+)\w+(?=\s+in\s)/,
1136+ alias: 'variable',
1137+ lookbehind: true
1138+ },
1139+ // Highlight variable names as variables in the left-hand part
1140+ // of assignments (“=” and “+=”).
1141+ 'assign-left': {
1142+ pattern: /(^|[\s;|&]|[<>]\()\w+(?=\+?=)/,
1143+ inside: {
1144+ 'environment': {
1145+ pattern: RegExp("(^|[\\s;|&]|[<>]\\()" + envVars),
1146+ lookbehind: true,
1147+ alias: 'constant'
1148+ }
1149+ },
1150+ alias: 'variable',
1151+ lookbehind: true
1152+ },
1153+ 'string': [
1154+ // Support for Here-documents https://en.wikipedia.org/wiki/Here_document
1155+ {
1156+ pattern: /((?:^|[^<])<<-?\s*)(\w+?)\s*(?:\r?\n|\r)[\s\S]*?(?:\r?\n|\r)\2/,
1157+ lookbehind: true,
1158+ greedy: true,
1159+ inside: insideString
1160+ },
1161+ // Here-document with quotes around the tag
1162+ // → No expansion (so no “inside”).
1163+ {
1164+ pattern: /((?:^|[^<])<<-?\s*)(["'])(\w+)\2\s*(?:\r?\n|\r)[\s\S]*?(?:\r?\n|\r)\3/,
1165+ lookbehind: true,
1166+ greedy: true
1167+ },
1168+ // “Normal” string
1169+ {
1170+ pattern: /(^|[^\\](?:\\\\)*)(["'])(?:\\[\s\S]|\$\([^)]+\)|`[^`]+`|(?!\2)[^\\])*\2/,
1171+ lookbehind: true,
1172+ greedy: true,
1173+ inside: insideString
1174+ }
1175+ ],
1176+ 'environment': {
1177+ pattern: RegExp("\\$?" + envVars),
1178+ alias: 'constant'
1179+ },
1180+ 'variable': insideString.variable,
1181+ 'function': {
1182+ pattern: /(^|[\s;|&]|[<>]\()(?:add|apropos|apt|aptitude|apt-cache|apt-get|aspell|automysqlbackup|awk|basename|bash|bc|bconsole|bg|bzip2|cal|cat|cfdisk|chgrp|chkconfig|chmod|chown|chroot|cksum|clear|cmp|column|comm|composer|cp|cron|crontab|csplit|curl|cut|date|dc|dd|ddrescue|debootstrap|df|diff|diff3|dig|dir|dircolors|dirname|dirs|dmesg|du|egrep|eject|env|ethtool|expand|expect|expr|fdformat|fdisk|fg|fgrep|file|find|fmt|fold|format|free|fsck|ftp|fuser|gawk|git|gparted|grep|groupadd|groupdel|groupmod|groups|grub-mkconfig|gzip|halt|head|hg|history|host|hostname|htop|iconv|id|ifconfig|ifdown|ifup|import|install|ip|jobs|join|kill|killall|less|link|ln|locate|logname|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|pnpm|popd|pr|printcap|printenv|ps|pushd|pv|quota|quotacheck|quotactl|ram|rar|rcp|reboot|remsync|rename|renice|rev|rm|rmdir|rpm|rsync|scp|screen|sdiff|sed|sendmail|seq|service|sftp|sh|shellcheck|shuf|shutdown|sleep|slocate|sort|split|ssh|stat|strace|su|sudo|sum|suspend|swapon|sync|tac|tail|tar|tee|time|timeout|top|touch|tr|traceroute|tsort|tty|umount|uname|unexpand|uniq|units|unrar|unshar|unzip|update-grub|uptime|useradd|userdel|usermod|users|uudecode|uuencode|v|vdir|vi|vim|virsh|vmstat|wait|watch|wc|wget|whereis|which|who|whoami|write|xargs|xdg-open|yarn|yes|zenity|zip|zsh|zypper)(?=$|[)\s;|&])/,
1183+ lookbehind: true
1184+ },
1185+ 'keyword': {
1186+ pattern: /(^|[\s;|&]|[<>]\()(?:if|then|else|elif|fi|for|while|in|case|esac|function|select|do|done|until)(?=$|[)\s;|&])/,
1187+ lookbehind: true
1188+ },
1189+ // https://www.gnu.org/software/bash/manual/html_node/Shell-Builtin-Commands.html
1190+ 'builtin': {
1191+ pattern: /(^|[\s;|&]|[<>]\()(?:\.|:|break|cd|continue|eval|exec|exit|export|getopts|hash|pwd|readonly|return|shift|test|times|trap|umask|unset|alias|bind|builtin|caller|command|declare|echo|enable|help|let|local|logout|mapfile|printf|read|readarray|source|type|typeset|ulimit|unalias|set|shopt)(?=$|[)\s;|&])/,
1192+ lookbehind: true,
1193+ // Alias added to make those easier to distinguish from strings.
1194+ alias: 'class-name'
1195+ },
1196+ 'boolean': {
1197+ pattern: /(^|[\s;|&]|[<>]\()(?:true|false)(?=$|[)\s;|&])/,
1198+ lookbehind: true
1199+ },
1200+ 'file-descriptor': {
1201+ pattern: /\B&\d\b/,
1202+ alias: 'important'
1203+ },
1204+ 'operator': {
1205+ // Lots of redirections here, but not just that.
1206+ pattern: /\d?<>|>\||\+=|==?|!=?|=~|<<[<-]?|[&\d]?>>|\d?[<>]&?|&[>&]?|\|[&|]?|<=?|>=?/,
1207+ inside: {
1208+ 'file-descriptor': {
1209+ pattern: /^\d/,
1210+ alias: 'important'
1211+ }
1212+ }
1213+ },
1214+ 'punctuation': /\$?\(\(?|\)\)?|\.\.|[{}[\];\\]/,
1215+ 'number': {
1216+ pattern: /(^|\s)(?:[1-9]\d*|0)(?:[.,]\d+)?\b/,
1217+ lookbehind: true
1218+ }
1219+ };
1220+
1221+ /* Patterns in command substitution. */
1222+ var toBeCopied = [
1223+ 'comment',
1224+ 'function-name',
1225+ 'for-or-select',
1226+ 'assign-left',
1227+ 'string',
1228+ 'environment',
1229+ 'function',
1230+ 'keyword',
1231+ 'builtin',
1232+ 'boolean',
1233+ 'file-descriptor',
1234+ 'operator',
1235+ 'punctuation',
1236+ 'number'
1237+ ];
1238+ var inside = insideString.variable[1].inside;
1239+ for(var i = 0; i < toBeCopied.length; i++) {
1240+ inside[toBeCopied[i]] = Prism.languages.bash[toBeCopied[i]];
1241+ }
1242+
1243+ Prism.languages.shell = Prism.languages.bash;
11061244 })(Prism);
11071245
11081246 Prism.languages.c = Prism.languages.extend('clike', {
1109− 'class-name': {
1110− pattern: /(\b(?:enum|struct)\s+)\w+/,
1111− lookbehind: true
1112− },
1113− '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/,
1114− 'operator': />>=?|<<=?|->|([-+&|:])\1|[?:~]|[-+*/%&|^!=<>]=?/,
1115− 'number': /(?:\b0x(?:[\da-f]+\.?[\da-f]*|\.[\da-f]+)(?:p[+-]?\d+)?|(?:\b\d+\.?\d*|\B\.\d+)(?:e[+-]?\d+)?)[ful]*/i
1247+ 'comment': {
1248+ pattern: /\/\/(?:[^\r\n\\]|\\(?:\r\n?|\n|(?![\r\n])))*|\/\*[\s\S]*?(?:\*\/|$)/,
1249+ greedy: true
1250+ },
1251+ 'class-name': {
1252+ pattern: /(\b(?:enum|struct)\s+(?:__attribute__\s*\(\([\s\S]*?\)\)\s*)?)\w+/,
1253+ lookbehind: true
1254+ },
1255+ 'keyword': /\b(?:__attribute__|_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/,
1256+ 'function': /[a-z_]\w*(?=\s*\()/i,
1257+ 'operator': />>=?|<<=?|->|([-+&|:])\1|[?:~]|[-+*/%&|^!=<>]=?/,
1258+ 'number': /(?:\b0x(?:[\da-f]+\.?[\da-f]*|\.[\da-f]+)(?:p[+-]?\d+)?|(?:\b\d+\.?\d*|\B\.\d+)(?:e[+-]?\d+)?)[ful]*/i
11161259 });
11171260
11181261 Prism.languages.insertBefore('c', 'string', {
1119− 'macro': {
1120− // allow for multiline macro definitions
1121− // spaces after the # character compile fine with gcc
1122− pattern: /(^\s*)#\s*[a-z]+(?:[^\r\n\\]|\\(?:\r\n|[\s\S]))*/im,
1123− lookbehind: true,
1124− alias: 'property',
1125− inside: {
1126− // highlight the path of the include statement as a string
1127− 'string': {
1128− pattern: /(#\s*include\s*)(?:<.+?>|("|')(?:\\?.)+?\2)/,
1129− lookbehind: true
1130− },
1131− // highlight macro directives as keywords
1132− 'directive': {
1133− pattern: /(#\s*)\b(?:define|defined|elif|else|endif|error|ifdef|ifndef|if|import|include|line|pragma|undef|using)\b/,
1134− lookbehind: true,
1135− alias: 'keyword'
1136− }
1137− }
1138− },
1139− // highlight predefined macros as constants
1140− 'constant': /\b(?:__FILE__|__LINE__|__DATE__|__TIME__|__TIMESTAMP__|__func__|EOF|NULL|SEEK_CUR|SEEK_END|SEEK_SET|stdin|stdout|stderr)\b/
1262+ 'macro': {
1263+ // allow for multiline macro definitions
1264+ // spaces after the # character compile fine with gcc
1265+ pattern: /(^\s*)#\s*[a-z]+(?:[^\r\n\\/]|\/(?!\*)|\/\*(?:[^*]|\*(?!\/))*\*\/|\\(?:\r\n|[\s\S]))*/im,
1266+ lookbehind: true,
1267+ greedy: true,
1268+ alias: 'property',
1269+ inside: {
1270+ 'string': [
1271+ {
1272+ // highlight the path of the include statement as a string
1273+ pattern: /^(#\s*include\s*)<[^>]+>/,
1274+ lookbehind: true
1275+ },
1276+ Prism.languages.c['string']
1277+ ],
1278+ 'comment': Prism.languages.c['comment'],
1279+ // highlight macro directives as keywords
1280+ 'directive': {
1281+ pattern: /^(#\s*)[a-z]+/,
1282+ lookbehind: true,
1283+ alias: 'keyword'
1284+ }
1285+ }
1286+ },
1287+ // highlight predefined macros as constants
1288+ 'constant': /\b(?:__FILE__|__LINE__|__DATE__|__TIME__|__TIMESTAMP__|__func__|EOF|NULL|SEEK_CUR|SEEK_END|SEEK_SET|stdin|stdout|stderr)\b/
11411289 });
11421290
11431291 delete Prism.languages.c['boolean'];
11441292
1145−Prism.languages.cpp = Prism.languages.extend('c', {
1146− 'class-name': {
1147− pattern: /(\b(?:class|enum|struct)\s+)\w+/,
1148− lookbehind: true
1149− },
1150− '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/,
1151− 'number': {
1152− pattern: /(?:\b0b[01']+|\b0x(?:[\da-f']+\.?[\da-f']*|\.[\da-f']+)(?:p[+-]?[\d']+)?|(?:\b[\d']+\.?[\d']*|\B\.[\d']+)(?:e[+-]?[\d']+)?)[ful]*/i,
1153− greedy: true
1154− },
1155− 'operator': />>=?|<<=?|->|([-+&|:])\1|[?:~]|[-+*/%&|^!=<>]=?|\b(?:and|and_eq|bitand|bitor|not|not_eq|or|or_eq|xor|xor_eq)\b/,
1156− 'boolean': /\b(?:true|false)\b/
1157−});
1293+(function (Prism) {
11581294
1159−Prism.languages.insertBefore('cpp', 'string', {
1160− 'raw-string': {
1161− pattern: /R"([^()\\ ]{0,16})\([\s\S]*?\)\1"/,
1162− alias: 'string',
1163− greedy: true
1164− }
1165−});
1295+ var keyword = /\b(?:alignas|alignof|asm|auto|bool|break|case|catch|char|char8_t|char16_t|char32_t|class|compl|concept|const|consteval|constexpr|constinit|const_cast|continue|co_await|co_return|co_yield|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|requires|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/;
1296+
1297+ Prism.languages.cpp = Prism.languages.extend('c', {
1298+ 'class-name': [
1299+ {
1300+ pattern: RegExp(/(\b(?:class|enum|struct|typename)\s+)(?!<keyword>)\w+/.source
1301+ .replace(/<keyword>/g, function () { return keyword.source; })),
1302+ lookbehind: true
1303+ },
1304+ // This is intended to capture the class name of method implementations like:
1305+ // void foo::bar() const {}
1306+ // However! The `foo` in the above example could also be a namespace, so we only capture the class name if
1307+ // it starts with an uppercase letter. This approximation should give decent results.
1308+ /\b[A-Z]\w*(?=\s*::\s*\w+\s*\()/,
1309+ // This will capture the class name before destructors like:
1310+ // Foo::~Foo() {}
1311+ /\b[A-Z_]\w*(?=\s*::\s*~\w+\s*\()/i,
1312+ {
1313+ // This also intends to capture the class name of method implementations but here the class has template
1314+ // parameters, so it can't be a namespace (until C++ adds generic namespaces).
1315+ pattern: /\w+(?=\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>\s*::\s*\w+\s*\()/,
1316+ inside: null // see below
1317+ }
1318+ ],
1319+ 'keyword': keyword,
1320+ 'number': {
1321+ pattern: /(?:\b0b[01']+|\b0x(?:[\da-f']+\.?[\da-f']*|\.[\da-f']+)(?:p[+-]?[\d']+)?|(?:\b[\d']+\.?[\d']*|\B\.[\d']+)(?:e[+-]?[\d']+)?)[ful]*/i,
1322+ greedy: true
1323+ },
1324+ 'operator': />>=?|<<=?|->|([-+&|:])\1|[?:~]|[-+*/%&|^!=<>]=?|\b(?:and|and_eq|bitand|bitor|not|not_eq|or|or_eq|xor|xor_eq)\b/,
1325+ 'boolean': /\b(?:true|false)\b/
1326+ });
1327+
1328+ Prism.languages.insertBefore('cpp', 'string', {
1329+ 'raw-string': {
1330+ pattern: /R"([^()\\ ]{0,16})\([\s\S]*?\)\1"/,
1331+ alias: 'string',
1332+ greedy: true
1333+ }
1334+ });
1335+
1336+ Prism.languages.insertBefore('cpp', 'class-name', {
1337+ // the base clause is an optional list of parent classes
1338+ // https://en.cppreference.com/w/cpp/language/class
1339+ 'base-clause': {
1340+ pattern: /(\b(?:class|struct)\s+\w+\s*:\s*)(?:[^;{}"'])+?(?=\s*[;{])/,
1341+ lookbehind: true,
1342+ greedy: true,
1343+ inside: Prism.languages.extend('cpp', {})
1344+ }
1345+ });
1346+ Prism.languages.insertBefore('inside', 'operator', {
1347+ // All untokenized words that are not namespaces should be class names
1348+ 'class-name': /\b[a-z_]\w*\b(?!\s*::)/i
1349+ }, Prism.languages.cpp['base-clause']);
1350+
1351+}(Prism));
11661352
11671353 (function(Prism) {
11681354
11691355 // Ignore comments starting with { to privilege string interpolation highlighting
11701356 var comment = /#(?!\{).+/,
11711357 interpolation = {
1172− pattern: /#\{[^}]+\}/,
1173− alias: 'variable'
1358+ pattern: /#\{[^}]+\}/,
1359+ alias: 'variable'
11741360 };
11751361
11761362 Prism.languages.coffeescript = Prism.languages.extend('javascript', {
1177− 'comment': comment,
1178− 'string': [
1179−
1180− // Strings are multiline
1181− {
1182− pattern: /'(?:\\[\s\S]|[^\\'])*'/,
1183− greedy: true
1184− },
1185−
1186− {
1187− // Strings are multiline
1188− pattern: /"(?:\\[\s\S]|[^\\"])*"/,
1189− greedy: true,
1190− inside: {
1191− 'interpolation': interpolation
1192− }
1193− }
1194− ],
1195− 'keyword': /\b(?:and|break|by|catch|class|continue|debugger|delete|do|each|else|extend|extends|false|finally|for|if|in|instanceof|is|isnt|let|loop|namespace|new|no|not|null|of|off|on|or|own|return|super|switch|then|this|throw|true|try|typeof|undefined|unless|until|when|while|window|with|yes|yield)\b/,
1196− 'class-member': {
1197− pattern: /@(?!\d)\w+/,
1198− alias: 'variable'
1199− }
1363+ 'comment': comment,
1364+ 'string': [
1365+
1366+ // Strings are multiline
1367+ {
1368+ pattern: /'(?:\\[\s\S]|[^\\'])*'/,
1369+ greedy: true
1370+ },
1371+
1372+ {
1373+ // Strings are multiline
1374+ pattern: /"(?:\\[\s\S]|[^\\"])*"/,
1375+ greedy: true,
1376+ inside: {
1377+ 'interpolation': interpolation
1378+ }
1379+ }
1380+ ],
1381+ 'keyword': /\b(?:and|break|by|catch|class|continue|debugger|delete|do|each|else|extend|extends|false|finally|for|if|in|instanceof|is|isnt|let|loop|namespace|new|no|not|null|of|off|on|or|own|return|super|switch|then|this|throw|true|try|typeof|undefined|unless|until|when|while|window|with|yes|yield)\b/,
1382+ 'class-member': {
1383+ pattern: /@(?!\d)\w+/,
1384+ alias: 'variable'
1385+ }
12001386 });
12011387
12021388 Prism.languages.insertBefore('coffeescript', 'comment', {
1203− 'multiline-comment': {
1204− pattern: /###[\s\S]+?###/,
1205− alias: 'comment'
1206− },
1207−
1208− // Block regexp can contain comments and interpolation
1209− 'block-regex': {
1210− pattern: /\/{3}[\s\S]*?\/{3}/,
1211− alias: 'regex',
1212− inside: {
1213− 'comment': comment,
1214− 'interpolation': interpolation
1215− }
1216− }
1389+ 'multiline-comment': {
1390+ pattern: /###[\s\S]+?###/,
1391+ alias: 'comment'
1392+ },
1393+
1394+ // Block regexp can contain comments and interpolation
1395+ 'block-regex': {
1396+ pattern: /\/{3}[\s\S]*?\/{3}/,
1397+ alias: 'regex',
1398+ inside: {
1399+ 'comment': comment,
1400+ 'interpolation': interpolation
1401+ }
1402+ }
12171403 });
12181404
12191405 Prism.languages.insertBefore('coffeescript', 'string', {
1220− 'inline-javascript': {
1221− pattern: /`(?:\\[\s\S]|[^\\`])*`/,
1222− inside: {
1223− 'delimiter': {
1224− pattern: /^`|`$/,
1225− alias: 'punctuation'
1226− },
1227− rest: Prism.languages.javascript
1228− }
1229− },
1230−
1231− // Block strings
1232− 'multiline-string': [
1233− {
1234− pattern: /'''[\s\S]*?'''/,
1235− greedy: true,
1236− alias: 'string'
1237− },
1238− {
1239− pattern: /"""[\s\S]*?"""/,
1240− greedy: true,
1241− alias: 'string',
1242− inside: {
1243− interpolation: interpolation
1244− }
1245− }
1246− ]
1406+ 'inline-javascript': {
1407+ pattern: /`(?:\\[\s\S]|[^\\`])*`/,
1408+ inside: {
1409+ 'delimiter': {
1410+ pattern: /^`|`$/,
1411+ alias: 'punctuation'
1412+ },
1413+ rest: Prism.languages.javascript
1414+ }
1415+ },
1416+
1417+ // Block strings
1418+ 'multiline-string': [
1419+ {
1420+ pattern: /'''[\s\S]*?'''/,
1421+ greedy: true,
1422+ alias: 'string'
1423+ },
1424+ {
1425+ pattern: /"""[\s\S]*?"""/,
1426+ greedy: true,
1427+ alias: 'string',
1428+ inside: {
1429+ interpolation: interpolation
1430+ }
1431+ }
1432+ ]
12471433
12481434 });
12491435
12501436 Prism.languages.insertBefore('coffeescript', 'keyword', {
1251− // Object property
1252− 'property': /(?!\d)\w+(?=\s*:(?!:))/
1437+ // Object property
1438+ 'property': /(?!\d)\w+(?=\s*:(?!:))/
12531439 });
12541440
12551441 delete Prism.languages.coffeescript['template-string'];
@@ -1262,428 +1448,385 @@ Prism.languages.coffee = Prism.languages.coffeescript; · 6 unmodified lines
12621448 * Adds the following new token classes:
12631449 * constant, builtin, variable, symbol, regex
12641450 */
1265−(function(Prism) {
1266− Prism.languages.ruby = Prism.languages.extend('clike', {
1267− 'comment': [
1268− /#.*/,
1269− {
1270− pattern: /^=begin\s[\s\S]*?^=end/m,
1271− greedy: true
1272− }
1273− ],
1274− 'class-name': {
1275− pattern: /(\b(?:class)\s+|\bcatch\s+\()[\w.\\]+/i,
1276− lookbehind: true,
1277− inside: {
1278− 'punctuation': /[.\\]/
1279− }
1280− },
1281− 'keyword': /\b(?:alias|and|BEGIN|begin|break|case|class|def|define_method|defined|do|each|else|elsif|END|end|ensure|extend|for|if|in|include|module|new|next|nil|not|or|prepend|protected|private|public|raise|redo|require|rescue|retry|return|self|super|then|throw|undef|unless|until|when|while|yield)\b/
1282− });
1283−
1284− var interpolation = {
1285− pattern: /#\{[^}]+\}/,
1286− inside: {
1287− 'delimiter': {
1288− pattern: /^#\{|\}$/,
1289− alias: 'tag'
1290− },
1291− rest: Prism.languages.ruby
1292− }
1293− };
1294−
1295− delete Prism.languages.ruby.function;
1296−
1297− Prism.languages.insertBefore('ruby', 'keyword', {
1298− 'regex': [
1299− {
1300− pattern: /%r([^a-zA-Z0-9\s{(\[<])(?:(?!\1)[^\\]|\\[\s\S])*\1[gim]{0,3}/,
1301− greedy: true,
1302− inside: {
1303− 'interpolation': interpolation
1304− }
1305− },
1306− {
1307− pattern: /%r\((?:[^()\\]|\\[\s\S])*\)[gim]{0,3}/,
1308− greedy: true,
1309− inside: {
1310− 'interpolation': interpolation
1311− }
1312− },
1313− {
1314− // Here we need to specifically allow interpolation
1315− pattern: /%r\{(?:[^#{}\\]|#(?:\{[^}]+\})?|\\[\s\S])*\}[gim]{0,3}/,
1316− greedy: true,
1317− inside: {
1318− 'interpolation': interpolation
1319− }
1320− },
1321− {
1322− pattern: /%r\[(?:[^\[\]\\]|\\[\s\S])*\][gim]{0,3}/,
1323− greedy: true,
1324− inside: {
1325− 'interpolation': interpolation
1326− }
1327− },
1328− {
1329− pattern: /%r<(?:[^<>\\]|\\[\s\S])*>[gim]{0,3}/,
1330− greedy: true,
1331− inside: {
1332− 'interpolation': interpolation
1333− }
1334− },
1335− {
1336− pattern: /(^|[^/])\/(?!\/)(?:\[.+?]|\\.|[^/\\\r\n])+\/[gim]{0,3}(?=\s*(?:$|[\r\n,.;})]))/,
1337− lookbehind: true,
1338− greedy: true
1339− }
1340− ],
1341− 'variable': /[@$]+[a-zA-Z_]\w*(?:[?!]|\b)/,
1342− 'symbol': {
1343− pattern: /(^|[^:]):[a-zA-Z_]\w*(?:[?!]|\b)/,
1344− lookbehind: true
1345− },
1346− 'method-definition': {
1347− pattern: /(\bdef\s+)[\w.]+/,
1348− lookbehind: true,
1349− inside: {
1350− 'function': /\w+$/,
1351− rest: Prism.languages.ruby
1352− }
1353− }
1354− });
1355−
1356− Prism.languages.insertBefore('ruby', 'number', {
1357− 'builtin': /\b(?:Array|Bignum|Binding|Class|Continuation|Dir|Exception|FalseClass|File|Stat|Fixnum|Float|Hash|Integer|IO|MatchData|Method|Module|NilClass|Numeric|Object|Proc|Range|Regexp|String|Struct|TMS|Symbol|ThreadGroup|Thread|Time|TrueClass)\b/,
1358− 'constant': /\b[A-Z]\w*(?:[?!]|\b)/
1359− });
1360−
1361− Prism.languages.ruby.string = [
1362− {
1363− pattern: /%[qQiIwWxs]?([^a-zA-Z0-9\s{(\[<])(?:(?!\1)[^\\]|\\[\s\S])*\1/,
1364− greedy: true,
1365− inside: {
1366− 'interpolation': interpolation
1367− }
1368− },
1369− {
1370− pattern: /%[qQiIwWxs]?\((?:[^()\\]|\\[\s\S])*\)/,
1371− greedy: true,
1372− inside: {
1373− 'interpolation': interpolation
1374− }
1375− },
1376− {
1377− // Here we need to specifically allow interpolation
1378− pattern: /%[qQiIwWxs]?\{(?:[^#{}\\]|#(?:\{[^}]+\})?|\\[\s\S])*\}/,
1379− greedy: true,
1380− inside: {
1381− 'interpolation': interpolation
1382− }
1383− },
1384− {
1385− pattern: /%[qQiIwWxs]?\[(?:[^\[\]\\]|\\[\s\S])*\]/,
1386− greedy: true,
1387− inside: {
1388− 'interpolation': interpolation
1389− }
1390− },
1391− {
1392− pattern: /%[qQiIwWxs]?<(?:[^<>\\]|\\[\s\S])*>/,
1393− greedy: true,
1394− inside: {
1395− 'interpolation': interpolation
1396− }
1397− },
1398− {
1399− pattern: /("|')(?:#\{[^}]+\}|\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,
1400− greedy: true,
1401− inside: {
1402− 'interpolation': interpolation
1403− }
1404− }
1405− ];
1406−
1407− Prism.languages.rb = Prism.languages.ruby;
1451+(function (Prism) {
1452+ Prism.languages.ruby = Prism.languages.extend('clike', {
1453+ 'comment': [
1454+ /#.*/,
1455+ {
1456+ pattern: /^=begin\s[\s\S]*?^=end/m,
1457+ greedy: true
1458+ }
1459+ ],
1460+ 'class-name': {
1461+ pattern: /(\b(?:class)\s+|\bcatch\s+\()[\w.\\]+/i,
1462+ lookbehind: true,
1463+ inside: {
1464+ 'punctuation': /[.\\]/
1465+ }
1466+ },
1467+ 'keyword': /\b(?:alias|and|BEGIN|begin|break|case|class|def|define_method|defined|do|each|else|elsif|END|end|ensure|extend|for|if|in|include|module|new|next|nil|not|or|prepend|protected|private|public|raise|redo|require|rescue|retry|return|self|super|then|throw|undef|unless|until|when|while|yield)\b/
1468+ });
1469+
1470+ var interpolation = {
1471+ pattern: /#\{[^}]+\}/,
1472+ inside: {
1473+ 'delimiter': {
1474+ pattern: /^#\{|\}$/,
1475+ alias: 'tag'
1476+ },
1477+ rest: Prism.languages.ruby
1478+ }
1479+ };
1480+
1481+ delete Prism.languages.ruby.function;
1482+
1483+ Prism.languages.insertBefore('ruby', 'keyword', {
1484+ 'regex': [
1485+ {
1486+ pattern: RegExp(/%r/.source + '(?:' + [
1487+ /([^a-zA-Z0-9\s{(\[<])(?:(?!\1)[^\\]|\\[\s\S])*\1[gim]{0,3}/.source,
1488+ /\((?:[^()\\]|\\[\s\S])*\)[gim]{0,3}/.source,
1489+ // Here we need to specifically allow interpolation
1490+ /\{(?:[^#{}\\]|#(?:\{[^}]+\})?|\\[\s\S])*\}[gim]{0,3}/.source,
1491+ /\[(?:[^\[\]\\]|\\[\s\S])*\][gim]{0,3}/.source,
1492+ /<(?:[^<>\\]|\\[\s\S])*>[gim]{0,3}/.source
1493+ ].join('|') + ')'),
1494+ greedy: true,
1495+ inside: {
1496+ 'interpolation': interpolation
1497+ }
1498+ },
1499+ {
1500+ pattern: /(^|[^/])\/(?!\/)(?:\[[^\r\n\]]+\]|\\.|[^[/\\\r\n])+\/[gim]{0,3}(?=\s*(?:$|[\r\n,.;})]))/,
1501+ lookbehind: true,
1502+ greedy: true
1503+ }
1504+ ],
1505+ 'variable': /[@$]+[a-zA-Z_]\w*(?:[?!]|\b)/,
1506+ 'symbol': {
1507+ pattern: /(^|[^:]):[a-zA-Z_]\w*(?:[?!]|\b)/,
1508+ lookbehind: true
1509+ },
1510+ 'method-definition': {
1511+ pattern: /(\bdef\s+)[\w.]+/,
1512+ lookbehind: true,
1513+ inside: {
1514+ 'function': /\w+$/,
1515+ rest: Prism.languages.ruby
1516+ }
1517+ }
1518+ });
1519+
1520+ Prism.languages.insertBefore('ruby', 'number', {
1521+ 'builtin': /\b(?:Array|Bignum|Binding|Class|Continuation|Dir|Exception|FalseClass|File|Stat|Fixnum|Float|Hash|Integer|IO|MatchData|Method|Module|NilClass|Numeric|Object|Proc|Range|Regexp|String|Struct|TMS|Symbol|ThreadGroup|Thread|Time|TrueClass)\b/,
1522+ 'constant': /\b[A-Z]\w*(?:[?!]|\b)/
1523+ });
1524+
1525+ Prism.languages.ruby.string = [
1526+ {
1527+ pattern: RegExp(/%[qQiIwWxs]?/.source + '(?:' + [
1528+ /([^a-zA-Z0-9\s{(\[<])(?:(?!\1)[^\\]|\\[\s\S])*\1/.source,
1529+ /\((?:[^()\\]|\\[\s\S])*\)/.source,
1530+ // Here we need to specifically allow interpolation
1531+ /\{(?:[^#{}\\]|#(?:\{[^}]+\})?|\\[\s\S])*\}/.source,
1532+ /\[(?:[^\[\]\\]|\\[\s\S])*\]/.source,
1533+ /<(?:[^<>\\]|\\[\s\S])*>/.source
1534+ ].join('|') + ')'),
1535+ greedy: true,
1536+ inside: {
1537+ 'interpolation': interpolation
1538+ }
1539+ },
1540+ {
1541+ pattern: /("|')(?:#\{[^}]+\}|\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,
1542+ greedy: true,
1543+ inside: {
1544+ 'interpolation': interpolation
1545+ }
1546+ }
1547+ ];
1548+
1549+ Prism.languages.rb = Prism.languages.ruby;
14081550 }(Prism));
14091551
14101552 (function(Prism) {
1411− Prism.languages.crystal = Prism.languages.extend('ruby', {
1412− keyword: [
1413− /\b(?:abstract|alias|as|asm|begin|break|case|class|def|do|else|elsif|end|ensure|enum|extend|for|fun|if|include|instance_sizeof|lib|macro|module|next|of|out|pointerof|private|protected|rescue|return|require|select|self|sizeof|struct|super|then|type|typeof|uninitialized|union|unless|until|when|while|with|yield|__DIR__|__END_LINE__|__FILE__|__LINE__)\b/,
1414− {
1415− pattern: /(\.\s*)(?:is_a|responds_to)\?/,
1416− lookbehind: true
1417− }
1418− ],
1419−
1420− number: /\b(?:0b[01_]*[01]|0o[0-7_]*[0-7]|0x[\da-fA-F_]*[\da-fA-F]|(?:\d(?:[\d_]*\d)?)(?:\.[\d_]*\d)?(?:[eE][+-]?[\d_]*\d)?)(?:_(?:[uif](?:8|16|32|64))?)?\b/
1421− });
1422−
1423− Prism.languages.insertBefore('crystal', 'string', {
1424− attribute: {
1425− pattern: /@\[.+?\]/,
1426− alias: 'attr-name',
1427− inside: {
1428− delimiter: {
1429− pattern: /^@\[|\]$/,
1430− alias: 'tag'
1431− },
1432− rest: Prism.languages.crystal
1433− }
1434− },
1435−
1436− expansion: [
1437− {
1438− pattern: /\{\{.+?\}\}/,
1439− inside: {
1440− delimiter: {
1441− pattern: /^\{\{|\}\}$/,
1442− alias: 'tag'
1443− },
1444− rest: Prism.languages.crystal
1445− }
1446− },
1447− {
1448− pattern: /\{%.+?%\}/,
1449− inside: {
1450− delimiter: {
1451− pattern: /^\{%|%\}$/,
1452− alias: 'tag'
1453− },
1454− rest: Prism.languages.crystal
1455− }
1456− }
1457− ]
1458− });
1553+ Prism.languages.crystal = Prism.languages.extend('ruby', {
1554+ keyword: [
1555+ /\b(?:abstract|alias|as|asm|begin|break|case|class|def|do|else|elsif|end|ensure|enum|extend|for|fun|if|include|instance_sizeof|lib|macro|module|next|of|out|pointerof|private|protected|rescue|return|require|select|self|sizeof|struct|super|then|type|typeof|uninitialized|union|unless|until|when|while|with|yield|__DIR__|__END_LINE__|__FILE__|__LINE__)\b/,
1556+ {
1557+ pattern: /(\.\s*)(?:is_a|responds_to)\?/,
1558+ lookbehind: true
1559+ }
1560+ ],
1561+
1562+ number: /\b(?:0b[01_]*[01]|0o[0-7_]*[0-7]|0x[\da-fA-F_]*[\da-fA-F]|(?:\d(?:[\d_]*\d)?)(?:\.[\d_]*\d)?(?:[eE][+-]?[\d_]*\d)?)(?:_(?:[uif](?:8|16|32|64))?)?\b/
1563+ });
1564+
1565+ Prism.languages.insertBefore('crystal', 'string', {
1566+ attribute: {
1567+ pattern: /@\[.+?\]/,
1568+ alias: 'attr-name',
1569+ inside: {
1570+ delimiter: {
1571+ pattern: /^@\[|\]$/,
1572+ alias: 'tag'
1573+ },
1574+ rest: Prism.languages.crystal
1575+ }
1576+ },
1577+
1578+ expansion: [
1579+ {
1580+ pattern: /\{\{.+?\}\}/,
1581+ inside: {
1582+ delimiter: {
1583+ pattern: /^\{\{|\}\}$/,
1584+ alias: 'tag'
1585+ },
1586+ rest: Prism.languages.crystal
1587+ }
1588+ },
1589+ {
1590+ pattern: /\{%.+?%\}/,
1591+ inside: {
1592+ delimiter: {
1593+ pattern: /^\{%|%\}$/,
1594+ alias: 'tag'
1595+ },
1596+ rest: Prism.languages.crystal
1597+ }
1598+ }
1599+ ]
1600+ });
14591601
14601602 }(Prism));
14611603
14621604 Prism.languages.d = Prism.languages.extend('clike', {
1463− 'comment': [
1464− {
1465− // Shebang
1466− pattern: /^\s*#!.+/,
1467− greedy: true
1468− },
1469− {
1470− pattern: RegExp(/(^|[^\\])/.source + '(?:' + [
1471− // /+ comment +/
1472− // Allow one level of nesting
1473− /\/\+(?:\/\+[\s\S]*?\+\/|(?!\/\+)[\s\S])*?\+\//.source,
1474− // // comment
1475− /\/\/.*/.source,
1476− // /* comment */
1477− /\/\*[\s\S]*?\*\//.source
1478− ].join('|') + ')'),
1479− lookbehind: true,
1480− greedy: true
1481− }
1482− ],
1483− 'string': [
1484− {
1485− pattern: RegExp([
1486− // r"", x""
1487− /\b[rx]"(?:\\[\s\S]|[^\\"])*"[cwd]?/.source,
1488−
1489− // q"[]", q"()", q"<>", q"{}"
1490− /\bq"(?:\[[\s\S]*?\]|\([\s\S]*?\)|<[\s\S]*?>|\{[\s\S]*?\})"/.source,
1491−
1492− // q"IDENT
1493− // ...
1494− // IDENT"
1495− /\bq"((?!\d)\w+)$[\s\S]*?^\1"/.source,
1496−
1497− // q"//", q"||", etc.
1498− /\bq"(.)[\s\S]*?\2"/.source,
1499−
1500− // Characters
1501− // 'a', '\\', '\n', '\xFF', '\377', '\uFFFF', '\U0010FFFF', '\quot'
1502− /'(?:\\(?:\W|\w+)|[^\\])'/.source,
1503−
1504− /(["`])(?:\\[\s\S]|(?!\3)[^\\])*\3[cwd]?/.source
1505− ].join('|'), 'm'),
1506− greedy: true
1507− },
1508− {
1509− pattern: /\bq\{(?:\{[^{}]*\}|[^{}])*\}/,
1510− greedy: true,
1511− alias: 'token-string'
1512− }
1513− ],
1514−
1515− 'number': [
1516− // The lookbehind and the negative look-ahead try to prevent bad highlighting of the .. operator
1517− // Hexadecimal numbers must be handled separately to avoid problems with exponent "e"
1518− /\b0x\.?[a-f\d_]+(?:(?!\.\.)\.[a-f\d_]*)?(?:p[+-]?[a-f\d_]+)?[ulfi]*/i,
1519− {
1520− pattern: /((?:\.\.)?)(?:\b0b\.?|\b|\.)\d[\d_]*(?:(?!\.\.)\.[\d_]*)?(?:e[+-]?\d[\d_]*)?[ulfi]*/i,
1521− lookbehind: true
1522− }
1523− ],
1524−
1525− // In order: $, keywords and special tokens, globally defined symbols
1526− 'keyword': /\$|\b(?:abstract|alias|align|asm|assert|auto|body|bool|break|byte|case|cast|catch|cdouble|cent|cfloat|char|class|const|continue|creal|dchar|debug|default|delegate|delete|deprecated|do|double|else|enum|export|extern|false|final|finally|float|for|foreach|foreach_reverse|function|goto|idouble|if|ifloat|immutable|import|inout|int|interface|invariant|ireal|lazy|long|macro|mixin|module|new|nothrow|null|out|override|package|pragma|private|protected|public|pure|real|ref|return|scope|shared|short|static|struct|super|switch|synchronized|template|this|throw|true|try|typedef|typeid|typeof|ubyte|ucent|uint|ulong|union|unittest|ushort|version|void|volatile|wchar|while|with|__(?:(?:FILE|MODULE|LINE|FUNCTION|PRETTY_FUNCTION|DATE|EOF|TIME|TIMESTAMP|VENDOR|VERSION)__|gshared|traits|vector|parameters)|string|wstring|dstring|size_t|ptrdiff_t)\b/,
1527− 'operator': /\|[|=]?|&[&=]?|\+[+=]?|-[-=]?|\.?\.\.|=[>=]?|!(?:i[ns]\b|<>?=?|>=?|=)?|\bi[ns]\b|(?:<[<>]?|>>?>?|\^\^|[*\/%^~])=?/
1605+ 'comment': [
1606+ {
1607+ // Shebang
1608+ pattern: /^\s*#!.+/,
1609+ greedy: true
1610+ },
1611+ {
1612+ pattern: RegExp(/(^|[^\\])/.source + '(?:' + [
1613+ // /+ comment +/
1614+ // Allow one level of nesting
1615+ /\/\+(?:\/\+(?:[^+]|\+(?!\/))*\+\/|(?!\/\+)[\s\S])*?\+\//.source,
1616+ // // comment
1617+ /\/\/.*/.source,
1618+ // /* comment */
1619+ /\/\*[\s\S]*?\*\//.source
1620+ ].join('|') + ')'),
1621+ lookbehind: true,
1622+ greedy: true
1623+ }
1624+ ],
1625+ 'string': [
1626+ {
1627+ pattern: RegExp([
1628+ // r"", x""
1629+ /\b[rx]"(?:\\[\s\S]|[^\\"])*"[cwd]?/.source,
1630+
1631+ // q"[]", q"()", q"<>", q"{}"
1632+ /\bq"(?:\[[\s\S]*?\]|\([\s\S]*?\)|<[\s\S]*?>|\{[\s\S]*?\})"/.source,
1633+
1634+ // q"IDENT
1635+ // ...
1636+ // IDENT"
1637+ /\bq"((?!\d)\w+)$[\s\S]*?^\1"/.source,
1638+
1639+ // q"//", q"||", etc.
1640+ /\bq"(.)[\s\S]*?\2"/.source,
1641+
1642+ // Characters
1643+ // 'a', '\\', '\n', '\xFF', '\377', '\uFFFF', '\U0010FFFF', '\quot'
1644+ /'(?:\\(?:\W|\w+)|[^\\])'/.source,
1645+
1646+ /(["`])(?:\\[\s\S]|(?!\3)[^\\])*\3[cwd]?/.source
1647+ ].join('|'), 'm'),
1648+ greedy: true
1649+ },
1650+ {
1651+ pattern: /\bq\{(?:\{[^{}]*\}|[^{}])*\}/,
1652+ greedy: true,
1653+ alias: 'token-string'
1654+ }
1655+ ],
1656+
1657+ 'number': [
1658+ // The lookbehind and the negative look-ahead try to prevent bad highlighting of the .. operator
1659+ // Hexadecimal numbers must be handled separately to avoid problems with exponent "e"
1660+ /\b0x\.?[a-f\d_]+(?:(?!\.\.)\.[a-f\d_]*)?(?:p[+-]?[a-f\d_]+)?[ulfi]*/i,
1661+ {
1662+ pattern: /((?:\.\.)?)(?:\b0b\.?|\b|\.)\d[\d_]*(?:(?!\.\.)\.[\d_]*)?(?:e[+-]?\d[\d_]*)?[ulfi]*/i,
1663+ lookbehind: true
1664+ }
1665+ ],
1666+
1667+ // In order: $, keywords and special tokens, globally defined symbols
1668+ 'keyword': /\$|\b(?:abstract|alias|align|asm|assert|auto|body|bool|break|byte|case|cast|catch|cdouble|cent|cfloat|char|class|const|continue|creal|dchar|debug|default|delegate|delete|deprecated|do|double|else|enum|export|extern|false|final|finally|float|for|foreach|foreach_reverse|function|goto|idouble|if|ifloat|immutable|import|inout|int|interface|invariant|ireal|lazy|long|macro|mixin|module|new|nothrow|null|out|override|package|pragma|private|protected|public|pure|real|ref|return|scope|shared|short|static|struct|super|switch|synchronized|template|this|throw|true|try|typedef|typeid|typeof|ubyte|ucent|uint|ulong|union|unittest|ushort|version|void|volatile|wchar|while|with|__(?:(?:FILE|MODULE|LINE|FUNCTION|PRETTY_FUNCTION|DATE|EOF|TIME|TIMESTAMP|VENDOR|VERSION)__|gshared|traits|vector|parameters)|string|wstring|dstring|size_t|ptrdiff_t)\b/,
1669+ 'operator': /\|[|=]?|&[&=]?|\+[+=]?|-[-=]?|\.?\.\.|=[>=]?|!(?:i[ns]\b|<>?=?|>=?|=)?|\bi[ns]\b|(?:<[<>]?|>>?>?|\^\^|[*\/%^~])=?/
15281670 });
15291671
15301672 Prism.languages.insertBefore('d', 'keyword', {
1531− 'property': /\B@\w*/
1673+ 'property': /\B@\w*/
15321674 });
15331675
15341676 Prism.languages.insertBefore('d', 'function', {
1535− 'register': {
1536− // Iasm registers
1537− pattern: /\b(?:[ABCD][LHX]|E[ABCD]X|E?(?:BP|SP|DI|SI)|[ECSDGF]S|CR[0234]|DR[012367]|TR[3-7]|X?MM[0-7]|R[ABCD]X|[BS]PL|R[BS]P|[DS]IL|R[DS]I|R(?:[89]|1[0-5])[BWD]?|XMM(?:[89]|1[0-5])|YMM(?:1[0-5]|\d))\b|\bST(?:\([0-7]\)|\b)/,
1538− alias: 'variable'
1539− }
1677+ 'register': {
1678+ // Iasm registers
1679+ pattern: /\b(?:[ABCD][LHX]|E[ABCD]X|E?(?:BP|SP|DI|SI)|[ECSDGF]S|CR[0234]|DR[012367]|TR[3-7]|X?MM[0-7]|R[ABCD]X|[BS]PL|R[BS]P|[DS]IL|R[DS]I|R(?:[89]|1[0-5])[BWD]?|XMM(?:[89]|1[0-5])|YMM(?:1[0-5]|\d))\b|\bST(?:\([0-7]\)|\b)/,
1680+ alias: 'variable'
1681+ }
15401682 });
15411683
15421684 Prism.languages.dart = Prism.languages.extend('clike', {
1543− 'string': [
1544− {
1545− pattern: /r?("""|''')[\s\S]*?\1/,
1546− greedy: true
1547− },
1548− {
1549− pattern: /r?("|')(?:\\.|(?!\1)[^\\\r\n])*\1/,
1550− greedy: true
1551− }
1552− ],
1553− 'keyword': [
1554− /\b(?:async|sync|yield)\*/,
1555− /\b(?:abstract|assert|async|await|break|case|catch|class|const|continue|default|deferred|do|dynamic|else|enum|export|external|extends|factory|final|finally|for|get|if|implements|import|in|library|new|null|operator|part|rethrow|return|set|static|super|switch|this|throw|try|typedef|var|void|while|with|yield)\b/
1556− ],
1557− 'operator': /\bis!|\b(?:as|is)\b|\+\+|--|&&|\|\||<<=?|>>=?|~(?:\/=?)?|[+\-*\/%&^|=!<>]=?|\?/
1685+ 'string': [
1686+ {
1687+ pattern: /r?("""|''')[\s\S]*?\1/,
1688+ greedy: true
1689+ },
1690+ {
1691+ pattern: /r?("|')(?:\\.|(?!\1)[^\\\r\n])*\1/,
1692+ greedy: true
1693+ }
1694+ ],
1695+ 'keyword': [
1696+ /\b(?:async|sync|yield)\*/,
1697+ /\b(?:abstract|assert|async|await|break|case|catch|class|const|continue|covariant|default|deferred|do|dynamic|else|enum|export|extension|external|extends|factory|final|finally|for|Function|get|hide|if|implements|interface|import|in|library|mixin|new|null|on|operator|part|rethrow|return|set|show|static|super|switch|sync|this|throw|try|typedef|var|void|while|with|yield)\b/
1698+ ],
1699+ 'operator': /\bis!|\b(?:as|is)\b|\+\+|--|&&|\|\||<<=?|>>=?|~(?:\/=?)?|[+\-*\/%&^|=!<>]=?|\?/
15581700 });
15591701
15601702 Prism.languages.insertBefore('dart','function',{
1561− 'metadata': {
1562− pattern: /@\w+/,
1563− alias: 'symbol'
1564− }
1703+ 'metadata': {
1704+ pattern: /@\w+/,
1705+ alias: 'symbol'
1706+ }
15651707 });
1708+
15661709 (function (Prism) {
15671710
1568− /**
1569− * Returns the placeholder for the given language id and index.
1570− *
1571− * @param {string} language
1572− * @param {string|number} index
1573− * @returns {string}
1574− */
1575− function getPlaceholder(language, index) {
1576− return '___' + language.toUpperCase() + index + '___';
1577− }
1578−
1579− Object.defineProperties(Prism.languages['markup-templating'] = {}, {
1580− buildPlaceholders: {
1581− /**
1582− * Tokenize all inline templating expressions matching `placeholderPattern`.
1583− *
1584− * If `replaceFilter` is provided, only matches of `placeholderPattern` for which `replaceFilter` returns
1585− * `true` will be replaced.
1586− *
1587− * @param {object} env The environment of the `before-tokenize` hook.
1588− * @param {string} language The language id.
1589− * @param {RegExp} placeholderPattern The matches of this pattern will be replaced by placeholders.
1590− * @param {(match: string) => boolean} [replaceFilter]
1591− */
1592− value: function (env, language, placeholderPattern, replaceFilter) {
1593− if (env.language !== language) {
1594− return;
1595− }
1596−
1597− var tokenStack = env.tokenStack = [];
1598−
1599− env.code = env.code.replace(placeholderPattern, function (match) {
1600− if (typeof replaceFilter === 'function' && !replaceFilter(match)) {
1601− return match;
1602− }
1603− var i = tokenStack.length;
1604− var placeholder;
1605−
1606− // Check for existing strings
1607− while (env.code.indexOf(placeholder = getPlaceholder(language, i)) !== -1)
1608− ++i;
1609−
1610− // Create a sparse array
1611− tokenStack[i] = match;
1612−
1613− return placeholder;
1614− });
1615−
1616− // Switch the grammar to markup
1617− env.grammar = Prism.languages.markup;
1618− }
1619− },
1620− tokenizePlaceholders: {
1621− /**
1622− * Replace placeholders with proper tokens after tokenizing.
1623− *
1624− * @param {object} env The environment of the `after-tokenize` hook.
1625− * @param {string} language The language id.
1626− */
1627− value: function (env, language) {
1628− if (env.language !== language || !env.tokenStack) {
1629− return;
1630− }
1631−
1632− // Switch the grammar back
1633− env.grammar = Prism.languages[language];
1634−
1635− var j = 0;
1636− var keys = Object.keys(env.tokenStack);
1637−
1638− function walkTokens(tokens) {
1639− for (var i = 0; i < tokens.length; i++) {
1640− // all placeholders are replaced already
1641− if (j >= keys.length) {
1642− break;
1643− }
1644−
1645− var token = tokens[i];
1646− if (typeof token === 'string' || (token.content && typeof token.content === 'string')) {
1647− var k = keys[j];
1648− var t = env.tokenStack[k];
1649− var s = typeof token === 'string' ? token : token.content;
1650− var placeholder = getPlaceholder(language, k);
1651−
1652− var index = s.indexOf(placeholder);
1653− if (index > -1) {
1654− ++j;
1655−
1656− var before = s.substring(0, index);
1657− var middle = new Prism.Token(language, Prism.tokenize(t, env.grammar), 'language-' + language, t);
1658− var after = s.substring(index + placeholder.length);
1659−
1660− var replacement = [];
1661− if (before) {
1662− replacement.push.apply(replacement, walkTokens([before]));
1663− }
1664− replacement.push(middle);
1665− if (after) {
1666− replacement.push.apply(replacement, walkTokens([after]));
1667− }
1668−
1669− if (typeof token === 'string') {
1670− tokens.splice.apply(tokens, [i, 1].concat(replacement));
1671− } else {
1672− token.content = replacement;
1673− }
1674− }
1675− } else if (token.content /* && typeof token.content !== 'string' */) {
1676− walkTokens(token.content);
1677− }
1678− }
1679−
1680− return tokens;
1681− }
1682−
1683− walkTokens(env.tokens);
1684− }
1685− }
1686− });
1711+ /**
1712+ * Returns the placeholder for the given language id and index.
1713+ *
1714+ * @param {string} language
1715+ * @param {string|number} index
1716+ * @returns {string}
1717+ */
1718+ function getPlaceholder(language, index) {
1719+ return '___' + language.toUpperCase() + index + '___';
1720+ }
1721+
1722+ Object.defineProperties(Prism.languages['markup-templating'] = {}, {
1723+ buildPlaceholders: {
1724+ /**
1725+ * Tokenize all inline templating expressions matching `placeholderPattern`.
1726+ *
1727+ * If `replaceFilter` is provided, only matches of `placeholderPattern` for which `replaceFilter` returns
1728+ * `true` will be replaced.
1729+ *
1730+ * @param {object} env The environment of the `before-tokenize` hook.
1731+ * @param {string} language The language id.
1732+ * @param {RegExp} placeholderPattern The matches of this pattern will be replaced by placeholders.
1733+ * @param {(match: string) => boolean} [replaceFilter]
1734+ */
1735+ value: function (env, language, placeholderPattern, replaceFilter) {
1736+ if (env.language !== language) {
1737+ return;
1738+ }
1739+
1740+ var tokenStack = env.tokenStack = [];
1741+
1742+ env.code = env.code.replace(placeholderPattern, function (match) {
1743+ if (typeof replaceFilter === 'function' && !replaceFilter(match)) {
1744+ return match;
1745+ }
1746+ var i = tokenStack.length;
1747+ var placeholder;
1748+
1749+ // Check for existing strings
1750+ while (env.code.indexOf(placeholder = getPlaceholder(language, i)) !== -1)
1751+ ++i;
1752+
1753+ // Create a sparse array
1754+ tokenStack[i] = match;
1755+
1756+ return placeholder;
1757+ });
1758+
1759+ // Switch the grammar to markup
1760+ env.grammar = Prism.languages.markup;
1761+ }
1762+ },
1763+ tokenizePlaceholders: {
1764+ /**
1765+ * Replace placeholders with proper tokens after tokenizing.
1766+ *
1767+ * @param {object} env The environment of the `after-tokenize` hook.
1768+ * @param {string} language The language id.
1769+ */
1770+ value: function (env, language) {
1771+ if (env.language !== language || !env.tokenStack) {
1772+ return;
1773+ }
1774+
1775+ // Switch the grammar back
1776+ env.grammar = Prism.languages[language];
1777+
1778+ var j = 0;
1779+ var keys = Object.keys(env.tokenStack);
1780+
1781+ function walkTokens(tokens) {
1782+ for (var i = 0; i < tokens.length; i++) {
1783+ // all placeholders are replaced already
1784+ if (j >= keys.length) {
1785+ break;
1786+ }
1787+
1788+ var token = tokens[i];
1789+ if (typeof token === 'string' || (token.content && typeof token.content === 'string')) {
1790+ var k = keys[j];
1791+ var t = env.tokenStack[k];
1792+ var s = typeof token === 'string' ? token : token.content;
1793+ var placeholder = getPlaceholder(language, k);
1794+
1795+ var index = s.indexOf(placeholder);
1796+ if (index > -1) {
1797+ ++j;
1798+
1799+ var before = s.substring(0, index);
1800+ var middle = new Prism.Token(language, Prism.tokenize(t, env.grammar), 'language-' + language, t);
1801+ var after = s.substring(index + placeholder.length);
1802+
1803+ var replacement = [];
1804+ if (before) {
1805+ replacement.push.apply(replacement, walkTokens([before]));
1806+ }
1807+ replacement.push(middle);
1808+ if (after) {
1809+ replacement.push.apply(replacement, walkTokens([after]));
1810+ }
1811+
1812+ if (typeof token === 'string') {
1813+ tokens.splice.apply(tokens, [i, 1].concat(replacement));
1814+ } else {
1815+ token.content = replacement;
1816+ }
1817+ }
1818+ } else if (token.content /* && typeof token.content !== 'string' */) {
1819+ walkTokens(token.content);
1820+ }
1821+ }
1822+
1823+ return tokens;
1824+ }
1825+
1826+ walkTokens(env.tokens);
1827+ }
1828+ }
1829+ });
16871830
16881831 }(Prism));
16891832
@@ -1692,709 +1835,773 @@ Prism.languages.insertBefore('dart','function',{ · 2 unmodified lines
16921835
16931836 (function (Prism) {
16941837
1695− Prism.languages.django = {
1696− 'comment': /^{#[\s\S]*?#}$/,
1697− 'tag': {
1698− pattern: /(^{%[+-]?\s*)\w+/,
1699− lookbehind: true,
1700− alias: 'keyword'
1701− },
1702− 'delimiter': {
1703− pattern: /^{[{%][+-]?|[+-]?[}%]}$/,
1704− alias: 'punctuation'
1705− },
1706− 'string': {
1707− pattern: /("|')(?:\\.|(?!\1)[^\\\r\n])*\1/,
1708− greedy: true
1709− },
1710− 'filter': {
1711− pattern: /(\|)\w+/,
1712− lookbehind: true,
1713− alias: 'function'
1714− },
1715− 'test': {
1716− pattern: /(\bis\s+(?:not\s+)?)(?!not\b)\w+/,
1717− lookbehind: true,
1718− alias: 'function'
1719− },
1720− 'function': /\b[a-z_]\w+(?=\s*\()/i,
1721− 'keyword': /\b(?:and|as|by|else|for|if|import|in|is|loop|not|or|recursive|with|without)\b/,
1722− 'operator': /[-+*/%=]=?|!=|\*\*?=?|\/\/?=?|<[<=>]?|>[=>]?|[&|^~]/,
1723− 'number': /\b\d+(?:\.\d+)?\b/,
1724− 'boolean': /[Tt]rue|[Ff]alse|[Nn]one/,
1725− 'variable': /\b\w+?\b/,
1726− 'punctuation': /[{}[\](),.:;]/
1727− };
1728−
1729−
1730− var pattern = /{{[\s\S]*?}}|{%[\s\S]*?%}|{#[\s\S]*?#}/g;
1731− var markupTemplating = Prism.languages['markup-templating'];
1732−
1733− Prism.hooks.add('before-tokenize', function (env) {
1734− markupTemplating.buildPlaceholders(env, 'django', pattern);
1735− });
1736− Prism.hooks.add('after-tokenize', function (env) {
1737− markupTemplating.tokenizePlaceholders(env, 'django');
1738− });
1739−
1740− // Add an Jinja2 alias
1741− Prism.languages.jinja2 = Prism.languages.django;
1742− Prism.hooks.add('before-tokenize', function (env) {
1743− markupTemplating.buildPlaceholders(env, 'jinja2', pattern);
1744− });
1745− Prism.hooks.add('after-tokenize', function (env) {
1746− markupTemplating.tokenizePlaceholders(env, 'jinja2');
1747− });
1838+ Prism.languages.django = {
1839+ 'comment': /^{#[\s\S]*?#}$/,
1840+ 'tag': {
1841+ pattern: /(^{%[+-]?\s*)\w+/,
1842+ lookbehind: true,
1843+ alias: 'keyword'
1844+ },
1845+ 'delimiter': {
1846+ pattern: /^{[{%][+-]?|[+-]?[}%]}$/,
1847+ alias: 'punctuation'
1848+ },
1849+ 'string': {
1850+ pattern: /("|')(?:\\.|(?!\1)[^\\\r\n])*\1/,
1851+ greedy: true
1852+ },
1853+ 'filter': {
1854+ pattern: /(\|)\w+/,
1855+ lookbehind: true,
1856+ alias: 'function'
1857+ },
1858+ 'test': {
1859+ pattern: /(\bis\s+(?:not\s+)?)(?!not\b)\w+/,
1860+ lookbehind: true,
1861+ alias: 'function'
1862+ },
1863+ 'function': /\b[a-z_]\w+(?=\s*\()/i,
1864+ 'keyword': /\b(?:and|as|by|else|for|if|import|in|is|loop|not|or|recursive|with|without)\b/,
1865+ 'operator': /[-+*/%=]=?|!=|\*\*?=?|\/\/?=?|<[<=>]?|>[=>]?|[&|^~]/,
1866+ 'number': /\b\d+(?:\.\d+)?\b/,
1867+ 'boolean': /[Tt]rue|[Ff]alse|[Nn]one/,
1868+ 'variable': /\b\w+?\b/,
1869+ 'punctuation': /[{}[\](),.:;]/
1870+ };
1871+
1872+
1873+ var pattern = /{{[\s\S]*?}}|{%[\s\S]*?%}|{#[\s\S]*?#}/g;
1874+ var markupTemplating = Prism.languages['markup-templating'];
1875+
1876+ Prism.hooks.add('before-tokenize', function (env) {
1877+ markupTemplating.buildPlaceholders(env, 'django', pattern);
1878+ });
1879+ Prism.hooks.add('after-tokenize', function (env) {
1880+ markupTemplating.tokenizePlaceholders(env, 'django');
1881+ });
1882+
1883+ // Add an Jinja2 alias
1884+ Prism.languages.jinja2 = Prism.languages.django;
1885+ Prism.hooks.add('before-tokenize', function (env) {
1886+ markupTemplating.buildPlaceholders(env, 'jinja2', pattern);
1887+ });
1888+ Prism.hooks.add('after-tokenize', function (env) {
1889+ markupTemplating.tokenizePlaceholders(env, 'jinja2');
1890+ });
17481891
17491892 })(Prism);
17501893
17511894 Prism.languages.elixir = {
1752− 'comment': /#.*/m,
1753− // ~r"""foo""" (multi-line), ~r'''foo''' (multi-line), ~r/foo/, ~r|foo|, ~r"foo", ~r'foo', ~r(foo), ~r[foo], ~r{foo}, ~r<foo>
1754− 'regex': {
1755− pattern: /~[rR](?:("""|''')(?:\\[\s\S]|(?!\1)[^\\])+\1|([\/|"'])(?:\\.|(?!\2)[^\\\r\n])+\2|\((?:\\.|[^\\)\r\n])+\)|\[(?:\\.|[^\\\]\r\n])+\]|\{(?:\\.|[^\\}\r\n])+\}|<(?:\\.|[^\\>\r\n])+>)[uismxfr]*/,
1756− greedy: true
1757− },
1758− 'string': [
1759− {
1760− // ~s"""foo""" (multi-line), ~s'''foo''' (multi-line), ~s/foo/, ~s|foo|, ~s"foo", ~s'foo', ~s(foo), ~s[foo], ~s{foo} (with interpolation care), ~s<foo>
1761− pattern: /~[cCsSwW](?:("""|''')(?:\\[\s\S]|(?!\1)[^\\])+\1|([\/|"'])(?:\\.|(?!\2)[^\\\r\n])+\2|\((?:\\.|[^\\)\r\n])+\)|\[(?:\\.|[^\\\]\r\n])+\]|\{(?:\\.|#\{[^}]+\}|[^\\}\r\n])+\}|<(?:\\.|[^\\>\r\n])+>)[csa]?/,
1762− greedy: true,
1763− inside: {
1764− // See interpolation below
1765− }
1766− },
1767− {
1768− pattern: /("""|''')[\s\S]*?\1/,
1769− greedy: true,
1770− inside: {
1771− // See interpolation below
1772− }
1773− },
1774− {
1775− // Multi-line strings are allowed
1776− pattern: /("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,
1777− greedy: true,
1778− inside: {
1779− // See interpolation below
1780− }
1781− }
1782− ],
1783− 'atom': {
1784− // Look-behind prevents bad highlighting of the :: operator
1785− pattern: /(^|[^:]):\w+/,
1786− lookbehind: true,
1787− alias: 'symbol'
1788− },
1789− // Look-ahead prevents bad highlighting of the :: operator
1790− 'attr-name': /\w+\??:(?!:)/,
1791− 'capture': {
1792− // Look-behind prevents bad highlighting of the && operator
1793− pattern: /(^|[^&])&(?:[^&\s\d()][^\s()]*|(?=\())/,
1794− lookbehind: true,
1795− alias: 'function'
1796− },
1797− 'argument': {
1798− // Look-behind prevents bad highlighting of the && operator
1799− pattern: /(^|[^&])&\d+/,
1800− lookbehind: true,
1801− alias: 'variable'
1802− },
1803− 'attribute': {
1804− pattern: /@\w+/,
1805− alias: 'variable'
1806− },
1807− 'number': /\b(?:0[box][a-f\d_]+|\d[\d_]*)(?:\.[\d_]+)?(?:e[+-]?[\d_]+)?\b/i,
1808− 'keyword': /\b(?:after|alias|and|case|catch|cond|def(?:callback|exception|impl|module|p|protocol|struct)?|do|else|end|fn|for|if|import|not|or|require|rescue|try|unless|use|when)\b/,
1809− 'boolean': /\b(?:true|false|nil)\b/,
1810− 'operator': [
1811− /\bin\b|&&?|\|[|>]?|\\\\|::|\.\.\.?|\+\+?|-[->]?|<[-=>]|>=|!==?|\B!|=(?:==?|[>~])?|[*\/^]/,
1812− {
1813− // We don't want to match <<
1814− pattern: /([^<])<(?!<)/,
1815− lookbehind: true
1816− },
1817− {
1818− // We don't want to match >>
1819− pattern: /([^>])>(?!>)/,
1820− lookbehind: true
1821− }
1822− ],
1823− 'punctuation': /<<|>>|[.,%\[\]{}()]/
1895+ 'comment': /#.*/m,
1896+ // ~r"""foo""" (multi-line), ~r'''foo''' (multi-line), ~r/foo/, ~r|foo|, ~r"foo", ~r'foo', ~r(foo), ~r[foo], ~r{foo}, ~r<foo>
1897+ 'regex': {
1898+ pattern: /~[rR](?:("""|''')(?:\\[\s\S]|(?!\1)[^\\])+\1|([\/|"'])(?:\\.|(?!\2)[^\\\r\n])+\2|\((?:\\.|[^\\)\r\n])+\)|\[(?:\\.|[^\\\]\r\n])+\]|\{(?:\\.|[^\\}\r\n])+\}|<(?:\\.|[^\\>\r\n])+>)[uismxfr]*/,
1899+ greedy: true
1900+ },
1901+ 'string': [
1902+ {
1903+ // ~s"""foo""" (multi-line), ~s'''foo''' (multi-line), ~s/foo/, ~s|foo|, ~s"foo", ~s'foo', ~s(foo), ~s[foo], ~s{foo} (with interpolation care), ~s<foo>
1904+ pattern: /~[cCsSwW](?:("""|''')(?:\\[\s\S]|(?!\1)[^\\])+\1|([\/|"'])(?:\\.|(?!\2)[^\\\r\n])+\2|\((?:\\.|[^\\)\r\n])+\)|\[(?:\\.|[^\\\]\r\n])+\]|\{(?:\\.|#\{[^}]+\}|#(?!\{)|[^#\\}\r\n])+\}|<(?:\\.|[^\\>\r\n])+>)[csa]?/,
1905+ greedy: true,
1906+ inside: {
1907+ // See interpolation below
1908+ }
1909+ },
1910+ {
1911+ pattern: /("""|''')[\s\S]*?\1/,
1912+ greedy: true,
1913+ inside: {
1914+ // See interpolation below
1915+ }
1916+ },
1917+ {
1918+ // Multi-line strings are allowed
1919+ pattern: /("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,
1920+ greedy: true,
1921+ inside: {
1922+ // See interpolation below
1923+ }
1924+ }
1925+ ],
1926+ 'atom': {
1927+ // Look-behind prevents bad highlighting of the :: operator
1928+ pattern: /(^|[^:]):\w+/,
1929+ lookbehind: true,
1930+ alias: 'symbol'
1931+ },
1932+ // Look-ahead prevents bad highlighting of the :: operator
1933+ 'attr-name': /\w+\??:(?!:)/,
1934+ 'capture': {
1935+ // Look-behind prevents bad highlighting of the && operator
1936+ pattern: /(^|[^&])&(?:[^&\s\d()][^\s()]*|(?=\())/,
1937+ lookbehind: true,
1938+ alias: 'function'
1939+ },
1940+ 'argument': {
1941+ // Look-behind prevents bad highlighting of the && operator
1942+ pattern: /(^|[^&])&\d+/,
1943+ lookbehind: true,
1944+ alias: 'variable'
1945+ },
1946+ 'attribute': {
1947+ pattern: /@\w+/,
1948+ alias: 'variable'
1949+ },
1950+ 'number': /\b(?:0[box][a-f\d_]+|\d[\d_]*)(?:\.[\d_]+)?(?:e[+-]?[\d_]+)?\b/i,
1951+ 'keyword': /\b(?:after|alias|and|case|catch|cond|def(?:callback|exception|impl|module|p|protocol|struct)?|do|else|end|fn|for|if|import|not|or|require|rescue|try|unless|use|when)\b/,
1952+ 'boolean': /\b(?:true|false|nil)\b/,
1953+ 'operator': [
1954+ /\bin\b|&&?|\|[|>]?|\\\\|::|\.\.\.?|\+\+?|-[->]?|<[-=>]|>=|!==?|\B!|=(?:==?|[>~])?|[*\/^]/,
1955+ {
1956+ // We don't want to match <<
1957+ pattern: /([^<])<(?!<)/,
1958+ lookbehind: true
1959+ },
1960+ {
1961+ // We don't want to match >>
1962+ pattern: /([^>])>(?!>)/,
1963+ lookbehind: true
1964+ }
1965+ ],
1966+ 'punctuation': /<<|>>|[.,%\[\]{}()]/
18241967 };
18251968
18261969 Prism.languages.elixir.string.forEach(function(o) {
1827− o.inside = {
1828− 'interpolation': {
1829− pattern: /#\{[^}]+\}/,
1830− inside: {
1831− 'delimiter': {
1832− pattern: /^#\{|\}$/,
1833− alias: 'punctuation'
1834− },
1835− rest: Prism.languages.elixir
1836− }
1837− }
1838− };
1970+ o.inside = {
1971+ 'interpolation': {
1972+ pattern: /#\{[^}]+\}/,
1973+ inside: {
1974+ 'delimiter': {
1975+ pattern: /^#\{|\}$/,
1976+ alias: 'punctuation'
1977+ },
1978+ rest: Prism.languages.elixir
1979+ }
1980+ }
1981+ };
18391982 });
18401983
18411984 Prism.languages.erlang = {
1842− 'comment': /%.+/,
1843− 'string': {
1844− pattern: /"(?:\\.|[^\\"\r\n])*"/,
1845− greedy: true
1846− },
1847− 'quoted-function': {
1848− pattern: /'(?:\\.|[^\\'\r\n])+'(?=\()/,
1849− alias: 'function'
1850− },
1851− 'quoted-atom': {
1852− pattern: /'(?:\\.|[^\\'\r\n])+'/,
1853− alias: 'atom'
1854− },
1855− 'boolean': /\b(?:true|false)\b/,
1856− 'keyword': /\b(?:fun|when|case|of|end|if|receive|after|try|catch)\b/,
1857− 'number': [
1858− /\$\\?./,
1859− /\d+#[a-z0-9]+/i,
1860− /(?:\b\d+\.?\d*|\B\.\d+)(?:e[+-]?\d+)?/i
1861− ],
1862− 'function': /\b[a-z][\w@]*(?=\()/,
1863− 'variable': {
1864− // Look-behind is used to prevent wrong highlighting of atoms containing "@"
1865− pattern: /(^|[^@])(?:\b|\?)[A-Z_][\w@]*/,
1866− lookbehind: true
1867− },
1868− 'operator': [
1869− /[=\/<>:]=|=[:\/]=|\+\+?|--?|[=*\/!]|\b(?:bnot|div|rem|band|bor|bxor|bsl|bsr|not|and|or|xor|orelse|andalso)\b/,
1870− {
1871− // We don't want to match <<
1872− pattern: /(^|[^<])<(?!<)/,
1873− lookbehind: true
1874− },
1875− {
1876− // We don't want to match >>
1877− pattern: /(^|[^>])>(?!>)/,
1878− lookbehind: true
1879− }
1880− ],
1881− 'atom': /\b[a-z][\w@]*/,
1882− 'punctuation': /[()[\]{}:;,.#|]|<<|>>/
1985+ 'comment': /%.+/,
1986+ 'string': {
1987+ pattern: /"(?:\\.|[^\\"\r\n])*"/,
1988+ greedy: true
1989+ },
1990+ 'quoted-function': {
1991+ pattern: /'(?:\\.|[^\\'\r\n])+'(?=\()/,
1992+ alias: 'function'
1993+ },
1994+ 'quoted-atom': {
1995+ pattern: /'(?:\\.|[^\\'\r\n])+'/,
1996+ alias: 'atom'
1997+ },
1998+ 'boolean': /\b(?:true|false)\b/,
1999+ 'keyword': /\b(?:fun|when|case|of|end|if|receive|after|try|catch)\b/,
2000+ 'number': [
2001+ /\$\\?./,
2002+ /\d+#[a-z0-9]+/i,
2003+ /(?:\b\d+\.?\d*|\B\.\d+)(?:e[+-]?\d+)?/i
2004+ ],
2005+ 'function': /\b[a-z][\w@]*(?=\()/,
2006+ 'variable': {
2007+ // Look-behind is used to prevent wrong highlighting of atoms containing "@"
2008+ pattern: /(^|[^@])(?:\b|\?)[A-Z_][\w@]*/,
2009+ lookbehind: true
2010+ },
2011+ 'operator': [
2012+ /[=\/<>:]=|=[:\/]=|\+\+?|--?|[=*\/!]|\b(?:bnot|div|rem|band|bor|bxor|bsl|bsr|not|and|or|xor|orelse|andalso)\b/,
2013+ {
2014+ // We don't want to match <<
2015+ pattern: /(^|[^<])<(?!<)/,
2016+ lookbehind: true
2017+ },
2018+ {
2019+ // We don't want to match >>
2020+ pattern: /(^|[^>])>(?!>)/,
2021+ lookbehind: true
2022+ }
2023+ ],
2024+ 'atom': /\b[a-z][\w@]*/,
2025+ 'punctuation': /[()[\]{}:;,.#|]|<<|>>/
18832026
18842027 };
18852028 Prism.languages.go = Prism.languages.extend('clike', {
1886− 'keyword': /\b(?:break|case|chan|const|continue|default|defer|else|fallthrough|for|func|go(?:to)?|if|import|interface|map|package|range|return|select|struct|switch|type|var)\b/,
1887− 'builtin': /\b(?:bool|byte|complex(?:64|128)|error|float(?:32|64)|rune|string|u?int(?:8|16|32|64)?|uintptr|append|cap|close|complex|copy|delete|imag|len|make|new|panic|print(?:ln)?|real|recover)\b/,
1888− 'boolean': /\b(?:_|iota|nil|true|false)\b/,
1889− 'operator': /[*\/%^!=]=?|\+[=+]?|-[=-]?|\|[=|]?|&(?:=|&|\^=?)?|>(?:>=?|=)?|<(?:<=?|=|-)?|:=|\.\.\./,
1890− 'number': /(?:\b0x[a-f\d]+|(?:\b\d+\.?\d*|\B\.\d+)(?:e[-+]?\d+)?)i?/i,
1891− 'string': {
1892− pattern: /(["'`])(?:\\[\s\S]|(?!\1)[^\\])*\1/,
1893− greedy: true
1894− }
2029+ 'keyword': /\b(?:break|case|chan|const|continue|default|defer|else|fallthrough|for|func|go(?:to)?|if|import|interface|map|package|range|return|select|struct|switch|type|var)\b/,
2030+ 'builtin': /\b(?:bool|byte|complex(?:64|128)|error|float(?:32|64)|rune|string|u?int(?:8|16|32|64)?|uintptr|append|cap|close|complex|copy|delete|imag|len|make|new|panic|print(?:ln)?|real|recover)\b/,
2031+ 'boolean': /\b(?:_|iota|nil|true|false)\b/,
2032+ 'operator': /[*\/%^!=]=?|\+[=+]?|-[=-]?|\|[=|]?|&(?:=|&|\^=?)?|>(?:>=?|=)?|<(?:<=?|=|-)?|:=|\.\.\./,
2033+ 'number': /(?:\b0x[a-f\d]+|(?:\b\d+\.?\d*|\B\.\d+)(?:e[-+]?\d+)?)i?/i,
2034+ 'string': {
2035+ pattern: /(["'`])(?:\\[\s\S]|(?!\1)[^\\])*\1/,
2036+ greedy: true
2037+ }
18952038 });
18962039 delete Prism.languages.go['class-name'];
18972040
18982041 Prism.languages.groovy = Prism.languages.extend('clike', {
1899− 'string': [
1900− {
1901− pattern: /("""|''')(?:[^\\]|\\[\s\S])*?\1|\$\/(?:\$\/\$|[\s\S])*?\/\$/,
1902− greedy: true
1903− },
1904− {
1905− // TODO: Slash strings (e.g. /foo/) can contain line breaks but this will cause a lot of trouble with
1906− // simple division (see JS regex), so find a fix maybe?
1907− pattern: /(["'/])(?:\\.|(?!\1)[^\\\r\n])*\1/,
1908− greedy: true
1909− }
1910− ],
1911− '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/,
1912− 'number': /\b(?:0b[01_]+|0x[\da-f_]+(?:\.[\da-f_p\-]+)?|[\d_]+(?:\.[\d_]+)?(?:e[+-]?[\d]+)?)[glidf]?\b/i,
1913− 'operator': {
1914− pattern: /(^|[^.])(?:~|==?~?|\?[.:]?|\*(?:[.=]|\*=?)?|\.[@&]|\.\.<|\.\.(?!\.)|-[-=>]?|\+[+=]?|!=?|<(?:<=?|=>?)?|>(?:>>?=?|=)?|&[&=]?|\|[|=]?|\/=?|\^=?|%=?)/,
1915− lookbehind: true
1916− },
1917− 'punctuation': /\.+|[{}[\];(),.:$]/
2042+ 'string': [
2043+ {
2044+ // https://groovy-lang.org/syntax.html#_dollar_slashy_string
2045+ pattern: /("""|''')(?:[^\\]|\\[\s\S])*?\1|\$\/(?:[^/$]|\$(?:[/$]|(?![/$]))|\/(?!\$))*\/\$/,
2046+ greedy: true
2047+ },
2048+ {
2049+ // TODO: Slash strings (e.g. /foo/) can contain line breaks but this will cause a lot of trouble with
2050+ // simple division (see JS regex), so find a fix maybe?
2051+ pattern: /(["'/])(?:\\.|(?!\1)[^\\\r\n])*\1/,
2052+ greedy: true
2053+ }
2054+ ],
2055+ '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/,
2056+ 'number': /\b(?:0b[01_]+|0x[\da-f_]+(?:\.[\da-f_p\-]+)?|[\d_]+(?:\.[\d_]+)?(?:e[+-]?[\d]+)?)[glidf]?\b/i,
2057+ 'operator': {
2058+ pattern: /(^|[^.])(?:~|==?~?|\?[.:]?|\*(?:[.=]|\*=?)?|\.[@&]|\.\.<|\.\.(?!\.)|-[-=>]?|\+[+=]?|!=?|<(?:<=?|=>?)?|>(?:>>?=?|=)?|&[&=]?|\|[|=]?|\/=?|\^=?|%=?)/,
2059+ lookbehind: true
2060+ },
2061+ 'punctuation': /\.+|[{}[\];(),.:$]/
19182062 });
19192063
19202064 Prism.languages.insertBefore('groovy', 'string', {
1921− 'shebang': {
1922− pattern: /#!.+/,
1923− alias: 'comment'
1924− }
2065+ 'shebang': {
2066+ pattern: /#!.+/,
2067+ alias: 'comment'
2068+ }
19252069 });
19262070
19272071 Prism.languages.insertBefore('groovy', 'punctuation', {
1928− 'spock-block': /\b(?:setup|given|when|then|and|cleanup|expect|where):/
2072+ 'spock-block': /\b(?:setup|given|when|then|and|cleanup|expect|where):/
19292073 });
19302074
19312075 Prism.languages.insertBefore('groovy', 'function', {
1932− 'annotation': {
1933− pattern: /(^|[^.])@\w+/,
1934− lookbehind: true,
1935− alias: 'punctuation'
1936− }
2076+ 'annotation': {
2077+ pattern: /(^|[^.])@\w+/,
2078+ lookbehind: true,
2079+ alias: 'punctuation'
2080+ }
19372081 });
19382082
19392083 // Handle string interpolation
19402084 Prism.hooks.add('wrap', function(env) {
1941− if (env.language === 'groovy' && env.type === 'string') {
1942− var delimiter = env.content[0];
1943−
1944− if (delimiter != "'") {
1945− var pattern = /([^\\])(?:\$(?:\{.*?\}|[\w.]+))/;
1946− if (delimiter === '$') {
1947− pattern = /([^\$])(?:\$(?:\{.*?\}|[\w.]+))/;
1948− }
1949−
1950− // To prevent double HTML-encoding we have to decode env.content first
1951− env.content = env.content.replace(/&lt;/g, '<').replace(/&amp;/g, '&');
1952−
1953− env.content = Prism.highlight(env.content, {
1954− 'expression': {
1955− pattern: pattern,
1956− lookbehind: true,
1957− inside: Prism.languages.groovy
1958− }
1959− });
1960−
1961− env.classes.push(delimiter === '/' ? 'regex' : 'gstring');
1962− }
1963− }
2085+ if (env.language === 'groovy' && env.type === 'string') {
2086+ var delimiter = env.content[0];
2087+
2088+ if (delimiter != "'") {
2089+ var pattern = /([^\\])(?:\$(?:\{.*?\}|[\w.]+))/;
2090+ if (delimiter === '$') {
2091+ pattern = /([^\$])(?:\$(?:\{.*?\}|[\w.]+))/;
2092+ }
2093+
2094+ // To prevent double HTML-encoding we have to decode env.content first
2095+ env.content = env.content.replace(/&lt;/g, '<').replace(/&amp;/g, '&');
2096+
2097+ env.content = Prism.highlight(env.content, {
2098+ 'expression': {
2099+ pattern: pattern,
2100+ lookbehind: true,
2101+ inside: Prism.languages.groovy
2102+ }
2103+ });
2104+
2105+ env.classes.push(delimiter === '/' ? 'regex' : 'gstring');
2106+ }
2107+ }
19642108 });
19652109
19662110 (function (Prism) {
19672111
1968− var keywords = /\b(?:abstract|assert|boolean|break|byte|case|catch|char|class|const|continue|default|do|double|else|enum|exports|extends|final|finally|float|for|goto|if|implements|import|instanceof|int|interface|long|module|native|new|null|open|opens|package|private|protected|provides|public|requires|return|short|static|strictfp|super|switch|synchronized|this|throw|throws|to|transient|transitive|try|uses|var|void|volatile|while|with|yield)\b/;
1969−
1970− // based on the java naming conventions
1971− var className = /\b[A-Z](?:\w*[a-z]\w*)?\b/;
1972−
1973− Prism.languages.java = Prism.languages.extend('clike', {
1974− 'class-name': [
1975− className,
1976−
1977− // variables and parameters
1978− // this to support class names (or generic parameters) which do not contain a lower case letter (also works for methods)
1979− /\b[A-Z]\w*(?=\s+\w+\s*[;,=())])/
1980− ],
1981− 'keyword': keywords,
1982− 'function': [
1983− Prism.languages.clike.function,
1984− {
1985− pattern: /(\:\:)[a-z_]\w*/,
1986− lookbehind: true
1987− }
1988− ],
1989− '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,
1990− 'operator': {
1991− pattern: /(^|[^.])(?:<<=?|>>>?=?|->|--|\+\+|&&|\|\||::|[?:~]|[-+*/%&|^!=<>]=?)/m,
1992− lookbehind: true
1993− }
1994− });
1995−
1996− Prism.languages.insertBefore('java', 'string', {
1997− 'triple-quoted-string': {
1998− // http://openjdk.java.net/jeps/355#Description
1999− pattern: /"""[ \t]*[\r\n](?:(?:"|"")?(?:\\.|[^"\\]))*"""/,
2000− greedy: true,
2001− alias: 'string'
2002− }
2003− });
2004−
2005− Prism.languages.insertBefore('java', 'class-name', {
2006− 'annotation': {
2007− alias: 'punctuation',
2008− pattern: /(^|[^.])@\w+/,
2009− lookbehind: true
2010− },
2011− 'namespace': {
2012− pattern: /(\b(?:exports|import(?:\s+static)?|module|open|opens|package|provides|requires|to|transitive|uses|with)\s+)[a-z]\w*(?:\.[a-z]\w*)+/,
2013− lookbehind: true,
2014− inside: {
2015− 'punctuation': /\./,
2016− }
2017− },
2018− 'generics': {
2019− pattern: /<(?:[\w\s,.&?]|<(?:[\w\s,.&?]|<(?:[\w\s,.&?]|<[\w\s,.&?]*>)*>)*>)*>/,
2020− inside: {
2021− 'class-name': className,
2022− 'keyword': keywords,
2023− 'punctuation': /[<>(),.:]/,
2024− 'operator': /[?&|]/
2025− }
2026− }
2027− });
2112+ var keywords = /\b(?:abstract|assert|boolean|break|byte|case|catch|char|class|const|continue|default|do|double|else|enum|exports|extends|final|finally|float|for|goto|if|implements|import|instanceof|int|interface|long|module|native|new|null|open|opens|package|private|protected|provides|public|record|requires|return|short|static|strictfp|super|switch|synchronized|this|throw|throws|to|transient|transitive|try|uses|var|void|volatile|while|with|yield)\b/;
2113+
2114+ // based on the java naming conventions
2115+ var className = /\b[A-Z](?:\w*[a-z]\w*)?\b/;
2116+
2117+ Prism.languages.java = Prism.languages.extend('clike', {
2118+ 'class-name': [
2119+ className,
2120+
2121+ // variables and parameters
2122+ // this to support class names (or generic parameters) which do not contain a lower case letter (also works for methods)
2123+ /\b[A-Z]\w*(?=\s+\w+\s*[;,=())])/
2124+ ],
2125+ 'keyword': keywords,
2126+ 'function': [
2127+ Prism.languages.clike.function,
2128+ {
2129+ pattern: /(\:\:)[a-z_]\w*/,
2130+ lookbehind: true
2131+ }
2132+ ],
2133+ '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,
2134+ 'operator': {
2135+ pattern: /(^|[^.])(?:<<=?|>>>?=?|->|--|\+\+|&&|\|\||::|[?:~]|[-+*/%&|^!=<>]=?)/m,
2136+ lookbehind: true
2137+ }
2138+ });
2139+
2140+ Prism.languages.insertBefore('java', 'string', {
2141+ 'triple-quoted-string': {
2142+ // http://openjdk.java.net/jeps/355#Description
2143+ pattern: /"""[ \t]*[\r\n](?:(?:"|"")?(?:\\.|[^"\\]))*"""/,
2144+ greedy: true,
2145+ alias: 'string'
2146+ }
2147+ });
2148+
2149+ Prism.languages.insertBefore('java', 'class-name', {
2150+ 'annotation': {
2151+ alias: 'punctuation',
2152+ pattern: /(^|[^.])@\w+/,
2153+ lookbehind: true
2154+ },
2155+ 'namespace': {
2156+ pattern: RegExp(
2157+ /(\b(?:exports|import(?:\s+static)?|module|open|opens|package|provides|requires|to|transitive|uses|with)\s+)(?!<keyword>)[a-z]\w*(?:\.[a-z]\w*)*\.?/
2158+ .source.replace(/<keyword>/g, function () { return keywords.source; })),
2159+ lookbehind: true,
2160+ inside: {
2161+ 'punctuation': /\./,
2162+ }
2163+ },
2164+ 'generics': {
2165+ pattern: /<(?:[\w\s,.&?]|<(?:[\w\s,.&?]|<(?:[\w\s,.&?]|<[\w\s,.&?]*>)*>)*>)*>/,
2166+ inside: {
2167+ 'class-name': className,
2168+ 'keyword': keywords,
2169+ 'punctuation': /[<>(),.:]/,
2170+ 'operator': /[?&|]/
2171+ }
2172+ }
2173+ });
20282174 }(Prism));
20292175
20302176 Prism.languages.json = {
2031− 'property': {
2032− pattern: /"(?:\\.|[^\\"\r\n])*"(?=\s*:)/,
2033− greedy: true
2034− },
2035− 'string': {
2036− pattern: /"(?:\\.|[^\\"\r\n])*"(?!\s*:)/,
2037− greedy: true
2038− },
2039− 'comment': /\/\/.*|\/\*[\s\S]*?(?:\*\/|$)/,
2040− 'number': /-?\d+\.?\d*(?:e[+-]?\d+)?/i,
2041− 'punctuation': /[{}[\],]/,
2042− 'operator': /:/,
2043− 'boolean': /\b(?:true|false)\b/,
2044− 'null': {
2045− pattern: /\bnull\b/,
2046− alias: 'keyword'
2047− }
2177+ 'property': {
2178+ pattern: /"(?:\\.|[^\\"\r\n])*"(?=\s*:)/,
2179+ greedy: true
2180+ },
2181+ 'string': {
2182+ pattern: /"(?:\\.|[^\\"\r\n])*"(?!\s*:)/,
2183+ greedy: true
2184+ },
2185+ 'comment': /\/\/.*|\/\*[\s\S]*?(?:\*\/|$)/,
2186+ 'number': /-?\d+\.?\d*(?:e[+-]?\d+)?/i,
2187+ 'punctuation': /[{}[\],]/,
2188+ 'operator': /:/,
2189+ 'boolean': /\b(?:true|false)\b/,
2190+ 'null': {
2191+ pattern: /\bnull\b/,
2192+ alias: 'keyword'
2193+ }
20482194 };
20492195
2050−Prism.languages.julia= {
2051− 'comment': {
2052− pattern: /(^|[^\\])#.*/,
2053− lookbehind: true
2054− },
2055− 'string': /("""|''')[\s\S]+?\1|("|')(?:\\.|(?!\2)[^\\\r\n])*\2/,
2056− 'keyword' : /\b(?:abstract|baremodule|begin|bitstype|break|catch|ccall|const|continue|do|else|elseif|end|export|finally|for|function|global|if|immutable|import|importall|in|let|local|macro|module|print|println|quote|return|struct|try|type|typealias|using|while)\b/,
2057− 'boolean' : /\b(?:true|false)\b/,
2058− 'number' : /(?:\b(?=\d)|\B(?=\.))(?:0[box])?(?:[\da-f]+\.?\d*|\.\d+)(?:[efp][+-]?\d+)?j?/i,
2059− 'operator': /[-+*^%÷&$\\]=?|\/[\/=]?|!=?=?|\|[=>]?|<(?:<=?|[=:])?|>(?:=|>>?=?)?|==?=?|[~≠≤≥]/,
2060− 'punctuation' : /[{}[\];(),.:]/,
2061− 'constant': /\b(?:(?:NaN|Inf)(?:16|32|64)?)\b/
2196+Prism.languages.webmanifest = Prism.languages.json;
2197+
2198+Prism.languages.julia = {
2199+ 'comment': {
2200+ // support one level of nested comments
2201+ // https://github.com/JuliaLang/julia/pull/6128
2202+ pattern: /(^|[^\\])(?:#=(?:[^#=]|=(?!#)|#(?!=)|#=(?:[^#=]|=(?!#)|#(?!=))*=#)*=#|#.*)/,
2203+ lookbehind: true
2204+ },
2205+ 'regex': {
2206+ // https://docs.julialang.org/en/v1/manual/strings/#Regular-Expressions-1
2207+ pattern: /r"(?:\\.|[^"\\\r\n])*"[imsx]{0,4}/,
2208+ greedy: true
2209+ },
2210+ 'string': {
2211+ // https://docs.julialang.org/en/v1/manual/strings/#man-characters-1
2212+ // https://docs.julialang.org/en/v1/manual/strings/#String-Basics-1
2213+ // https://docs.julialang.org/en/v1/manual/strings/#non-standard-string-literals-1
2214+ // https://docs.julialang.org/en/v1/manual/running-external-programs/#Running-External-Programs-1
2215+ pattern: /"""[\s\S]+?"""|\w*"(?:\\.|[^"\\\r\n])*"|(^|[^\w'])'(?:\\[^\r\n][^'\r\n]*|[^\\\r\n])'|`(?:[^\\`\r\n]|\\.)*`/,
2216+ lookbehind: true,
2217+ greedy: true
2218+ },
2219+ 'keyword': /\b(?:abstract|baremodule|begin|bitstype|break|catch|ccall|const|continue|do|else|elseif|end|export|finally|for|function|global|if|immutable|import|importall|in|let|local|macro|module|print|println|quote|return|struct|try|type|typealias|using|while)\b/,
2220+ 'boolean': /\b(?:true|false)\b/,
2221+ 'number': /(?:\b(?=\d)|\B(?=\.))(?:0[box])?(?:[\da-f]+(?:_[\da-f]+)*\.?(?:\d+(?:_\d+)*)?|\.\d+(?:_\d+)*)(?:[efp][+-]?\d+(?:_\d+)*)?j?/i,
2222+ // https://docs.julialang.org/en/v1/manual/mathematical-operations/
2223+ // https://docs.julialang.org/en/v1/manual/mathematical-operations/#Operator-Precedence-and-Associativity-1
2224+ 'operator': /&&|\|\||[-+*^%÷⊻&$\\]=?|\/[\/=]?|!=?=?|\|[=>]?|<(?:<=?|[=:|])?|>(?:=|>>?=?)?|==?=?|[~≠≤≥'√∛]/,
2225+ 'punctuation': /::?|[{}[\]();,.?]/,
2226+ // https://docs.julialang.org/en/v1/base/numbers/#Base.im
2227+ 'constant': /\b(?:(?:NaN|Inf)(?:16|32|64)?|im|pi|e|catalan|eulergamma|golden)\b|[πℯγφ]/
20622228 };
20632229
20642230 (function (Prism) {
2065− Prism.languages.kotlin = Prism.languages.extend('clike', {
2066− 'keyword': {
2067− // The lookbehind prevents wrong highlighting of e.g. kotlin.properties.get
2068− pattern: /(^|[^.])\b(?:abstract|actual|annotation|as|break|by|catch|class|companion|const|constructor|continue|crossinline|data|do|dynamic|else|enum|expect|external|final|finally|for|fun|get|if|import|in|infix|init|inline|inner|interface|internal|is|lateinit|noinline|null|object|open|operator|out|override|package|private|protected|public|reified|return|sealed|set|super|suspend|tailrec|this|throw|to|try|typealias|val|var|vararg|when|where|while)\b/,
2069− lookbehind: true
2070− },
2071− 'function': [
2072− /\w+(?=\s*\()/,
2073− {
2074− pattern: /(\.)\w+(?=\s*\{)/,
2075− lookbehind: true
2076− }
2077− ],
2078− 'number': /\b(?:0[xX][\da-fA-F]+(?:_[\da-fA-F]+)*|0[bB][01]+(?:_[01]+)*|\d+(?:_\d+)*(?:\.\d+(?:_\d+)*)?(?:[eE][+-]?\d+(?:_\d+)*)?[fFL]?)\b/,
2079− 'operator': /\+[+=]?|-[-=>]?|==?=?|!(?:!|==?)?|[\/*%<>]=?|[?:]:?|\.\.|&&|\|\||\b(?:and|inv|or|shl|shr|ushr|xor)\b/
2080− });
2081−
2082− delete Prism.languages.kotlin["class-name"];
2083−
2084− Prism.languages.insertBefore('kotlin', 'string', {
2085− 'raw-string': {
2086− pattern: /("""|''')[\s\S]*?\1/,
2087− alias: 'string'
2088− // See interpolation below
2089− }
2090− });
2091− Prism.languages.insertBefore('kotlin', 'keyword', {
2092− 'annotation': {
2093− pattern: /\B@(?:\w+:)?(?:[A-Z]\w*|\[[^\]]+\])/,
2094− alias: 'builtin'
2095− }
2096− });
2097− Prism.languages.insertBefore('kotlin', 'function', {
2098− 'label': {
2099− pattern: /\w+@|@\w+/,
2100− alias: 'symbol'
2101− }
2102− });
2103−
2104− var interpolation = [
2105− {
2106− pattern: /\$\{[^}]+\}/,
2107− inside: {
2108− 'delimiter': {
2109− pattern: /^\$\{|\}$/,
2110− alias: 'variable'
2111− },
2112− rest: Prism.languages.kotlin
2113− }
2114− },
2115− {
2116− pattern: /\$\w+/,
2117− alias: 'variable'
2118− }
2119− ];
2120−
2121− Prism.languages.kotlin['string'].inside = Prism.languages.kotlin['raw-string'].inside = {
2122− interpolation: interpolation
2123− };
2231+ Prism.languages.kotlin = Prism.languages.extend('clike', {
2232+ 'keyword': {
2233+ // The lookbehind prevents wrong highlighting of e.g. kotlin.properties.get
2234+ pattern: /(^|[^.])\b(?:abstract|actual|annotation|as|break|by|catch|class|companion|const|constructor|continue|crossinline|data|do|dynamic|else|enum|expect|external|final|finally|for|fun|get|if|import|in|infix|init|inline|inner|interface|internal|is|lateinit|noinline|null|object|open|operator|out|override|package|private|protected|public|reified|return|sealed|set|super|suspend|tailrec|this|throw|to|try|typealias|val|var|vararg|when|where|while)\b/,
2235+ lookbehind: true
2236+ },
2237+ 'function': [
2238+ /\w+(?=\s*\()/,
2239+ {
2240+ pattern: /(\.)\w+(?=\s*\{)/,
2241+ lookbehind: true
2242+ }
2243+ ],
2244+ 'number': /\b(?:0[xX][\da-fA-F]+(?:_[\da-fA-F]+)*|0[bB][01]+(?:_[01]+)*|\d+(?:_\d+)*(?:\.\d+(?:_\d+)*)?(?:[eE][+-]?\d+(?:_\d+)*)?[fFL]?)\b/,
2245+ 'operator': /\+[+=]?|-[-=>]?|==?=?|!(?:!|==?)?|[\/*%<>]=?|[?:]:?|\.\.|&&|\|\||\b(?:and|inv|or|shl|shr|ushr|xor)\b/
2246+ });
2247+
2248+ delete Prism.languages.kotlin["class-name"];
2249+
2250+ Prism.languages.insertBefore('kotlin', 'string', {
2251+ 'raw-string': {
2252+ pattern: /("""|''')[\s\S]*?\1/,
2253+ alias: 'string'
2254+ // See interpolation below
2255+ }
2256+ });
2257+ Prism.languages.insertBefore('kotlin', 'keyword', {
2258+ 'annotation': {
2259+ pattern: /\B@(?:\w+:)?(?:[A-Z]\w*|\[[^\]]+\])/,
2260+ alias: 'builtin'
2261+ }
2262+ });
2263+ Prism.languages.insertBefore('kotlin', 'function', {
2264+ 'label': {
2265+ pattern: /\w+@|@\w+/,
2266+ alias: 'symbol'
2267+ }
2268+ });
2269+
2270+ var interpolation = [
2271+ {
2272+ pattern: /\$\{[^}]+\}/,
2273+ inside: {
2274+ 'delimiter': {
2275+ pattern: /^\$\{|\}$/,
2276+ alias: 'variable'
2277+ },
2278+ rest: Prism.languages.kotlin
2279+ }
2280+ },
2281+ {
2282+ pattern: /\$\w+/,
2283+ alias: 'variable'
2284+ }
2285+ ];
2286+
2287+ Prism.languages.kotlin['string'].inside = Prism.languages.kotlin['raw-string'].inside = {
2288+ interpolation: interpolation
2289+ };
21242290
21252291 }(Prism));
21262292
21272293 Prism.languages.lua = {
2128− 'comment': /^#!.+|--(?:\[(=*)\[[\s\S]*?\]\1\]|.*)/m,
2129− // \z may be used to skip the following space
2130− 'string': {
2131− pattern: /(["'])(?:(?!\1)[^\\\r\n]|\\z(?:\r\n|\s)|\\(?:\r\n|[\s\S]))*\1|\[(=*)\[[\s\S]*?\]\2\]/,
2132− greedy: true
2133− },
2134− 'number': /\b0x[a-f\d]+\.?[a-f\d]*(?:p[+-]?\d+)?\b|\b\d+(?:\.\B|\.?\d*(?:e[+-]?\d+)?\b)|\B\.\d+(?:e[+-]?\d+)?\b/i,
2135− 'keyword': /\b(?:and|break|do|else|elseif|end|false|for|function|goto|if|in|local|nil|not|or|repeat|return|then|true|until|while)\b/,
2136− 'function': /(?!\d)\w+(?=\s*(?:[({]))/,
2137− 'operator': [
2138− /[-+*%^&|#]|\/\/?|<[<=]?|>[>=]?|[=~]=?/,
2139− {
2140− // Match ".." but don't break "..."
2141− pattern: /(^|[^.])\.\.(?!\.)/,
2142− lookbehind: true
2143− }
2144− ],
2145− 'punctuation': /[\[\](){},;]|\.+|:+/
2294+ 'comment': /^#!.+|--(?:\[(=*)\[[\s\S]*?\]\1\]|.*)/m,
2295+ // \z may be used to skip the following space
2296+ 'string': {
2297+ pattern: /(["'])(?:(?!\1)[^\\\r\n]|\\z(?:\r\n|\s)|\\(?:\r\n|[\s\S]))*\1|\[(=*)\[[\s\S]*?\]\2\]/,
2298+ greedy: true
2299+ },
2300+ 'number': /\b0x[a-f\d]+\.?[a-f\d]*(?:p[+-]?\d+)?\b|\b\d+(?:\.\B|\.?\d*(?:e[+-]?\d+)?\b)|\B\.\d+(?:e[+-]?\d+)?\b/i,
2301+ 'keyword': /\b(?:and|break|do|else|elseif|end|false|for|function|goto|if|in|local|nil|not|or|repeat|return|then|true|until|while)\b/,
2302+ 'function': /(?!\d)\w+(?=\s*(?:[({]))/,
2303+ 'operator': [
2304+ /[-+*%^&|#]|\/\/?|<[<=]?|>[>=]?|[=~]=?/,
2305+ {
2306+ // Match ".." but don't break "..."
2307+ pattern: /(^|[^.])\.\.(?!\.)/,
2308+ lookbehind: true
2309+ }
2310+ ],
2311+ 'punctuation': /[\[\](){},;]|\.+|:+/
21462312 };
21472313 Prism.languages.matlab = {
2148− 'comment': [
2149− /%\{[\s\S]*?\}%/,
2150− /%.+/
2151− ],
2152− 'string': {
2153− pattern: /\B'(?:''|[^'\r\n])*'/,
2154− greedy: true
2155− },
2156− // FIXME We could handle imaginary numbers as a whole
2157− 'number': /(?:\b\d+\.?\d*|\B\.\d+)(?:[eE][+-]?\d+)?(?:[ij])?|\b[ij]\b/,
2158− 'keyword': /\b(?:break|case|catch|continue|else|elseif|end|for|function|if|inf|NaN|otherwise|parfor|pause|pi|return|switch|try|while)\b/,
2159− 'function': /(?!\d)\w+(?=\s*\()/,
2160− 'operator': /\.?[*^\/\\']|[+\-:@]|[<>=~]=?|&&?|\|\|?/,
2161− 'punctuation': /\.{3}|[.,;\[\](){}!]/
2314+ 'comment': [
2315+ /%\{[\s\S]*?\}%/,
2316+ /%.+/
2317+ ],
2318+ 'string': {
2319+ pattern: /\B'(?:''|[^'\r\n])*'/,
2320+ greedy: true
2321+ },
2322+ // FIXME We could handle imaginary numbers as a whole
2323+ 'number': /(?:\b\d+\.?\d*|\B\.\d+)(?:[eE][+-]?\d+)?(?:[ij])?|\b[ij]\b/,
2324+ 'keyword': /\b(?:break|case|catch|continue|else|elseif|end|for|function|if|inf|NaN|otherwise|parfor|pause|pi|return|switch|try|while)\b/,
2325+ 'function': /(?!\d)\w+(?=\s*\()/,
2326+ 'operator': /\.?[*^\/\\']|[+\-:@]|[<>=~]=?|&&?|\|\|?/,
2327+ 'punctuation': /\.{3}|[.,;\[\](){}!]/
21622328 };
21632329 Prism.languages.nginx = Prism.languages.extend('clike', {
2164− 'comment': {
2165− pattern: /(^|[^"{\\])#.*/,
2166− lookbehind: true
2167− },
2168− '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_size|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_transparency|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|perl_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|proxy_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
2330+ 'comment': {
2331+ pattern: /(^|[^"{\\])#.*/,
2332+ lookbehind: true
2333+ },
2334+ '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_size|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_transparency|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|perl_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|proxy_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
21692335 });
21702336
21712337 Prism.languages.insertBefore('nginx', 'keyword', {
2172− 'variable': /\$[a-z_]+/i
2338+ 'variable': /\$[a-z_]+/i
21732339 });
21742340
21752341 Prism.languages.nim = {
2176− 'comment': /#.*/,
2177− // Double-quoted strings can be prefixed by an identifier (Generalized raw string literals)
2178− // Character literals are handled specifically to prevent issues with numeric type suffixes
2179− 'string': {
2180− pattern: /(?:(?:\b(?!\d)(?:\w|\\x[8-9a-fA-F][0-9a-fA-F])+)?(?:"""[\s\S]*?"""(?!")|"(?:\\[\s\S]|""|[^"\\])*")|'(?:\\(?:\d+|x[\da-fA-F]{2}|.)|[^'])')/,
2181− greedy: true
2182− },
2183− // The negative look ahead prevents wrong highlighting of the .. operator
2184− 'number': /\b(?:0[xXoObB][\da-fA-F_]+|\d[\d_]*(?:(?!\.\.)\.[\d_]*)?(?:[eE][+-]?\d[\d_]*)?)(?:'?[iuf]\d*)?/,
2185− 'keyword': /\b(?:addr|as|asm|atomic|bind|block|break|case|cast|concept|const|continue|converter|defer|discard|distinct|do|elif|else|end|enum|except|export|finally|for|from|func|generic|if|import|include|interface|iterator|let|macro|method|mixin|nil|object|out|proc|ptr|raise|ref|return|static|template|try|tuple|type|using|var|when|while|with|without|yield)\b/,
2186− 'function': {
2187− pattern: /(?:(?!\d)(?:\w|\\x[8-9a-fA-F][0-9a-fA-F])+|`[^`\r\n]+`)\*?(?:\[[^\]]+\])?(?=\s*\()/,
2188− inside: {
2189− 'operator': /\*$/
2190− }
2191− },
2192− // We don't want to highlight operators inside backticks
2193− 'ignore': {
2194− pattern: /`[^`\r\n]+`/,
2195− inside: {
2196− 'punctuation': /`/
2197− }
2198− },
2199− 'operator': {
2200− // Look behind and look ahead prevent wrong highlighting of punctuations [. .] {. .} (. .)
2201− // but allow the slice operator .. to take precedence over them
2202− // One can define his own operators in Nim so all combination of operators might be an operator.
2203− pattern: /(^|[({\[](?=\.\.)|(?![({\[]\.).)(?:(?:[=+\-*\/<>@$~&%|!?^:\\]|\.\.|\.(?![)}\]]))+|\b(?:and|div|of|or|in|is|isnot|mod|not|notin|shl|shr|xor)\b)/m,
2204− lookbehind: true
2205− },
2206− 'punctuation': /[({\[]\.|\.[)}\]]|[`(){}\[\],:]/
2342+ 'comment': /#.*/,
2343+ // Double-quoted strings can be prefixed by an identifier (Generalized raw string literals)
2344+ // Character literals are handled specifically to prevent issues with numeric type suffixes
2345+ 'string': {
2346+ pattern: /(?:(?:\b(?!\d)(?:\w|\\x[8-9a-fA-F][0-9a-fA-F])+)?(?:"""[\s\S]*?"""(?!")|"(?:\\[\s\S]|""|[^"\\])*")|'(?:\\(?:\d+|x[\da-fA-F]{2}|.)|[^'])')/,
2347+ greedy: true
2348+ },
2349+ // The negative look ahead prevents wrong highlighting of the .. operator
2350+ 'number': /\b(?:0[xXoObB][\da-fA-F_]+|\d[\d_]*(?:(?!\.\.)\.[\d_]*)?(?:[eE][+-]?\d[\d_]*)?)(?:'?[iuf]\d*)?/,
2351+ 'keyword': /\b(?:addr|as|asm|atomic|bind|block|break|case|cast|concept|const|continue|converter|defer|discard|distinct|do|elif|else|end|enum|except|export|finally|for|from|func|generic|if|import|include|interface|iterator|let|macro|method|mixin|nil|object|out|proc|ptr|raise|ref|return|static|template|try|tuple|type|using|var|when|while|with|without|yield)\b/,
2352+ 'function': {
2353+ pattern: /(?:(?!\d)(?:\w|\\x[8-9a-fA-F][0-9a-fA-F])+|`[^`\r\n]+`)\*?(?:\[[^\]]+\])?(?=\s*\()/,
2354+ inside: {
2355+ 'operator': /\*$/
2356+ }
2357+ },
2358+ // We don't want to highlight operators inside backticks
2359+ 'ignore': {
2360+ pattern: /`[^`\r\n]+`/,
2361+ inside: {
2362+ 'punctuation': /`/
2363+ }
2364+ },
2365+ 'operator': {
2366+ // Look behind and look ahead prevent wrong highlighting of punctuations [. .] {. .} (. .)
2367+ // but allow the slice operator .. to take precedence over them
2368+ // One can define his own operators in Nim so all combination of operators might be an operator.
2369+ pattern: /(^|[({\[](?=\.\.)|(?![({\[]\.).)(?:(?:[=+\-*\/<>@$~&%|!?^:\\]|\.\.|\.(?![)}\]]))+|\b(?:and|div|of|or|in|is|isnot|mod|not|notin|shl|shr|xor)\b)/m,
2370+ lookbehind: true
2371+ },
2372+ 'punctuation': /[({\[]\.|\.[)}\]]|[`(){}\[\],:]/
2373+};
2374+Prism.languages.ocaml = {
2375+ 'comment': /\(\*[\s\S]*?\*\)/,
2376+ 'string': [
2377+ {
2378+ pattern: /"(?:\\.|[^\\\r\n"])*"/,
2379+ greedy: true
2380+ },
2381+ {
2382+ pattern: /(['`])(?:\\(?:\d+|x[\da-f]+|.)|(?!\1)[^\\\r\n])\1/i,
2383+ greedy: true
2384+ }
2385+ ],
2386+ 'number': /\b(?:0x[\da-f][\da-f_]+|(?:0[bo])?\d[\d_]*\.?[\d_]*(?:e[+-]?[\d_]+)?)/i,
2387+ 'directive': {
2388+ pattern: /\B#\w+/,
2389+ alias: 'important'
2390+ },
2391+ 'label': {
2392+ pattern: /\B~\w+/,
2393+ alias: 'function'
2394+ },
2395+ 'type_variable': {
2396+ pattern: /\B'\w+/,
2397+ alias: 'function'
2398+ },
2399+ 'variant': {
2400+ pattern: /`\w+/,
2401+ alias: 'variable'
2402+ },
2403+ 'module': {
2404+ pattern: /\b[A-Z]\w+/,
2405+ alias: 'variable'
2406+ },
2407+ // For the list of keywords and operators,
2408+ // see: http://caml.inria.fr/pub/docs/manual-ocaml/lex.html#sec84
2409+ 'keyword': /\b(?:as|assert|begin|class|constraint|do|done|downto|else|end|exception|external|for|fun|function|functor|if|in|include|inherit|initializer|lazy|let|match|method|module|mutable|new|nonrec|object|of|open|private|rec|sig|struct|then|to|try|type|val|value|virtual|when|where|while|with)\b/,
2410+ 'boolean': /\b(?:false|true)\b/,
2411+ // Custom operators are allowed
2412+ 'operator': /:=|[=<>@^|&+\-*\/$%!?~][!$%&*+\-.\/:<=>?@^|~]*|\b(?:and|asr|land|lor|lsl|lsr|lxor|mod|or)\b/,
2413+ 'punctuation': /[(){}\[\]|_.,:;]/
22072414 };
22082415 Prism.languages.perl = {
2209− 'comment': [
2210− {
2211− // POD
2212− pattern: /(^\s*)=\w+[\s\S]*?=cut.*/m,
2213− lookbehind: true
2214− },
2215− {
2216− pattern: /(^|[^\\$])#.*/,
2217− lookbehind: true
2218− }
2219− ],
2220− // TODO Could be nice to handle Heredoc too.
2221− 'string': [
2222− // q/.../
2223− {
2224− pattern: /\b(?:q|qq|qx|qw)\s*([^a-zA-Z0-9\s{(\[<])(?:(?!\1)[^\\]|\\[\s\S])*\1/,
2225− greedy: true
2226− },
2227−
2228− // q a...a
2229− {
2230− pattern: /\b(?:q|qq|qx|qw)\s+([a-zA-Z0-9])(?:(?!\1)[^\\]|\\[\s\S])*\1/,
2231− greedy: true
2232− },
2233−
2234− // q(...)
2235− {
2236− pattern: /\b(?:q|qq|qx|qw)\s*\((?:[^()\\]|\\[\s\S])*\)/,
2237− greedy: true
2238− },
2239−
2240− // q{...}
2241− {
2242− pattern: /\b(?:q|qq|qx|qw)\s*\{(?:[^{}\\]|\\[\s\S])*\}/,
2243− greedy: true
2244− },
2245−
2246− // q[...]
2247− {
2248− pattern: /\b(?:q|qq|qx|qw)\s*\[(?:[^[\]\\]|\\[\s\S])*\]/,
2249− greedy: true
2250− },
2251−
2252− // q<...>
2253− {
2254− pattern: /\b(?:q|qq|qx|qw)\s*<(?:[^<>\\]|\\[\s\S])*>/,
2255− greedy: true
2256− },
2257−
2258− // "...", `...`
2259− {
2260− pattern: /("|`)(?:(?!\1)[^\\]|\\[\s\S])*\1/,
2261− greedy: true
2262− },
2263−
2264− // '...'
2265− // FIXME Multi-line single-quoted strings are not supported as they would break variables containing '
2266− {
2267− pattern: /'(?:[^'\\\r\n]|\\.)*'/,
2268− greedy: true
2269− }
2270− ],
2271− 'regex': [
2272− // m/.../
2273− {
2274− pattern: /\b(?:m|qr)\s*([^a-zA-Z0-9\s{(\[<])(?:(?!\1)[^\\]|\\[\s\S])*\1[msixpodualngc]*/,
2275− greedy: true
2276− },
2277−
2278− // m a...a
2279− {
2280− pattern: /\b(?:m|qr)\s+([a-zA-Z0-9])(?:(?!\1)[^\\]|\\[\s\S])*\1[msixpodualngc]*/,
2281− greedy: true
2282− },
2283−
2284− // m(...)
2285− {
2286− pattern: /\b(?:m|qr)\s*\((?:[^()\\]|\\[\s\S])*\)[msixpodualngc]*/,
2287− greedy: true
2288− },
2289−
2290− // m{...}
2291− {
2292− pattern: /\b(?:m|qr)\s*\{(?:[^{}\\]|\\[\s\S])*\}[msixpodualngc]*/,
2293− greedy: true
2294− },
2295−
2296− // m[...]
2297− {
2298− pattern: /\b(?:m|qr)\s*\[(?:[^[\]\\]|\\[\s\S])*\][msixpodualngc]*/,
2299− greedy: true
2300− },
2301−
2302− // m<...>
2303− {
2304− pattern: /\b(?:m|qr)\s*<(?:[^<>\\]|\\[\s\S])*>[msixpodualngc]*/,
2305− greedy: true
2306− },
2307−
2308− // The lookbehinds prevent -s from breaking
2309− // FIXME We don't handle change of separator like s(...)[...]
2310− // s/.../.../
2311− {
2312− pattern: /(^|[^-]\b)(?:s|tr|y)\s*([^a-zA-Z0-9\s{(\[<])(?:(?!\2)[^\\]|\\[\s\S])*\2(?:(?!\2)[^\\]|\\[\s\S])*\2[msixpodualngcer]*/,
2313− lookbehind: true,
2314− greedy: true
2315− },
2316−
2317− // s a...a...a
2318− {
2319− pattern: /(^|[^-]\b)(?:s|tr|y)\s+([a-zA-Z0-9])(?:(?!\2)[^\\]|\\[\s\S])*\2(?:(?!\2)[^\\]|\\[\s\S])*\2[msixpodualngcer]*/,
2320− lookbehind: true,
2321− greedy: true
2322− },
2323−
2324− // s(...)(...)
2325− {
2326− pattern: /(^|[^-]\b)(?:s|tr|y)\s*\((?:[^()\\]|\\[\s\S])*\)\s*\((?:[^()\\]|\\[\s\S])*\)[msixpodualngcer]*/,
2327− lookbehind: true,
2328− greedy: true
2329− },
2330−
2331− // s{...}{...}
2332− {
2333− pattern: /(^|[^-]\b)(?:s|tr|y)\s*\{(?:[^{}\\]|\\[\s\S])*\}\s*\{(?:[^{}\\]|\\[\s\S])*\}[msixpodualngcer]*/,
2334− lookbehind: true,
2335− greedy: true
2336− },
2337−
2338− // s[...][...]
2339− {
2340− pattern: /(^|[^-]\b)(?:s|tr|y)\s*\[(?:[^[\]\\]|\\[\s\S])*\]\s*\[(?:[^[\]\\]|\\[\s\S])*\][msixpodualngcer]*/,
2341− lookbehind: true,
2342− greedy: true
2343− },
2344−
2345− // s<...><...>
2346− {
2347− pattern: /(^|[^-]\b)(?:s|tr|y)\s*<(?:[^<>\\]|\\[\s\S])*>\s*<(?:[^<>\\]|\\[\s\S])*>[msixpodualngcer]*/,
2348− lookbehind: true,
2349− greedy: true
2350− },
2351−
2352− // /.../
2353− // The look-ahead tries to prevent two divisions on
2354− // the same line from being highlighted as regex.
2355− // This does not support multi-line regex.
2356− {
2357− pattern: /\/(?:[^\/\\\r\n]|\\.)*\/[msixpodualngc]*(?=\s*(?:$|[\r\n,.;})&|\-+*~<>!?^]|(?:lt|gt|le|ge|eq|ne|cmp|not|and|or|xor|x)\b))/,
2358− greedy: true
2359− }
2360− ],
2361−
2362− // FIXME Not sure about the handling of ::, ', and #
2363− 'variable': [
2364− // ${^POSTMATCH}
2365− /[&*$@%]\{\^[A-Z]+\}/,
2366− // $^V
2367− /[&*$@%]\^[A-Z_]/,
2368− // ${...}
2369− /[&*$@%]#?(?=\{)/,
2370− // $foo
2371− /[&*$@%]#?(?:(?:::)*'?(?!\d)[\w$]+)+(?:::)*/i,
2372− // $1
2373− /[&*$@%]\d+/,
2374− // $_, @_, %!
2375− // The negative lookahead prevents from breaking the %= operator
2376− /(?!%=)[$@%][!"#$%&'()*+,\-.\/:;<=>?@[\\\]^_`{|}~]/
2377− ],
2378− 'filehandle': {
2379− // <>, <FOO>, _
2380− pattern: /<(?![<=])\S*>|\b_\b/,
2381− alias: 'symbol'
2382− },
2383− 'vstring': {
2384− // v1.2, 1.2.3
2385− pattern: /v\d+(?:\.\d+)*|\d+(?:\.\d+){2,}/,
2386− alias: 'string'
2387− },
2388− 'function': {
2389− pattern: /sub [a-z0-9_]+/i,
2390− inside: {
2391− keyword: /sub/
2392− }
2393− },
2394− 'keyword': /\b(?:any|break|continue|default|delete|die|do|else|elsif|eval|for|foreach|given|goto|if|last|local|my|next|our|package|print|redo|require|return|say|state|sub|switch|undef|unless|until|use|when|while)\b/,
2395− 'number': /\b(?:0x[\dA-Fa-f](?:_?[\dA-Fa-f])*|0b[01](?:_?[01])*|(?:\d(?:_?\d)*)?\.?\d(?:_?\d)*(?:[Ee][+-]?\d+)?)\b/,
2396− 'operator': /-[rwxoRWXOezsfdlpSbctugkTBMAC]\b|\+[+=]?|-[-=>]?|\*\*?=?|\/\/?=?|=[=~>]?|~[~=]?|\|\|?=?|&&?=?|<(?:=>?|<=?)?|>>?=?|![~=]?|[%^]=?|\.(?:=|\.\.?)?|[\\?]|\bx(?:=|\b)|\b(?:lt|gt|le|ge|eq|ne|cmp|not|and|or|xor)\b/,
2397− 'punctuation': /[{}[\];(),:]/
2416+ 'comment': [
2417+ {
2418+ // POD
2419+ pattern: /(^\s*)=\w+[\s\S]*?=cut.*/m,
2420+ lookbehind: true
2421+ },
2422+ {
2423+ pattern: /(^|[^\\$])#.*/,
2424+ lookbehind: true
2425+ }
2426+ ],
2427+ // TODO Could be nice to handle Heredoc too.
2428+ 'string': [
2429+ // q/.../
2430+ {
2431+ pattern: /\b(?:q|qq|qx|qw)\s*([^a-zA-Z0-9\s{(\[<])(?:(?!\1)[^\\]|\\[\s\S])*\1/,
2432+ greedy: true
2433+ },
2434+
2435+ // q a...a
2436+ {
2437+ pattern: /\b(?:q|qq|qx|qw)\s+([a-zA-Z0-9])(?:(?!\1)[^\\]|\\[\s\S])*\1/,
2438+ greedy: true
2439+ },
2440+
2441+ // q(...)
2442+ {
2443+ pattern: /\b(?:q|qq|qx|qw)\s*\((?:[^()\\]|\\[\s\S])*\)/,
2444+ greedy: true
2445+ },
2446+
2447+ // q{...}
2448+ {
2449+ pattern: /\b(?:q|qq|qx|qw)\s*\{(?:[^{}\\]|\\[\s\S])*\}/,
2450+ greedy: true
2451+ },
2452+
2453+ // q[...]
2454+ {
2455+ pattern: /\b(?:q|qq|qx|qw)\s*\[(?:[^[\]\\]|\\[\s\S])*\]/,
2456+ greedy: true
2457+ },
2458+
2459+ // q<...>
2460+ {
2461+ pattern: /\b(?:q|qq|qx|qw)\s*<(?:[^<>\\]|\\[\s\S])*>/,
2462+ greedy: true
2463+ },
2464+
2465+ // "...", `...`
2466+ {
2467+ pattern: /("|`)(?:(?!\1)[^\\]|\\[\s\S])*\1/,
2468+ greedy: true
2469+ },
2470+
2471+ // '...'
2472+ // FIXME Multi-line single-quoted strings are not supported as they would break variables containing '
2473+ {
2474+ pattern: /'(?:[^'\\\r\n]|\\.)*'/,
2475+ greedy: true
2476+ }
2477+ ],
2478+ 'regex': [
2479+ // m/.../
2480+ {
2481+ pattern: /\b(?:m|qr)\s*([^a-zA-Z0-9\s{(\[<])(?:(?!\1)[^\\]|\\[\s\S])*\1[msixpodualngc]*/,
2482+ greedy: true
2483+ },
2484+
2485+ // m a...a
2486+ {
2487+ pattern: /\b(?:m|qr)\s+([a-zA-Z0-9])(?:(?!\1)[^\\]|\\[\s\S])*\1[msixpodualngc]*/,
2488+ greedy: true
2489+ },
2490+
2491+ // m(...)
2492+ {
2493+ pattern: /\b(?:m|qr)\s*\((?:[^()\\]|\\[\s\S])*\)[msixpodualngc]*/,
2494+ greedy: true
2495+ },
2496+
2497+ // m{...}
2498+ {
2499+ pattern: /\b(?:m|qr)\s*\{(?:[^{}\\]|\\[\s\S])*\}[msixpodualngc]*/,
2500+ greedy: true
2501+ },
2502+
2503+ // m[...]
2504+ {
2505+ pattern: /\b(?:m|qr)\s*\[(?:[^[\]\\]|\\[\s\S])*\][msixpodualngc]*/,
2506+ greedy: true
2507+ },
2508+
2509+ // m<...>
2510+ {
2511+ pattern: /\b(?:m|qr)\s*<(?:[^<>\\]|\\[\s\S])*>[msixpodualngc]*/,
2512+ greedy: true
2513+ },
2514+
2515+ // The lookbehinds prevent -s from breaking
2516+ // FIXME We don't handle change of separator like s(...)[...]
2517+ // s/.../.../
2518+ {
2519+ pattern: /(^|[^-]\b)(?:s|tr|y)\s*([^a-zA-Z0-9\s{(\[<])(?:(?!\2)[^\\]|\\[\s\S])*\2(?:(?!\2)[^\\]|\\[\s\S])*\2[msixpodualngcer]*/,
2520+ lookbehind: true,
2521+ greedy: true
2522+ },
2523+
2524+ // s a...a...a
2525+ {
2526+ pattern: /(^|[^-]\b)(?:s|tr|y)\s+([a-zA-Z0-9])(?:(?!\2)[^\\]|\\[\s\S])*\2(?:(?!\2)[^\\]|\\[\s\S])*\2[msixpodualngcer]*/,
2527+ lookbehind: true,
2528+ greedy: true
2529+ },
2530+
2531+ // s(...)(...)
2532+ {
2533+ pattern: /(^|[^-]\b)(?:s|tr|y)\s*\((?:[^()\\]|\\[\s\S])*\)\s*\((?:[^()\\]|\\[\s\S])*\)[msixpodualngcer]*/,
2534+ lookbehind: true,
2535+ greedy: true
2536+ },
2537+
2538+ // s{...}{...}
2539+ {
2540+ pattern: /(^|[^-]\b)(?:s|tr|y)\s*\{(?:[^{}\\]|\\[\s\S])*\}\s*\{(?:[^{}\\]|\\[\s\S])*\}[msixpodualngcer]*/,
2541+ lookbehind: true,
2542+ greedy: true
2543+ },
2544+
2545+ // s[...][...]
2546+ {
2547+ pattern: /(^|[^-]\b)(?:s|tr|y)\s*\[(?:[^[\]\\]|\\[\s\S])*\]\s*\[(?:[^[\]\\]|\\[\s\S])*\][msixpodualngcer]*/,
2548+ lookbehind: true,
2549+ greedy: true
2550+ },
2551+
2552+ // s<...><...>
2553+ {
2554+ pattern: /(^|[^-]\b)(?:s|tr|y)\s*<(?:[^<>\\]|\\[\s\S])*>\s*<(?:[^<>\\]|\\[\s\S])*>[msixpodualngcer]*/,
2555+ lookbehind: true,
2556+ greedy: true
2557+ },
2558+
2559+ // /.../
2560+ // The look-ahead tries to prevent two divisions on
2561+ // the same line from being highlighted as regex.
2562+ // This does not support multi-line regex.
2563+ {
2564+ pattern: /\/(?:[^\/\\\r\n]|\\.)*\/[msixpodualngc]*(?=\s*(?:$|[\r\n,.;})&|\-+*~<>!?^]|(?:lt|gt|le|ge|eq|ne|cmp|not|and|or|xor|x)\b))/,
2565+ greedy: true
2566+ }
2567+ ],
2568+
2569+ // FIXME Not sure about the handling of ::, ', and #
2570+ 'variable': [
2571+ // ${^POSTMATCH}
2572+ /[&*$@%]\{\^[A-Z]+\}/,
2573+ // $^V
2574+ /[&*$@%]\^[A-Z_]/,
2575+ // ${...}
2576+ /[&*$@%]#?(?=\{)/,
2577+ // $foo
2578+ /[&*$@%]#?(?:(?:::)*'?(?!\d)[\w$]+)+(?:::)*/i,
2579+ // $1
2580+ /[&*$@%]\d+/,
2581+ // $_, @_, %!
2582+ // The negative lookahead prevents from breaking the %= operator
2583+ /(?!%=)[$@%][!"#$%&'()*+,\-.\/:;<=>?@[\\\]^_`{|}~]/
2584+ ],
2585+ 'filehandle': {
2586+ // <>, <FOO>, _
2587+ pattern: /<(?![<=])\S*>|\b_\b/,
2588+ alias: 'symbol'
2589+ },
2590+ 'vstring': {
2591+ // v1.2, 1.2.3
2592+ pattern: /v\d+(?:\.\d+)*|\d+(?:\.\d+){2,}/,
2593+ alias: 'string'
2594+ },
2595+ 'function': {
2596+ pattern: /sub [a-z0-9_]+/i,
2597+ inside: {
2598+ keyword: /sub/
2599+ }
2600+ },
2601+ 'keyword': /\b(?:any|break|continue|default|delete|die|do|else|elsif|eval|for|foreach|given|goto|if|last|local|my|next|our|package|print|redo|require|return|say|state|sub|switch|undef|unless|until|use|when|while)\b/,
2602+ 'number': /\b(?:0x[\dA-Fa-f](?:_?[\dA-Fa-f])*|0b[01](?:_?[01])*|(?:\d(?:_?\d)*)?\.?\d(?:_?\d)*(?:[Ee][+-]?\d+)?)\b/,
2603+ 'operator': /-[rwxoRWXOezsfdlpSbctugkTBMAC]\b|\+[+=]?|-[-=>]?|\*\*?=?|\/\/?=?|=[=~>]?|~[~=]?|\|\|?=?|&&?=?|<(?:=>?|<=?)?|>>?=?|![~=]?|[%^]=?|\.(?:=|\.\.?)?|[\\?]|\bx(?:=|\b)|\b(?:lt|gt|le|ge|eq|ne|cmp|not|and|or|xor)\b/,
2604+ 'punctuation': /[{}[\];(),:]/
23982605 };
23992606
24002607 /**
@@ -2402,191 +2609,191 @@ Prism.languages.perl = { · 1 unmodified line
24022609 * Modified by Miles Johnson: http://milesj.me
24032610 *
24042611 * Supports the following:
2405− * - Extends clike syntax
2406− * - Support for PHP 5.3+ (namespaces, traits, generators, etc)
2407− * - Smarter constant and function matching
2612+ * - Extends clike syntax
2613+ * - Support for PHP 5.3+ (namespaces, traits, generators, etc)
2614+ * - Smarter constant and function matching
24082615 *
24092616 * Adds the following new token classes:
2410− * constant, delimiter, variable, function, package
2617+ * constant, delimiter, variable, function, package
24112618 */
24122619 (function (Prism) {
2413− Prism.languages.php = Prism.languages.extend('clike', {
2414− '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,
2415− 'boolean': {
2416− pattern: /\b(?:false|true)\b/i,
2417− alias: 'constant'
2418− },
2419− 'constant': [
2420− /\b[A-Z_][A-Z0-9_]*\b/,
2421− /\b(?:null)\b/i,
2422− ],
2423− 'comment': {
2424− pattern: /(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/,
2425− lookbehind: true
2426− }
2427− });
2428−
2429− Prism.languages.insertBefore('php', 'string', {
2430− 'shell-comment': {
2431− pattern: /(^|[^\\])#.*/,
2432− lookbehind: true,
2433− alias: 'comment'
2434− }
2435− });
2436−
2437− Prism.languages.insertBefore('php', 'comment', {
2438− 'delimiter': {
2439− pattern: /\?>$|^<\?(?:php(?=\s)|=)?/i,
2440− alias: 'important'
2441− }
2442− });
2443−
2444− Prism.languages.insertBefore('php', 'keyword', {
2445− 'variable': /\$+(?:\w+\b|(?={))/i,
2446− 'package': {
2447− pattern: /(\\|namespace\s+|use\s+)[\w\\]+/,
2448− lookbehind: true,
2449− inside: {
2450− punctuation: /\\/
2451− }
2452− }
2453− });
2454−
2455− // Must be defined after the function pattern
2456− Prism.languages.insertBefore('php', 'operator', {
2457− 'property': {
2458− pattern: /(->)[\w]+/,
2459− lookbehind: true
2460− }
2461− });
2462−
2463− var string_interpolation = {
2464− pattern: /{\$(?:{(?:{[^{}]+}|[^{}]+)}|[^{}])+}|(^|[^\\{])\$+(?:\w+(?:\[.+?]|->\w+)*)/,
2465− lookbehind: true,
2466− inside: Prism.languages.php
2467− };
2468−
2469− Prism.languages.insertBefore('php', 'string', {
2470− 'nowdoc-string': {
2471− pattern: /<<<'([^']+)'(?:\r\n?|\n)(?:.*(?:\r\n?|\n))*?\1;/,
2472− greedy: true,
2473− alias: 'string',
2474− inside: {
2475− 'delimiter': {
2476− pattern: /^<<<'[^']+'|[a-z_]\w*;$/i,
2477− alias: 'symbol',
2478− inside: {
2479− 'punctuation': /^<<<'?|[';]$/
2480− }
2481− }
2482− }
2483− },
2484− 'heredoc-string': {
2485− pattern: /<<<(?:"([^"]+)"(?:\r\n?|\n)(?:.*(?:\r\n?|\n))*?\1;|([a-z_]\w*)(?:\r\n?|\n)(?:.*(?:\r\n?|\n))*?\2;)/i,
2486− greedy: true,
2487− alias: 'string',
2488− inside: {
2489− 'delimiter': {
2490− pattern: /^<<<(?:"[^"]+"|[a-z_]\w*)|[a-z_]\w*;$/i,
2491− alias: 'symbol',
2492− inside: {
2493− 'punctuation': /^<<<"?|[";]$/
2494− }
2495− },
2496− 'interpolation': string_interpolation // See below
2497− }
2498− },
2499− 'single-quoted-string': {
2500− pattern: /'(?:\\[\s\S]|[^\\'])*'/,
2501− greedy: true,
2502− alias: 'string'
2503− },
2504− 'double-quoted-string': {
2505− pattern: /"(?:\\[\s\S]|[^\\"])*"/,
2506− greedy: true,
2507− alias: 'string',
2508− inside: {
2509− 'interpolation': string_interpolation // See below
2510− }
2511− }
2512− });
2513− // The different types of PHP strings "replace" the C-like standard string
2514− delete Prism.languages.php['string'];
2515−
2516− Prism.hooks.add('before-tokenize', function(env) {
2517− if (!/<\?/.test(env.code)) {
2518− return;
2519− }
2520−
2521− var phpPattern = /<\?(?:[^"'/#]|\/(?![*/])|("|')(?:\\[\s\S]|(?!\1)[^\\])*\1|(?:\/\/|#)(?:[^?\n\r]|\?(?!>))*(?=$|\?>|[\r\n])|\/\*[\s\S]*?(?:\*\/|$))*?(?:\?>|$)/ig;
2522− Prism.languages['markup-templating'].buildPlaceholders(env, 'php', phpPattern);
2523− });
2524−
2525− Prism.hooks.add('after-tokenize', function(env) {
2526− Prism.languages['markup-templating'].tokenizePlaceholders(env, 'php');
2527− });
2620+ Prism.languages.php = Prism.languages.extend('clike', {
2621+ '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,
2622+ 'boolean': {
2623+ pattern: /\b(?:false|true)\b/i,
2624+ alias: 'constant'
2625+ },
2626+ 'constant': [
2627+ /\b[A-Z_][A-Z0-9_]*\b/,
2628+ /\b(?:null)\b/i,
2629+ ],
2630+ 'comment': {
2631+ pattern: /(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/,
2632+ lookbehind: true
2633+ }
2634+ });
2635+
2636+ Prism.languages.insertBefore('php', 'string', {
2637+ 'shell-comment': {
2638+ pattern: /(^|[^\\])#.*/,
2639+ lookbehind: true,
2640+ alias: 'comment'
2641+ }
2642+ });
2643+
2644+ Prism.languages.insertBefore('php', 'comment', {
2645+ 'delimiter': {
2646+ pattern: /\?>$|^<\?(?:php(?=\s)|=)?/i,
2647+ alias: 'important'
2648+ }
2649+ });
2650+
2651+ Prism.languages.insertBefore('php', 'keyword', {
2652+ 'variable': /\$+(?:\w+\b|(?={))/i,
2653+ 'package': {
2654+ pattern: /(\\|namespace\s+|use\s+)[\w\\]+/,
2655+ lookbehind: true,
2656+ inside: {
2657+ punctuation: /\\/
2658+ }
2659+ }
2660+ });
2661+
2662+ // Must be defined after the function pattern
2663+ Prism.languages.insertBefore('php', 'operator', {
2664+ 'property': {
2665+ pattern: /(->)[\w]+/,
2666+ lookbehind: true
2667+ }
2668+ });
2669+
2670+ var string_interpolation = {
2671+ pattern: /{\$(?:{(?:{[^{}]+}|[^{}]+)}|[^{}])+}|(^|[^\\{])\$+(?:\w+(?:\[[^\r\n\[\]]+\]|->\w+)*)/,
2672+ lookbehind: true,
2673+ inside: Prism.languages.php
2674+ };
2675+
2676+ Prism.languages.insertBefore('php', 'string', {
2677+ 'nowdoc-string': {
2678+ pattern: /<<<'([^']+)'[\r\n](?:.*[\r\n])*?\1;/,
2679+ greedy: true,
2680+ alias: 'string',
2681+ inside: {
2682+ 'delimiter': {
2683+ pattern: /^<<<'[^']+'|[a-z_]\w*;$/i,
2684+ alias: 'symbol',
2685+ inside: {
2686+ 'punctuation': /^<<<'?|[';]$/
2687+ }
2688+ }
2689+ }
2690+ },
2691+ 'heredoc-string': {
2692+ pattern: /<<<(?:"([^"]+)"[\r\n](?:.*[\r\n])*?\1;|([a-z_]\w*)[\r\n](?:.*[\r\n])*?\2;)/i,
2693+ greedy: true,
2694+ alias: 'string',
2695+ inside: {
2696+ 'delimiter': {
2697+ pattern: /^<<<(?:"[^"]+"|[a-z_]\w*)|[a-z_]\w*;$/i,
2698+ alias: 'symbol',
2699+ inside: {
2700+ 'punctuation': /^<<<"?|[";]$/
2701+ }
2702+ },
2703+ 'interpolation': string_interpolation // See below
2704+ }
2705+ },
2706+ 'single-quoted-string': {
2707+ pattern: /'(?:\\[\s\S]|[^\\'])*'/,
2708+ greedy: true,
2709+ alias: 'string'
2710+ },
2711+ 'double-quoted-string': {
2712+ pattern: /"(?:\\[\s\S]|[^\\"])*"/,
2713+ greedy: true,
2714+ alias: 'string',
2715+ inside: {
2716+ 'interpolation': string_interpolation // See below
2717+ }
2718+ }
2719+ });
2720+ // The different types of PHP strings "replace" the C-like standard string
2721+ delete Prism.languages.php['string'];
2722+
2723+ Prism.hooks.add('before-tokenize', function(env) {
2724+ if (!/<\?/.test(env.code)) {

982 more lines aren’t shown here.

docs/file-scrapers.md+12−0
@@ -108,6 +108,18 @@ $GS = '/usr/local/opt/ghostscript/bin/gs'; # GhostScript · 107 unmodified lines
108108
109109 ## NumPy
110110
111+## OCaml
112+
113+Download from https://www.ocaml.org/docs/ the HTML reference:
114+https://ocaml.org/releases/4.11/ocaml-4.11-refman-html.tar.gz
115+and extract it as `/path/to/devdocs/docs/ocaml`:
116+
117+```sh
118+cd /path/to/devdocs/docs
119+wget https://ocaml.org/releases/4.11/ocaml-4.11-refman-html.tar.gz
120+tar xf ocaml-4.10-refman-html.tar.gz --transform 's/htmlman/ocaml/'
121+```
122+
111123 ## OpenJDK
112124
113125 https://packages.debian.org/sid/openjdk-11-doc
lib/docs/filters/ocaml/clean_html.rb+35−0
@@ -0,0 +1,35 @@
1+module Docs
2+ class Ocaml
3+ class CleanHtmlFilter < Filter
4+ def call
5+
6+ css('pre, .caml-example').each do |node|
7+ span = node.at_css('span[id]')
8+ node['id'] = span['id'] if span
9+ node['data-type'] = "#{span.content} [#{at_css('h1').content}]" if span
10+ node['data-language'] = 'ocaml'
11+ node.name = 'pre'
12+ node.content = node.content
13+ end
14+
15+ css('.caml-input').each do |node|
16+ node.content = '# ' + node.content.strip
17+ end
18+
19+ css('.maintitle *[style]').each do |node|
20+ node.remove_attribute 'style'
21+ end
22+
23+ css('h1').each do |node|
24+ node.content = node.content
25+ table = node.ancestors('table.center')
26+ table.first.before(node).remove if table.present?
27+ end
28+
29+ css('.navbar').remove
30+
31+ doc
32+ end
33+ end
34+ end
35+end
lib/docs/filters/ocaml/entries.rb+59−0
@@ -0,0 +1,59 @@
1+module Docs
2+ class Ocaml
3+ class EntriesFilter < Docs::EntriesFilter
4+ def get_name
5+ title = context[:html_title].gsub(/\u00A0/, " ")
6+ title = title.split.join(" ").strip
7+ title.gsub!(/^Chapter /, "")
8+
9+ # Move preface at the beginning
10+ title.gsub!(/^(Contents)/, '00.1 \1')
11+ title.gsub!(/^(Foreword)/, '00.2 \1')
12+
13+ # Pad chapter numbers with zeros to sort lexicographically
14+ title.gsub!(/(^\d[\. ])/, '0\1')
15+ title.gsub!(/(?<ma>^\d+\.)(?<mb>\d[\. ])/, '\k<ma>0\k<mb>')
16+
17+ # Add dot between chapter number and title
18+ title.gsub!(/(^[\d.]+)/, '\1. ')
19+
20+ title
21+ end
22+
23+ def get_type
24+ if slug.start_with?('libref')
25+ if slug.start_with?('libref/index_')
26+ 'Indexes'
27+ else
28+ 'Library reference'
29+ end
30+ else
31+ 'Documentation'
32+ end
33+ end
34+
35+ def additional_entries
36+ entries = []
37+
38+ module_node = css('h1').at_css('span')
39+
40+ css('pre > span[id]').each do |span|
41+ if span['id'].start_with?('VAL')
42+ entry_type = 'Values'
43+ elsif span['id'].start_with?('MODULE')
44+ entry_type = 'Modules'
45+ elsif span['id'].start_with?('EXCEPTION')
46+ entry_type = 'Exceptions'
47+ else
48+ next
49+ end
50+
51+ name = span.content
52+ name += " [#{module_node.content}]" unless module_node.nil?
53+ entries << [name, span['id'], entry_type]
54+ end
55+ entries
56+ end
57+ end
58+ end
59+end
lib/docs/scrapers/ocaml.rb+30−0
@@ -0,0 +1,30 @@
1+module Docs
2+ class Ocaml < FileScraper
3+ self.name = 'OCaml'
4+ self.type = 'ocaml'
5+ self.root_path = 'index.html'
6+ self.release = '4.11'
7+ self.base_url = "https://www.ocaml.org/releases/#{self.release}/htmlman/"
8+ self.links = {
9+ home: 'https://ocaml.org/',
10+ code: 'https://github.com/ocaml/ocaml'
11+ }
12+
13+ html_filters.push 'ocaml/entries', 'ocaml/clean_html'
14+
15+ options[:skip] = %w(
16+ libref/index.html
17+ )
18+
19+ options[:skip_patterns] = [
20+ /\Acompilerlibref\//,
21+ /\Alibref\/type_/,
22+ /\Alibref\/Stdlib\.\w+\.html/,
23+ ]
24+
25+ options[:attribution] = <<-HTML
26+ &copy; INRIA 1995-2020.
27+ HTML
28+
29+ end
30+end
public/icons/docs/ocaml/16.png+0−0

Binary file not shown.

public/icons/docs/ocaml/16@2x.png+0−0

Binary file not shown.

public/icons/docs/ocaml/SOURCE+2−0
@@ -0,0 +1,2 @@
1+https://ocaml.org/docs/logos.html
2+https://github.com/ocaml/ocaml-logo/tree/master/Colour/Favicon