diff --git a/assets/javascripts/news.json b/assets/javascripts/news.json
index d6d1b7f1..f047ba73 100644
--- a/assets/javascripts/news.json
+++ b/assets/javascripts/news.json
@@ -1,7 +1,11 @@
[
+ [
+ "2021-12-27",
+ "New documentation: Zig"
+ ],
[
"2021-12-26",
- "New documentation: Gnu Make"
+ "New documentation: GNU Make"
],
[
"2021-12-07",
diff --git a/assets/javascripts/templates/pages/about_tmpl.coffee b/assets/javascripts/templates/pages/about_tmpl.coffee
index 6a73aaf7..97a24878 100644
--- a/assets/javascripts/templates/pages/about_tmpl.coffee
+++ b/assets/javascripts/templates/pages/about_tmpl.coffee
@@ -918,5 +918,9 @@ credits = [
'BSD',
'https://raw.githubusercontent.com/yiisoft/yii/master/LICENSE'
], [
+ 'Zig',
+ '2015–2021, Zig contributors',
+ 'MIT',
+ 'https://raw.githubusercontent.com/ziglang/zig/master/LICENSE'
]
]
diff --git a/assets/javascripts/vendor/prism.js b/assets/javascripts/vendor/prism.js
index 7c45701f..e3756490 100644
--- a/assets/javascripts/vendor/prism.js
+++ b/assets/javascripts/vendor/prism.js
@@ -1,5 +1,5 @@
/* PrismJS 1.25.0
-https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript+bash+c+cpp+cmake+coffeescript+crystal+d+dart+diff+django+elixir+erlang+go+groovy+java+json+julia+kotlin+latex+lua+markup-templating+matlab+nginx+nim+ocaml+perl+php+python+r+jsx+ruby+rust+scss+shell-session+sql+typescript+yaml */
+https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript+bash+c+cpp+cmake+coffeescript+crystal+d+dart+diff+django+elixir+erlang+go+groovy+java+json+julia+kotlin+latex+lua+markup-templating+matlab+nginx+nim+ocaml+perl+php+python+r+jsx+ruby+rust+scss+shell-session+sql+typescript+yaml+zig */
///
var _self = (typeof window !== 'undefined')
@@ -21,7 +21,7 @@ var _self = (typeof window !== 'undefined')
var Prism = (function (_self) {
// Private helper vars
- var lang = /\blang(?:uage)?-([\w-]+)\b/i;
+ var lang = /(?:^|\s)lang(?:uage)?-([\w-]+)(?=\s|$)/i;
var uniqueId = 0;
// The grammar object for plaintext
@@ -186,15 +186,33 @@ var Prism = (function (_self) {
* @returns {string}
*/
getLanguage: function (element) {
- while (element && !lang.test(element.className)) {
+ while (element) {
+ var m = lang.exec(element.className);
+ if (m) {
+ return m[1].toLowerCase();
+ }
element = element.parentElement;
}
- if (element) {
- return (element.className.match(lang) || [, 'none'])[1].toLowerCase();
- }
return 'none';
},
+ /**
+ * Sets the Prism `language-xxxx` class of the given element.
+ *
+ * @param {Element} element
+ * @param {string} language
+ * @returns {void}
+ */
+ setLanguage: function (element, language) {
+ // remove all `language-xxxx` classes
+ // (this might leave behind a leading space)
+ element.className = element.className.replace(RegExp(lang, 'gi'), '');
+
+ // add the new `language-xxxx` class
+ // (using `classList` will automatically clean up spaces for us)
+ element.classList.add('language-' + language);
+ },
+
/**
* Returns the script element that is currently executing.
*
@@ -549,12 +567,12 @@ var Prism = (function (_self) {
var grammar = _.languages[language];
// Set language on the element, if not present
- element.className = element.className.replace(lang, '').replace(/\s+/g, ' ') + ' language-' + language;
+ _.util.setLanguage(element, language);
// Set language on the parent, for styling
var parent = element.parentElement;
if (parent && parent.nodeName.toLowerCase() === 'pre') {
- parent.className = parent.className.replace(lang, '').replace(/\s+/g, ' ') + ' language-' + language;
+ _.util.setLanguage(parent, language);
}
var code = element.textContent;
@@ -1843,7 +1861,7 @@ Prism.languages.js = Prism.languages.javascript;
},
'variable': insideString.variable,
'function': {
- pattern: /(^|[\s;|&]|[<>]\()(?:add|apropos|apt|apt-cache|apt-get|aptitude|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;|&])/,
+ pattern: /(^|[\s;|&]|[<>]\()(?:add|apropos|apt|apt-cache|apt-get|aptitude|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|docker|docker-compose|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|podman|podman-compose|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|vcpkg|vdir|vi|vim|virsh|vmstat|wait|watch|wc|wget|whereis|which|who|whoami|write|xargs|xdg-open|yarn|yes|zenity|zip|zsh|zypper)(?=$|[)\s;|&])/,
lookbehind: true
},
'keyword': {
@@ -1914,6 +1932,11 @@ Prism.languages.c = Prism.languages.extend('clike', {
pattern: /\/\/(?:[^\r\n\\]|\\(?:\r\n?|\n|(?![\r\n])))*|\/\*[\s\S]*?(?:\*\/|$)/,
greedy: true
},
+ 'string': {
+ // https://en.cppreference.com/w/c/language/string_literal
+ pattern: /"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"/,
+ greedy: true
+ },
'class-name': {
pattern: /(\b(?:enum|struct)\s+(?:__attribute__\s*\(\([\s\S]*?\)\)\s*)?)\w+|\b[a-z]\w*_t\b/,
lookbehind: true
@@ -1924,6 +1947,14 @@ Prism.languages.c = Prism.languages.extend('clike', {
'operator': />>=?|<<=?|->|([-+&|:])\1|[?:~]|[-+*/%&|^!=<>]=?/
});
+Prism.languages.insertBefore('c', 'string', {
+ 'char': {
+ // https://en.cppreference.com/w/c/language/character_constant
+ pattern: /'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n]){0,32}'/,
+ greedy: true
+ }
+});
+
Prism.languages.insertBefore('c', 'string', {
'macro': {
// allow for multiline macro definitions
@@ -1941,6 +1972,7 @@ Prism.languages.insertBefore('c', 'string', {
},
Prism.languages.c['string']
],
+ 'char': Prism.languages.c['char'],
'comment': Prism.languages.c['comment'],
'macro-name': [
{
@@ -1966,7 +1998,10 @@ Prism.languages.insertBefore('c', 'string', {
inside: Prism.languages.c
}
}
- },
+ }
+});
+
+Prism.languages.insertBefore('c', 'function', {
// highlight predefined macros as constants
'constant': /\b(?:EOF|NULL|SEEK_CUR|SEEK_END|SEEK_SET|__DATE__|__FILE__|__LINE__|__TIMESTAMP__|__TIME__|__func__|stderr|stdin|stdout)\b/
});
@@ -2208,50 +2243,65 @@ Prism.languages.cmake = {
*/
(function (Prism) {
Prism.languages.ruby = Prism.languages.extend('clike', {
- 'comment': [
- /#.*/,
- {
- pattern: /^=begin\s[\s\S]*?^=end/m,
- greedy: true
- }
- ],
+ 'comment': {
+ pattern: /#.*|^=begin\s[\s\S]*?^=end/m,
+ greedy: true
+ },
'class-name': {
- pattern: /(\b(?:class)\s+|\bcatch\s+\()[\w.\\]+/i,
+ pattern: /(\b(?:class|module)\s+|\bcatch\s+\()[\w.\\]+|\b[A-Z_]\w*(?=\s*\.\s*new\b)/,
lookbehind: true,
inside: {
'punctuation': /[.\\]/
}
},
- 'keyword': /\b(?:BEGIN|END|alias|and|begin|break|case|class|def|define_method|defined|do|each|else|elsif|end|ensure|extend|for|if|in|include|module|new|next|nil|not|or|prepend|private|protected|public|raise|redo|require|rescue|retry|return|self|super|then|throw|undef|unless|until|when|while|yield)\b/
+ 'keyword': /\b(?:BEGIN|END|alias|and|begin|break|case|class|def|define_method|defined|do|each|else|elsif|end|ensure|extend|for|if|in|include|module|new|next|nil|not|or|prepend|private|protected|public|raise|redo|require|rescue|retry|return|self|super|then|throw|undef|unless|until|when|while|yield)\b/,
+ 'operator': /\.{2,3}|&\.|===|=>|[!=]?~|(?:&&|\|\||<<|>>|\*\*|[+\-*/%<>!^&|=])=?|[?:]/,
+ 'punctuation': /[(){}[\].,;]/,
+ });
+
+ Prism.languages.insertBefore('ruby', 'operator', {
+ 'double-colon': {
+ pattern: /::/,
+ alias: 'punctuation'
+ },
});
var interpolation = {
- pattern: /#\{[^}]+\}/,
+ pattern: /((?:^|[^\\])(?:\\{2})*)#\{(?:[^{}]|\{[^{}]*\})*\}/,
+ lookbehind: true,
inside: {
+ 'content': {
+ pattern: /^(#\{)[\s\S]+(?=\}$)/,
+ lookbehind: true,
+ inside: Prism.languages.ruby
+ },
'delimiter': {
pattern: /^#\{|\}$/,
- alias: 'tag'
- },
- rest: Prism.languages.ruby
+ alias: 'punctuation'
+ }
}
};
delete Prism.languages.ruby.function;
+ var percentExpression = '(?:' + [
+ /([^a-zA-Z0-9\s{(\[<=])(?:(?!\1)[^\\]|\\[\s\S])*\1/.source,
+ /\((?:[^()\\]|\\[\s\S]|\((?:[^()\\]|\\[\s\S])*\))*\)/.source,
+ /\{(?:[^{}\\]|\\[\s\S]|\{(?:[^{}\\]|\\[\s\S])*\})*\}/.source,
+ /\[(?:[^\[\]\\]|\\[\s\S]|\[(?:[^\[\]\\]|\\[\s\S])*\])*\]/.source,
+ /<(?:[^<>\\]|\\[\s\S]|<(?:[^<>\\]|\\[\s\S])*>)*>/.source
+ ].join('|') + ')';
+
+ var symbolName = /(?:"(?:\\.|[^"\\\r\n])*"|(?:\b[a-zA-Z_]\w*|[^\s\0-\x7F]+)[?!]?|\$.)/.source;
+
Prism.languages.insertBefore('ruby', 'keyword', {
- 'regex': [
+ 'regex-literal': [
{
- pattern: RegExp(/%r/.source + '(?:' + [
- /([^a-zA-Z0-9\s{(\[<])(?:(?!\1)[^\\]|\\[\s\S])*\1/.source,
- /\((?:[^()\\]|\\[\s\S])*\)/.source,
- // Here we need to specifically allow interpolation
- /\{(?:[^#{}\\]|#(?:\{[^}]+\})?|\\[\s\S])*\}/.source,
- /\[(?:[^\[\]\\]|\\[\s\S])*\]/.source,
- /<(?:[^<>\\]|\\[\s\S])*>/.source
- ].join('|') + ')' + /[egimnosux]{0,6}/.source),
+ pattern: RegExp(/%r/.source + percentExpression + /[egimnosux]{0,6}/.source),
greedy: true,
inside: {
- 'interpolation': interpolation
+ 'interpolation': interpolation,
+ 'regex': /[\s\S]+/
}
},
{
@@ -2259,134 +2309,176 @@ Prism.languages.cmake = {
lookbehind: true,
greedy: true,
inside: {
- 'interpolation': interpolation
+ 'interpolation': interpolation,
+ 'regex': /[\s\S]+/
}
}
],
'variable': /[@$]+[a-zA-Z_]\w*(?:[?!]|\b)/,
- 'symbol': {
- pattern: /(^|[^:]):[a-zA-Z_]\w*(?:[?!]|\b)/,
- lookbehind: true
- },
+ 'symbol': [
+ {
+ pattern: RegExp(/(^|[^:]):/.source + symbolName),
+ lookbehind: true,
+ greedy: true
+ },
+ {
+ pattern: RegExp(/([\r\n{(,][ \t]*)/.source + symbolName + /(?=:(?!:))/.source),
+ lookbehind: true,
+ greedy: true
+ },
+ ],
'method-definition': {
- pattern: /(\bdef\s+)[\w.]+/,
+ pattern: /(\bdef\s+)\w+(?:\s*\.\s*\w+)?/,
lookbehind: true,
inside: {
- 'function': /\w+$/,
- rest: Prism.languages.ruby
+ 'function': /\b\w+$/,
+ 'keyword': /^self\b/,
+ 'class-name': /^\w+/,
+ 'punctuation': /\./
}
}
});
- Prism.languages.insertBefore('ruby', 'number', {
- 'builtin': /\b(?:Array|Bignum|Binding|Class|Continuation|Dir|Exception|FalseClass|File|Fixnum|Float|Hash|IO|Integer|MatchData|Method|Module|NilClass|Numeric|Object|Proc|Range|Regexp|Stat|String|Struct|Symbol|TMS|Thread|ThreadGroup|Time|TrueClass)\b/,
- 'constant': /\b[A-Z]\w*(?:[?!]|\b)/
- });
-
- Prism.languages.ruby.string = [
- {
- pattern: RegExp(/%[qQiIwWxs]?/.source + '(?:' + [
- /([^a-zA-Z0-9\s{(\[<])(?:(?!\1)[^\\]|\\[\s\S])*\1/.source,
- /\((?:[^()\\]|\\[\s\S])*\)/.source,
- // Here we need to specifically allow interpolation
- /\{(?:[^#{}\\]|#(?:\{[^}]+\})?|\\[\s\S])*\}/.source,
- /\[(?:[^\[\]\\]|\\[\s\S])*\]/.source,
- /<(?:[^<>\\]|\\[\s\S])*>/.source
- ].join('|') + ')'),
- greedy: true,
- inside: {
- 'interpolation': interpolation
- }
- },
- {
- pattern: /("|')(?:#\{[^}]+\}|#(?!\{)|\\(?:\r\n|[\s\S])|(?!\1)[^\\#\r\n])*\1/,
- greedy: true,
- inside: {
- 'interpolation': interpolation
+ Prism.languages.insertBefore('ruby', 'string', {
+ 'string-literal': [
+ {
+ pattern: RegExp(/%[qQiIwWs]?/.source + percentExpression),
+ greedy: true,
+ inside: {
+ 'interpolation': interpolation,
+ 'string': /[\s\S]+/
+ }
+ },
+ {
+ pattern: /("|')(?:#\{[^}]+\}|#(?!\{)|\\(?:\r\n|[\s\S])|(?!\1)[^\\#\r\n])*\1/,
+ greedy: true,
+ inside: {
+ 'interpolation': interpolation,
+ 'string': /[\s\S]+/
+ }
+ },
+ {
+ pattern: /<<[-~]?([a-z_]\w*)[\r\n](?:.*[\r\n])*?[\t ]*\1/i,
+ alias: 'heredoc-string',
+ greedy: true,
+ inside: {
+ 'delimiter': {
+ pattern: /^<<[-~]?[a-z_]\w*|\b[a-z_]\w*$/i,
+ inside: {
+ 'symbol': /\b\w+/,
+ 'punctuation': /^<<[-~]?/
+ }
+ },
+ 'interpolation': interpolation,
+ 'string': /[\s\S]+/
+ }
+ },
+ {
+ pattern: /<<[-~]?'([a-z_]\w*)'[\r\n](?:.*[\r\n])*?[\t ]*\1/i,
+ alias: 'heredoc-string',
+ greedy: true,
+ inside: {
+ 'delimiter': {
+ pattern: /^<<[-~]?'[a-z_]\w*'|\b[a-z_]\w*$/i,
+ inside: {
+ 'symbol': /\b\w+/,
+ 'punctuation': /^<<[-~]?'|'$/,
+ }
+ },
+ 'string': /[\s\S]+/
+ }
}
- },
- {
- pattern: /<<[-~]?([a-z_]\w*)[\r\n](?:.*[\r\n])*?[\t ]*\1/i,
- alias: 'heredoc-string',
- greedy: true,
- inside: {
- 'delimiter': {
- pattern: /^<<[-~]?[a-z_]\w*|[a-z_]\w*$/i,
- alias: 'symbol',
- inside: {
- 'punctuation': /^<<[-~]?/
+ ],
+ 'command-literal': [
+ {
+ pattern: RegExp(/%x/.source + percentExpression),
+ greedy: true,
+ inside: {
+ 'interpolation': interpolation,
+ 'command': {
+ pattern: /[\s\S]+/,
+ alias: 'string'
}
- },
- 'interpolation': interpolation
- }
- },
- {
- pattern: /<<[-~]?'([a-z_]\w*)'[\r\n](?:.*[\r\n])*?[\t ]*\1/i,
- alias: 'heredoc-string',
- greedy: true,
- inside: {
- 'delimiter': {
- pattern: /^<<[-~]?'[a-z_]\w*'|[a-z_]\w*$/i,
- alias: 'symbol',
- inside: {
- 'punctuation': /^<<[-~]?'|'$/,
+ }
+ },
+ {
+ pattern: /`(?:#\{[^}]+\}|#(?!\{)|\\(?:\r\n|[\s\S])|[^\\`#\r\n])*`/,
+ greedy: true,
+ inside: {
+ 'interpolation': interpolation,
+ 'command': {
+ pattern: /[\s\S]+/,
+ alias: 'string'
}
}
}
- }
- ];
+ ]
+ });
+
+ delete Prism.languages.ruby.string;
+
+ Prism.languages.insertBefore('ruby', 'number', {
+ 'builtin': /\b(?:Array|Bignum|Binding|Class|Continuation|Dir|Exception|FalseClass|File|Fixnum|Float|Hash|IO|Integer|MatchData|Method|Module|NilClass|Numeric|Object|Proc|Range|Regexp|Stat|String|Struct|Symbol|TMS|Thread|ThreadGroup|Time|TrueClass)\b/,
+ 'constant': /\b[A-Z][A-Z0-9_]*(?:[?!]|\b)/
+ });
Prism.languages.rb = Prism.languages.ruby;
}(Prism));
(function (Prism) {
Prism.languages.crystal = Prism.languages.extend('ruby', {
- keyword: [
- /\b(?:__DIR__|__END_LINE__|__FILE__|__LINE__|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|require|rescue|return|select|self|sizeof|struct|super|then|type|typeof|uninitialized|union|unless|until|when|while|with|yield)\b/,
+ 'keyword': [
+ /\b(?:__DIR__|__END_LINE__|__FILE__|__LINE__|abstract|alias|annotation|as|asm|begin|break|case|class|def|do|else|elsif|end|ensure|enum|extend|for|fun|if|ifdef|include|instance_sizeof|lib|macro|module|next|of|out|pointerof|private|protected|ptr|require|rescue|return|select|self|sizeof|struct|super|then|type|typeof|undef|uninitialized|union|unless|until|when|while|with|yield)\b/,
{
pattern: /(\.\s*)(?:is_a|responds_to)\?/,
lookbehind: true
}
],
-
- number: /\b(?:0b[01_]*[01]|0o[0-7_]*[0-7]|0x[\da-fA-F_]*[\da-fA-F]|(?:\d(?:[\d_]*\d)?)(?:\.[\d_]*\d)?(?:[eE][+-]?[\d_]*\d)?)(?:_(?:[uif](?:8|16|32|64))?)?\b/
+ '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/,
+ 'operator': [
+ /->/,
+ Prism.languages.ruby.operator,
+ ],
+ 'punctuation': /[(){}[\].,;\\]/,
});
- Prism.languages.insertBefore('crystal', 'string', {
- attribute: {
- pattern: /@\[.+?\]/,
- alias: 'attr-name',
+ Prism.languages.insertBefore('crystal', 'string-literal', {
+ 'attribute': {
+ pattern: /@\[.*?\]/,
inside: {
- delimiter: {
+ 'delimiter': {
pattern: /^@\[|\]$/,
- alias: 'tag'
+ alias: 'punctuation'
+ },
+ 'attribute': {
+ pattern: /^(\s*)\w+/,
+ lookbehind: true,
+ alias: 'class-name'
+ },
+ 'args': {
+ pattern: /\S(?:[\s\S]*\S)?/,
+ inside: Prism.languages.crystal
},
- rest: Prism.languages.crystal
}
},
-
- expansion: [
- {
- pattern: /\{\{.+?\}\}/,
- inside: {
- delimiter: {
- pattern: /^\{\{|\}\}$/,
- alias: 'tag'
- },
- rest: Prism.languages.crystal
- }
- },
- {
- pattern: /\{%.+?%\}/,
- inside: {
- delimiter: {
- pattern: /^\{%|%\}$/,
- alias: 'tag'
- },
- rest: Prism.languages.crystal
+ 'expansion': {
+ pattern: /\{(?:\{.*?\}|%.*?%)\}/,
+ inside: {
+ 'content': {
+ pattern: /^(\{.)[\s\S]+(?=.\}$)/,
+ lookbehind: true,
+ inside: Prism.languages.crystal
+ },
+ 'delimiter': {
+ pattern: /^\{[\{%]|[\}%]\}$/,
+ alias: 'operator'
}
}
- ]
+ },
+ 'char': {
+ pattern: /'(?:[^\\\r\n]{1,2}|\\(?:.|u(?:[A-Fa-f0-9]{1,4}|\{[A-Fa-f0-9]{1,6}\})))'/,
+ greedy: true
+ }
});
}(Prism));
@@ -2430,10 +2522,6 @@ Prism.languages.d = Prism.languages.extend('clike', {
// eslint-disable-next-line regexp/strict
/\bq"(.)[\s\S]*?\2"/.source,
- // Characters
- // 'a', '\\', '\n', '\xFF', '\377', '\uFFFF', '\U0010FFFF', '\quot'
- /'(?:\\(?:\W|\w+)|[^\\])'/.source,
-
// eslint-disable-next-line regexp/strict
/(["`])(?:\\[\s\S]|(?!\3)[^\\])*\3[cwd]?/.source
].join('|'), 'm'),
@@ -2462,6 +2550,12 @@ Prism.languages.d = Prism.languages.extend('clike', {
'operator': /\|[|=]?|&[&=]?|\+[+=]?|-[-=]?|\.?\.\.|=[>=]?|!(?:i[ns]\b|<>?=?|>=?|=)?|\bi[ns]\b|(?:<[<>]?|>>?>?|\^\^|[*\/%^~])=?/
});
+Prism.languages.insertBefore('d', 'string', {
+ // Characters
+ // 'a', '\\', '\n', '\xFF', '\377', '\uFFFF', '\U0010FFFF', '\quot'
+ 'char': /'(?:\\(?:\W|\w+)|[^\\])'/
+});
+
Prism.languages.insertBefore('d', 'keyword', {
'property': /\B@\w*/
});
@@ -2498,16 +2592,6 @@ Prism.languages.insertBefore('d', 'function', {
};
Prism.languages.dart = Prism.languages.extend('clike', {
- 'string': [
- {
- pattern: /r?("""|''')[\s\S]*?\1/,
- greedy: true
- },
- {
- pattern: /r?(["'])(?:\\.|(?!\1)[^\\\r\n])*\1/,
- greedy: true
- }
- ],
'class-name': [
className,
{
@@ -2522,10 +2606,32 @@ Prism.languages.insertBefore('d', 'function', {
'operator': /\bis!|\b(?:as|is)\b|\+\+|--|&&|\|\||<<=?|>>=?|~(?:\/=?)?|[+\-*\/%&^|=!<>]=?|\?/
});
- Prism.languages.insertBefore('dart', 'function', {
+ Prism.languages.insertBefore('dart', 'string', {
+ 'string-literal': {
+ pattern: /r?(?:("""|''')[\s\S]*?\1|(["'])(?:\\.|(?!\2)[^\\\r\n])*\2(?!\2))/,
+ greedy: true,
+ inside: {
+ 'interpolation': {
+ pattern: /((?:^|[^\\])(?:\\{2})*)\$(?:\w+|\{(?:[^{}]|\{[^{}]*\})*\})/,
+ lookbehind: true,
+ inside: {
+ 'punctuation': /^\$\{?|\}$/,
+ 'expression': {
+ pattern: /[\s\S]+/,
+ inside: Prism.languages.dart
+ }
+ }
+ },
+ 'string': /[\s\S]+/
+ }
+ },
+ 'string': undefined
+ });
+
+ Prism.languages.insertBefore('dart', 'class-name', {
'metadata': {
pattern: /@\w+/,
- alias: 'symbol'
+ alias: 'function'
}
});
@@ -2939,15 +3045,31 @@ Prism.languages.erlang = {
Prism.languages.go = Prism.languages.extend('clike', {
'string': {
- pattern: /(["'`])(?:\\[\s\S]|(?!\1)[^\\])*\1/,
+ pattern: /(^|[^\\])"(?:\\.|[^"\\\r\n])*"|`[^`]*`/,
+ lookbehind: true,
greedy: true
},
'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/,
'boolean': /\b(?:_|false|iota|nil|true)\b/,
- 'number': /(?:\b0x[a-f\d]+|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[-+]?\d+)?)i?/i,
+ 'number': [
+ // binary and octal integers
+ /\b0(?:b[01_]+|o[0-7_]+)i?\b/i,
+ // hexadecimal integers and floats
+ /\b0x(?:[a-f\d_]+(?:\.[a-f\d_]*)?|\.[a-f\d_]+)(?:p[+-]?\d+(?:_\d+)*)?i?(?!\w)/i,
+ // decimal integers and floats
+ /(?:\b\d[\d_]*(?:\.[\d_]*)?|\B\.\d[\d_]*)(?:e[+-]?[\d_]+)?i?(?!\w)/i
+ ],
'operator': /[*\/%^!=]=?|\+[=+]?|-[=-]?|\|[=|]?|&(?:=|&|\^=?)?|>(?:>=?|=)?|<(?:<=?|=|-)?|:=|\.\.\./,
'builtin': /\b(?:append|bool|byte|cap|close|complex|complex(?:64|128)|copy|delete|error|float(?:32|64)|u?int(?:8|16|32|64)?|imag|len|make|new|panic|print(?:ln)?|real|recover|rune|string|uintptr)\b/
});
+
+Prism.languages.insertBefore('go', 'string', {
+ 'char': {
+ pattern: /'(?:\\.|[^'\\\r\n]){0,10}'/,
+ greedy: true
+ }
+});
+
delete Prism.languages.go['class-name'];
Prism.languages.groovy = Prism.languages.extend('clike', {
@@ -3042,6 +3164,11 @@ Prism.hooks.add('wrap', function (env) {
};
Prism.languages.java = Prism.languages.extend('clike', {
+ 'string': {
+ pattern: /(^|[^\\])"(?:\\.|[^"\\\r\n])*"/,
+ lookbehind: true,
+ greedy: true
+ },
'class-name': [
className,
{
@@ -3073,6 +3200,10 @@ Prism.hooks.add('wrap', function (env) {
pattern: /"""[ \t]*[\r\n](?:(?:"|"")?(?:\\.|[^"\\]))*"""/,
greedy: true,
alias: 'string'
+ },
+ 'char': {
+ pattern: /'(?:\\.|[^'\\\r\n]){1,6}'/,
+ greedy: true
}
});
@@ -3144,11 +3275,15 @@ Prism.languages.julia = {
greedy: true
},
'string': {
- // https://docs.julialang.org/en/v1/manual/strings/#man-characters-1
// https://docs.julialang.org/en/v1/manual/strings/#String-Basics-1
// https://docs.julialang.org/en/v1/manual/strings/#non-standard-string-literals-1
// https://docs.julialang.org/en/v1/manual/running-external-programs/#Running-External-Programs-1
- pattern: /"""[\s\S]+?"""|(?:\b\w+)?"(?:\\.|[^"\\\r\n])*"|(^|[^\w'])'(?:\\[^\r\n][^'\r\n]*|[^\\\r\n])'|`(?:[^\\`\r\n]|\\.)*`/,
+ pattern: /"""[\s\S]+?"""|(?:\b\w+)?"(?:\\.|[^"\\\r\n])*"|`(?:[^\\`\r\n]|\\.)*`/,
+ greedy: true
+ },
+ 'char': {
+ // https://docs.julialang.org/en/v1/manual/strings/#man-characters-1
+ pattern: /(^|[^\w'])'(?:\\[^\r\n][^'\r\n]*|[^\\\r\n])'/,
lookbehind: true,
greedy: true
},
@@ -3187,19 +3322,60 @@ Prism.languages.julia = {
delete Prism.languages.kotlin['class-name'];
+ var interpolationInside = {
+ 'interpolation-punctuation': {
+ pattern: /^\$\{?|\}$/,
+ alias: 'punctuation'
+ },
+ 'expression': {
+ pattern: /[\s\S]+/,
+ inside: Prism.languages.kotlin
+ }
+ };
+
Prism.languages.insertBefore('kotlin', 'string', {
- 'raw-string': {
- pattern: /("""|''')[\s\S]*?\1/,
- alias: 'string'
- // See interpolation below
+ // https://kotlinlang.org/spec/expressions.html#string-interpolation-expressions
+ 'string-literal': [
+ {
+ pattern: /"""(?:[^$]|\$(?:(?!\{)|\{[^{}]*\}))*?"""/,
+ alias: 'multiline',
+ inside: {
+ 'interpolation': {
+ pattern: /\$(?:[a-z_]\w*|\{[^{}]*\})/i,
+ inside: interpolationInside
+ },
+ 'string': /[\s\S]+/
+ }
+ },
+ {
+ pattern: /"(?:[^"\\\r\n$]|\\.|\$(?:(?!\{)|\{[^{}]*\}))*"/,
+ alias: 'singleline',
+ inside: {
+ 'interpolation': {
+ pattern: /((?:^|[^\\])(?:\\{2})*)\$(?:[a-z_]\w*|\{[^{}]*\})/i,
+ lookbehind: true,
+ inside: interpolationInside
+ },
+ 'string': /[\s\S]+/
+ }
+ }
+ ],
+ 'char': {
+ // https://kotlinlang.org/spec/expressions.html#character-literals
+ pattern: /'(?:[^'\\\r\n]|\\(?:.|u[a-fA-F0-9]{0,4}))'/,
+ greedy: true
}
});
+
+ delete Prism.languages.kotlin['string'];
+
Prism.languages.insertBefore('kotlin', 'keyword', {
'annotation': {
pattern: /\B@(?:\w+:)?(?:[A-Z]\w*|\[[^\]]+\])/,
alias: 'builtin'
}
});
+
Prism.languages.insertBefore('kotlin', 'function', {
'label': {
pattern: /\b\w+@|@\w+\b/,
@@ -3207,27 +3383,6 @@ Prism.languages.julia = {
}
});
- var interpolation = [
- {
- pattern: /\$\{[^}]+\}/,
- inside: {
- 'delimiter': {
- pattern: /^\$\{|\}$/,
- alias: 'variable'
- },
- rest: Prism.languages.kotlin
- }
- },
- {
- pattern: /\$\w+/,
- alias: 'variable'
- }
- ];
-
- Prism.languages.kotlin['string'].inside = Prism.languages.kotlin['raw-string'].inside = {
- interpolation: interpolation
- };
-
Prism.languages.kt = Prism.languages.kotlin;
Prism.languages.kts = Prism.languages.kotlin;
}(Prism));
@@ -3342,7 +3497,8 @@ Prism.languages.matlab = {
Prism.languages.nginx = {
'comment': {
pattern: /(^|[\s{};])#.*/,
- lookbehind: true
+ lookbehind: true,
+ greedy: true
},
'directive': {
pattern: /(^|\s)\w(?:[^;{}"'\\\s]|\\.|"(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*'|\s+(?:#.*(?!.)|(?![#\s])))*?(?=\s*[;{])/,
@@ -3352,6 +3508,7 @@ Prism.languages.matlab = {
'string': {
pattern: /((?:^|[^\\])(?:\\\\)*)(?:"(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*')/,
lookbehind: true,
+ greedy: true,
inside: {
'escape': {
pattern: /\\["'\\nrt]/,
@@ -3389,23 +3546,29 @@ Prism.languages.matlab = {
}(Prism));
Prism.languages.nim = {
- 'comment': /#.*/,
- // Double-quoted strings can be prefixed by an identifier (Generalized raw string literals)
- // Character literals are handled specifically to prevent issues with numeric type suffixes
+ 'comment': {
+ pattern: /#.*/,
+ greedy: true
+ },
'string': {
- pattern: /(?:(?:\b(?!\d)(?:\w|\\x[89a-fA-F][0-9a-fA-F])+)?(?:"""[\s\S]*?"""(?!")|"(?:\\[\s\S]|""|[^"\\])*")|'(?:\\(?:\d+|x[\da-fA-F]{2}|.)|[^'])')/,
+ // Double-quoted strings can be prefixed by an identifier (Generalized raw string literals)
+ pattern: /(?:\b(?!\d)(?:\w|\\x[89a-fA-F][0-9a-fA-F])+)?(?:"""[\s\S]*?"""(?!")|"(?:\\[\s\S]|""|[^"\\])*")/,
greedy: true
},
- // The negative look ahead prevents wrong highlighting of the .. operator
- 'number': /\b(?:0[xXoObB][\da-fA-F_]+|\d[\d_]*(?:(?!\.\.)\.[\d_]*)?(?:[eE][+-]?\d[\d_]*)?)(?:'?[iuf]\d*)?/,
- '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/,
+ 'char': {
+ // Character literals are handled specifically to prevent issues with numeric type suffixes
+ pattern: /'(?:\\(?:\d+|x[\da-fA-F]{0,2}|.)|[^'])'/,
+ greedy: true
+ },
+
'function': {
pattern: /(?:(?!\d)(?:\w|\\x[89a-fA-F][0-9a-fA-F])+|`[^`\r\n]+`)\*?(?:\[[^\]]+\])?(?=\s*\()/,
+ greedy: true,
inside: {
'operator': /\*$/
}
},
- // We don't want to highlight operators inside backticks
+ // We don't want to highlight operators (and anything really) inside backticks
'identifier': {
pattern: /`[^`\r\n]+`/,
greedy: true,
@@ -3413,6 +3576,10 @@ Prism.languages.nim = {
'punctuation': /`/
}
},
+
+ // The negative look ahead prevents wrong highlighting of the .. operator
+ 'number': /\b(?:0[xXoObB][\da-fA-F_]+|\d[\d_]*(?:(?!\.\.)\.[\d_]*)?(?:[eE][+-]?\d[\d_]*)?)(?:'?[iuf]\d*)?/,
+ '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/,
'operator': {
// Look behind and look ahead prevent wrong highlighting of punctuations [. .] {. .} (. .)
// but allow the slice operator .. to take precedence over them
@@ -3423,26 +3590,42 @@ Prism.languages.nim = {
'punctuation': /[({\[]\.|\.[)}\]]|[`(){}\[\],:]/
};
+// https://ocaml.org/manual/lex.html
+
Prism.languages.ocaml = {
- 'comment': /\(\*[\s\S]*?\*\)/,
+ 'comment': {
+ pattern: /\(\*[\s\S]*?\*\)/,
+ greedy: true
+ },
+ 'char': {
+ pattern: /'(?:[^\\\r\n']|\\(?:.|[ox]?[0-9a-f]{1,3}))'/i,
+ greedy: true
+ },
'string': [
{
- pattern: /"(?:\\.|[^\\\r\n"])*"/,
+ pattern: /"(?:\\(?:[\s\S]|\r\n)|[^\\\r\n"])*"/,
greedy: true
},
{
- pattern: /(['`])(?:\\(?:\d+|x[\da-f]+|.)|(?!\1)[^\\\r\n])\1/i,
+ pattern: /\{([a-z_]*)\|[\s\S]*?\|\1\}/,
greedy: true
}
],
- 'number': /\b(?:0x[\da-f][\da-f_]+|(?:0[bo])?\d[\d_]*(?:\.[\d_]*)?(?:e[+-]?[\d_]+)?)/i,
+ 'number': [
+ // binary and octal
+ /\b(?:0b[01][01_]*|0o[0-7][0-7_]*)\b/i,
+ // hexadecimal
+ /\b0x[a-f0-9][a-f0-9_]*(?:\.[a-f0-9_]*)?(?:p[+-]?\d[\d_]*)?(?!\w)/i,
+ // decimal
+ /\b\d[\d_]*(?:\.[\d_]*)?(?:e[+-]?\d[\d_]*)?(?!\w)/i,
+ ],
'directive': {
pattern: /\B#\w+/,
- alias: 'important'
+ alias: 'property'
},
'label': {
pattern: /\B~\w+/,
- alias: 'function'
+ alias: 'property'
},
'type-variable': {
pattern: /\B'\w+/,
@@ -3450,212 +3633,178 @@ Prism.languages.ocaml = {
},
'variant': {
pattern: /`\w+/,
- alias: 'variable'
- },
- 'module': {
- pattern: /\b[A-Z]\w+/,
- alias: 'variable'
+ alias: 'symbol'
},
// For the list of keywords and operators,
// see: http://caml.inria.fr/pub/docs/manual-ocaml/lex.html#sec84
'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/,
'boolean': /\b(?:false|true)\b/,
+
+ 'operator-like-punctuation': {
+ pattern: /\[[<>|]|[>|]\]|\{<|>\}/,
+ alias: 'punctuation'
+ },
// Custom operators are allowed
- 'operator': /:=|[=<>@^|&+\-*\/$%!?~][!$%&*+\-.\/:<=>?@^|~]*|\b(?:and|asr|land|lor|lsl|lsr|lxor|mod|or)\b/,
- 'punctuation': /[(){}\[\].,:;]|\b_\b/
+ 'operator': /\.[.~]|:[=>]|[=<>@^|&+\-*\/$%!?~][!$%&*+\-.\/:<=>?@^|~]*|\b(?:and|asr|land|lor|lsl|lsr|lxor|mod|or)\b/,
+ 'punctuation': /;;|::|[(){}\[\].,:;#]|\b_\b/
};
-Prism.languages.perl = {
- 'comment': [
- {
- // POD
- pattern: /(^\s*)=\w[\s\S]*?=cut.*/m,
- lookbehind: true
- },
- {
- pattern: /(^|[^\\$])#.*/,
- lookbehind: true
- }
- ],
- // TODO Could be nice to handle Heredoc too.
- 'string': [
- // q/.../
- {
- pattern: /\b(?:q|qq|qw|qx)\s*([^a-zA-Z0-9\s{(\[<])(?:(?!\1)[^\\]|\\[\s\S])*\1/,
- greedy: true
- },
-
- // q a...a
- {
- pattern: /\b(?:q|qq|qw|qx)\s+([a-zA-Z0-9])(?:(?!\1)[^\\]|\\[\s\S])*\1/,
- greedy: true
- },
-
- // q(...)
- {
- pattern: /\b(?:q|qq|qw|qx)\s*\((?:[^()\\]|\\[\s\S])*\)/,
- greedy: true
- },
-
- // q{...}
- {
- pattern: /\b(?:q|qq|qw|qx)\s*\{(?:[^{}\\]|\\[\s\S])*\}/,
- greedy: true
- },
-
- // q[...]
- {
- pattern: /\b(?:q|qq|qw|qx)\s*\[(?:[^[\]\\]|\\[\s\S])*\]/,
- greedy: true
- },
-
- // q<...>
- {
- pattern: /\b(?:q|qq|qw|qx)\s*<(?:[^<>\\]|\\[\s\S])*>/,
- greedy: true
- },
-
- // "...", `...`
- {
- pattern: /("|`)(?:(?!\1)[^\\]|\\[\s\S])*\1/,
- greedy: true
- },
-
- // '...'
- // FIXME Multi-line single-quoted strings are not supported as they would break variables containing '
- {
- pattern: /'(?:[^'\\\r\n]|\\.)*'/,
- greedy: true
- }
- ],
- 'regex': [
- // m/.../
- {
- pattern: /\b(?:m|qr)\s*([^a-zA-Z0-9\s{(\[<])(?:(?!\1)[^\\]|\\[\s\S])*\1[msixpodualngc]*/,
- greedy: true
- },
-
- // m a...a
- {
- pattern: /\b(?:m|qr)\s+([a-zA-Z0-9])(?:(?!\1)[^\\]|\\[\s\S])*\1[msixpodualngc]*/,
- greedy: true
- },
-
- // m(...)
- {
- pattern: /\b(?:m|qr)\s*\((?:[^()\\]|\\[\s\S])*\)[msixpodualngc]*/,
- greedy: true
- },
+(function (Prism) {
- // m{...}
- {
- pattern: /\b(?:m|qr)\s*\{(?:[^{}\\]|\\[\s\S])*\}[msixpodualngc]*/,
- greedy: true
- },
+ var brackets = /(?:\((?:[^()\\]|\\[\s\S])*\)|\{(?:[^{}\\]|\\[\s\S])*\}|\[(?:[^[\]\\]|\\[\s\S])*\]|<(?:[^<>\\]|\\[\s\S])*>)/.source;
- // m[...]
- {
- pattern: /\b(?:m|qr)\s*\[(?:[^[\]\\]|\\[\s\S])*\][msixpodualngc]*/,
- greedy: true
- },
+ Prism.languages.perl = {
+ 'comment': [
+ {
+ // POD
+ pattern: /(^\s*)=\w[\s\S]*?=cut.*/m,
+ lookbehind: true,
+ greedy: true
+ },
+ {
+ pattern: /(^|[^\\$])#.*/,
+ lookbehind: true,
+ greedy: true
+ }
+ ],
+ // TODO Could be nice to handle Heredoc too.
+ 'string': [
+ {
+ pattern: RegExp(
+ /\b(?:q|qq|qw|qx)(?![a-zA-Z0-9])\s*/.source +
+ '(?:' +
+ [
+ // q/.../
+ /([^a-zA-Z0-9\s{(\[<])(?:(?!\1)[^\\]|\\[\s\S])*\1/.source,
+
+ // q a...a
+ // eslint-disable-next-line regexp/strict
+ /([a-zA-Z0-9])(?:(?!\2)[^\\]|\\[\s\S])*\2/.source,
+
+ // q(...)
+ // q{...}
+ // q[...]
+ // q<...>
+ brackets,
+ ].join('|') +
+ ')'
+ ),
+ greedy: true
+ },
- // m<...>
- {
- pattern: /\b(?:m|qr)\s*<(?:[^<>\\]|\\[\s\S])*>[msixpodualngc]*/,
- greedy: true
- },
+ // "...", `...`
+ {
+ pattern: /("|`)(?:(?!\1)[^\\]|\\[\s\S])*\1/,
+ greedy: true
+ },
- // The lookbehinds prevent -s from breaking
- // FIXME We don't handle change of separator like s(...)[...]
- // s/.../.../
- {
- pattern: /(^|[^-]\b)(?:s|tr|y)\s*([^a-zA-Z0-9\s{(\[<])(?:(?!\2)[^\\]|\\[\s\S])*\2(?:(?!\2)[^\\]|\\[\s\S])*\2[msixpodualngcer]*/,
- lookbehind: true,
- greedy: true
- },
+ // '...'
+ // FIXME Multi-line single-quoted strings are not supported as they would break variables containing '
+ {
+ pattern: /'(?:[^'\\\r\n]|\\.)*'/,
+ greedy: true
+ }
+ ],
+ 'regex': [
+ {
+ pattern: RegExp(
+ /\b(?:m|qr)(?![a-zA-Z0-9])\s*/.source +
+ '(?:' +
+ [
+ // m/.../
+ /([^a-zA-Z0-9\s{(\[<])(?:(?!\1)[^\\]|\\[\s\S])*\1/.source,
+
+ // m a...a
+ // eslint-disable-next-line regexp/strict
+ /([a-zA-Z0-9])(?:(?!\2)[^\\]|\\[\s\S])*\2/.source,
+
+ // m(...)
+ // m{...}
+ // m[...]
+ // m<...>
+ brackets,
+ ].join('|') +
+ ')' +
+ /[msixpodualngc]*/.source
+ ),
+ greedy: true
+ },
- // s a...a...a
- {
- pattern: /(^|[^-]\b)(?:s|tr|y)\s+([a-zA-Z0-9])(?:(?!\2)[^\\]|\\[\s\S])*\2(?:(?!\2)[^\\]|\\[\s\S])*\2[msixpodualngcer]*/,
- lookbehind: true,
- greedy: true
- },
+ // The lookbehinds prevent -s from breaking
+ {
+ pattern: RegExp(
+ /(^|[^-])\b(?:s|tr|y)(?![a-zA-Z0-9])\s*/.source +
+ '(?:' +
+ [
+ // s/.../.../
+ // eslint-disable-next-line regexp/strict
+ /([^a-zA-Z0-9\s{(\[<])(?:(?!\2)[^\\]|\\[\s\S])*\2(?:(?!\2)[^\\]|\\[\s\S])*\2/.source,
+
+ // s a...a...a
+ // eslint-disable-next-line regexp/strict
+ /([a-zA-Z0-9])(?:(?!\3)[^\\]|\\[\s\S])*\3(?:(?!\3)[^\\]|\\[\s\S])*\3/.source,
+
+ // s(...)(...)
+ // s{...}{...}
+ // s[...][...]
+ // s<...><...>
+ // s(...)[...]
+ brackets + /\s*/.source + brackets,
+ ].join('|') +
+ ')' +
+ /[msixpodualngcer]*/.source
+ ),
+ lookbehind: true,
+ greedy: true
+ },
- // s(...)(...)
- {
- pattern: /(^|[^-]\b)(?:s|tr|y)\s*\((?:[^()\\]|\\[\s\S])*\)\s*\((?:[^()\\]|\\[\s\S])*\)[msixpodualngcer]*/,
- lookbehind: true,
- greedy: true
- },
+ // /.../
+ // The look-ahead tries to prevent two divisions on
+ // the same line from being highlighted as regex.
+ // This does not support multi-line regex.
+ {
+ pattern: /\/(?:[^\/\\\r\n]|\\.)*\/[msixpodualngc]*(?=\s*(?:$|[\r\n,.;})&|\-+*~<>!?^]|(?:and|cmp|eq|ge|gt|le|lt|ne|not|or|x|xor)\b))/,
+ greedy: true
+ }
+ ],
- // s{...}{...}
- {
- pattern: /(^|[^-]\b)(?:s|tr|y)\s*\{(?:[^{}\\]|\\[\s\S])*\}\s*\{(?:[^{}\\]|\\[\s\S])*\}[msixpodualngcer]*/,
- lookbehind: true,
- greedy: true
+ // FIXME Not sure about the handling of ::, ', and #
+ 'variable': [
+ // ${^POSTMATCH}
+ /[&*$@%]\{\^[A-Z]+\}/,
+ // $^V
+ /[&*$@%]\^[A-Z_]/,
+ // ${...}
+ /[&*$@%]#?(?=\{)/,
+ // $foo
+ /[&*$@%]#?(?:(?:::)*'?(?!\d)[\w$]+(?![\w$]))+(?:::)*/,
+ // $1
+ /[&*$@%]\d+/,
+ // $_, @_, %!
+ // The negative lookahead prevents from breaking the %= operator
+ /(?!%=)[$@%][!"#$%&'()*+,\-.\/:;<=>?@[\\\]^_`{|}~]/
+ ],
+ 'filehandle': {
+ // <>, , _
+ pattern: /<(?![<=])\S*?>|\b_\b/,
+ alias: 'symbol'
},
-
- // s[...][...]
- {
- pattern: /(^|[^-]\b)(?:s|tr|y)\s*\[(?:[^[\]\\]|\\[\s\S])*\]\s*\[(?:[^[\]\\]|\\[\s\S])*\][msixpodualngcer]*/,
- lookbehind: true,
- greedy: true
+ 'v-string': {
+ // v1.2, 1.2.3
+ pattern: /v\d+(?:\.\d+)*|\d+(?:\.\d+){2,}/,
+ alias: 'string'
},
-
- // s<...><...>
- {
- pattern: /(^|[^-]\b)(?:s|tr|y)\s*<(?:[^<>\\]|\\[\s\S])*>\s*<(?:[^<>\\]|\\[\s\S])*>[msixpodualngcer]*/,
- lookbehind: true,
- greedy: true
+ 'function': {
+ pattern: /(\bsub[ \t]+)\w+/,
+ lookbehind: true
},
+ '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/,
+ 'number': /\b(?:0x[\dA-Fa-f](?:_?[\dA-Fa-f])*|0b[01](?:_?[01])*|(?:(?:\d(?:_?\d)*)?\.)?\d(?:_?\d)*(?:[Ee][+-]?\d+)?)\b/,
+ 'operator': /-[rwxoRWXOezsfdlpSbctugkTBMAC]\b|\+[+=]?|-[-=>]?|\*\*?=?|\/\/?=?|=[=~>]?|~[~=]?|\|\|?=?|&&?=?|<(?:=>?|<=?)?|>>?=?|![~=]?|[%^]=?|\.(?:=|\.\.?)?|[\\?]|\bx(?:=|\b)|\b(?:and|cmp|eq|ge|gt|le|lt|ne|not|or|xor)\b/,
+ 'punctuation': /[{}[\];(),:]/
+ };
- // /.../
- // The look-ahead tries to prevent two divisions on
- // the same line from being highlighted as regex.
- // This does not support multi-line regex.
- {
- pattern: /\/(?:[^\/\\\r\n]|\\.)*\/[msixpodualngc]*(?=\s*(?:$|[\r\n,.;})&|\-+*~<>!?^]|(?:and|cmp|eq|ge|gt|le|lt|ne|not|or|x|xor)\b))/,
- greedy: true
- }
- ],
-
- // FIXME Not sure about the handling of ::, ', and #
- 'variable': [
- // ${^POSTMATCH}
- /[&*$@%]\{\^[A-Z]+\}/,
- // $^V
- /[&*$@%]\^[A-Z_]/,
- // ${...}
- /[&*$@%]#?(?=\{)/,
- // $foo
- /[&*$@%]#?(?:(?:::)*'?(?!\d)[\w$]+(?![\w$]))+(?:::)*/,
- // $1
- /[&*$@%]\d+/,
- // $_, @_, %!
- // The negative lookahead prevents from breaking the %= operator
- /(?!%=)[$@%][!"#$%&'()*+,\-.\/:;<=>?@[\\\]^_`{|}~]/
- ],
- 'filehandle': {
- // <>, , _
- pattern: /<(?![<=])\S*>|\b_\b/,
- alias: 'symbol'
- },
- 'vstring': {
- // v1.2, 1.2.3
- pattern: /v\d+(?:\.\d+)*|\d+(?:\.\d+){2,}/,
- alias: 'string'
- },
- 'function': {
- pattern: /sub \w+/i,
- inside: {
- keyword: /sub/
- }
- },
- '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/,
- 'number': /\b(?:0x[\dA-Fa-f](?:_?[\dA-Fa-f])*|0b[01](?:_?[01])*|(?:(?:\d(?:_?\d)*)?\.)?\d(?:_?\d)*(?:[Ee][+-]?\d+)?)\b/,
- 'operator': /-[rwxoRWXOezsfdlpSbctugkTBMAC]\b|\+[+=]?|-[-=>]?|\*\*?=?|\/\/?=?|=[=~>]?|~[~=]?|\|\|?=?|&&?=?|<(?:=>?|<=?)?|>>?=?|![~=]?|[%^]=?|\.(?:=|\.\.?)?|[\\?]|\bx(?:=|\b)|\b(?:and|cmp|eq|ge|gt|le|lt|ne|not|or|xor)\b/,
- 'punctuation': /[{}[\];(),:]/
-};
+}(Prism));
/**
* Original by Aaron Harun: http://aahacreative.com/2012/07/31/php-syntax-highlighting-prism/
@@ -4003,7 +4152,8 @@ Prism.languages.perl = {
Prism.languages.python = {
'comment': {
pattern: /(^|[^\\])#.*/,
- lookbehind: true
+ lookbehind: true,
+ greedy: true
},
'string-interpolation': {
pattern: /(?:f|fr|rf)(?:("""|''')[\s\S]*?\1|("|')(?:\\.|(?!\2)[^\\\r\n])*\2)/i,
@@ -4132,6 +4282,7 @@ Prism.languages.r = {
'script': {
// Allow for two levels of nesting
pattern: re(/=/.source),
+ alias: 'language-javascript',
inside: {
'script-punctuation': {
pattern: /^=(?=\{)/,
@@ -4139,7 +4290,6 @@ Prism.languages.r = {
},
rest: Prism.languages.jsx
},
- 'alias': 'language-javascript'
}
}, Prism.languages.jsx.tag);
@@ -4263,8 +4413,7 @@ Prism.languages.r = {
},
'char': {
pattern: /b?'(?:\\(?:x[0-7][\da-fA-F]|u\{(?:[\da-fA-F]_*){1,6}\}|.)|[^\\\r\n\t'])'/,
- greedy: true,
- alias: 'string'
+ greedy: true
},
'attribute': {
pattern: /#!?\[(?:[^\[\]"]|"(?:\\[\s\S]|[^\\"])*")*\]/,
@@ -4307,7 +4456,7 @@ Prism.languages.r = {
alias: 'function'
},
'type-definition': {
- pattern: /(\b(?:enum|struct|union)\s+)\w+/,
+ pattern: /(\b(?:enum|struct|trait|type|union)\s+)\w+/,
lookbehind: true,
alias: 'class-name'
},
@@ -4695,3 +4844,105 @@ Prism.languages.sql = {
}(Prism));
+(function (Prism) {
+
+ function literal(str) {
+ return function () { return str; };
+ }
+
+ var keyword = /\b(?:align|allowzero|and|anyframe|anytype|asm|async|await|break|cancel|catch|comptime|const|continue|defer|else|enum|errdefer|error|export|extern|fn|for|if|inline|linksection|nakedcc|noalias|nosuspend|null|or|orelse|packed|promise|pub|resume|return|stdcallcc|struct|suspend|switch|test|threadlocal|try|undefined|union|unreachable|usingnamespace|var|volatile|while)\b/;
+
+ var IDENTIFIER = '\\b(?!' + keyword.source + ')(?!\\d)\\w+\\b';
+ var ALIGN = /align\s*\((?:[^()]|\([^()]*\))*\)/.source;
+ var PREFIX_TYPE_OP = /(?:\?|\bpromise->|(?:\[[^[\]]*\]|\*(?!\*)|\*\*)(?:\s*|\s*const\b|\s*volatile\b|\s*allowzero\b)*)/.source.replace(//g, literal(ALIGN));
+ var SUFFIX_EXPR = /(?:\bpromise\b|(?:\berror\.)?(?:\.)*(?!\s+))/.source.replace(//g, literal(IDENTIFIER));
+ var TYPE = '(?!\\s)(?:!?\\s*(?:' + PREFIX_TYPE_OP + '\\s*)*' + SUFFIX_EXPR + ')+';
+
+ /*
+ * A simplified grammar for Zig compile time type literals:
+ *
+ * TypeExpr = ( "!"? PREFIX_TYPE_OP* SUFFIX_EXPR )+
+ *
+ * SUFFIX_EXPR = ( \b "promise" \b | ( \b "error" "." )? IDENTIFIER ( "." IDENTIFIER )* (?! \s+ IDENTIFIER ) )
+ *
+ * PREFIX_TYPE_OP = "?"
+ * | \b "promise" "->"
+ * | ( "[" [^\[\]]* "]" | "*" | "**" ) ( ALIGN | "const" \b | "volatile" \b | "allowzero" \b )*
+ *
+ * ALIGN = "align" "(" ( [^()] | "(" [^()]* ")" )* ")"
+ *
+ * IDENTIFIER = \b (?! KEYWORD ) [a-zA-Z_] \w* \b
+ *
+ */
+
+ Prism.languages.zig = {
+ 'comment': [
+ {
+ pattern: /\/\/[/!].*/,
+ alias: 'doc-comment'
+ },
+ /\/{2}.*/
+ ],
+ 'string': [
+ {
+ // "string" and c"string"
+ pattern: /(^|[^\\@])c?"(?:[^"\\\r\n]|\\.)*"/,
+ lookbehind: true,
+ greedy: true
+ },
+ {
+ // multiline strings and c-strings
+ pattern: /([\r\n])([ \t]+c?\\{2}).*(?:(?:\r\n?|\n)\2.*)*/,
+ lookbehind: true,
+ greedy: true
+ }
+ ],
+ 'char': {
+ // characters 'a', '\n', '\xFF', '\u{10FFFF}'
+ pattern: /(^|[^\\])'(?:[^'\\\r\n]|[\uD800-\uDFFF]{2}|\\(?:.|x[a-fA-F\d]{2}|u\{[a-fA-F\d]{1,6}\}))'/,
+ lookbehind: true,
+ greedy: true
+ },
+ 'builtin': /\B@(?!\d)\w+(?=\s*\()/,
+ 'label': {
+ pattern: /(\b(?:break|continue)\s*:\s*)\w+\b|\b(?!\d)\w+\b(?=\s*:\s*(?:\{|while\b))/,
+ lookbehind: true
+ },
+ 'class-name': [
+ // const Foo = struct {};
+ /\b(?!\d)\w+(?=\s*=\s*(?:(?:extern|packed)\s+)?(?:enum|struct|union)\s*[({])/,
+ {
+ // const x: i32 = 9;
+ // var x: Bar;
+ // fn foo(x: bool, y: f32) void {}
+ pattern: RegExp(/(:\s*)(?=\s*(?:\s*)?[=;,)])|(?=\s*(?:\s*)?\{)/.source.replace(//g, literal(TYPE)).replace(//g, literal(ALIGN))),
+ lookbehind: true,
+ inside: null // see below
+ },
+ {
+ // extern fn foo(x: f64) f64; (optional alignment)
+ pattern: RegExp(/(\)\s*)(?=\s*(?:\s*)?;)/.source.replace(//g, literal(TYPE)).replace(//g, literal(ALIGN))),
+ lookbehind: true,
+ inside: null // see below
+ }
+ ],
+ 'builtin-type': {
+ pattern: /\b(?:anyerror|bool|c_u?(?:int|long|longlong|short)|c_longdouble|c_void|comptime_(?:float|int)|f(?:16|32|64|128)|[iu](?:8|16|32|64|128|size)|noreturn|type|void)\b/,
+ alias: 'keyword'
+ },
+ 'keyword': keyword,
+ 'function': /\b(?!\d)\w+(?=\s*\()/,
+ 'number': /\b(?:0b[01]+|0o[0-7]+|0x[a-fA-F\d]+(?:\.[a-fA-F\d]*)?(?:[pP][+-]?[a-fA-F\d]+)?|\d+(?:\.\d*)?(?:[eE][+-]?\d+)?)\b/,
+ 'boolean': /\b(?:false|true)\b/,
+ 'operator': /\.[*?]|\.{2,3}|[-=]>|\*\*|\+\+|\|\||(?:<<|>>|[-+*]%|[-+*/%^&|<>!=])=?|[?~]/,
+ 'punctuation': /[.:,;(){}[\]]/
+ };
+
+ Prism.languages.zig['class-name'].forEach(function (obj) {
+ if (obj.inside === null) {
+ obj.inside = Prism.languages.zig;
+ }
+ });
+
+}(Prism));
+
diff --git a/lib/docs/filters/zig/clean_html.rb b/lib/docs/filters/zig/clean_html.rb
new file mode 100644
index 00000000..df2601f8
--- /dev/null
+++ b/lib/docs/filters/zig/clean_html.rb
@@ -0,0 +1,19 @@
+module Docs
+ class Zig
+ class CleanHtmlFilter < Filter
+ def call
+ at_css('main').prepend_child at_css('h1')
+ @doc = at_css('main')
+ css('a.hdr').remove
+ css('h1, h2, h3').each do |node|
+ node.content = node.content
+ end
+ css('pre > code').each do |node|
+ node.parent['data-language'] = 'zig'
+ node.parent.content = node.parent.content
+ end
+ doc
+ end
+ end
+ end
+end
diff --git a/lib/docs/filters/zig/entries.rb b/lib/docs/filters/zig/entries.rb
new file mode 100644
index 00000000..73979b01
--- /dev/null
+++ b/lib/docs/filters/zig/entries.rb
@@ -0,0 +1,25 @@
+module Docs
+ class Zig
+ class EntriesFilter < Docs::EntriesFilter
+ def additional_entries
+ entries = []
+ type = nil
+ subtype = nil
+
+ css('h2, h3').each do |node|
+ if node.name == 'h2' && node['id']
+ type = node.content.gsub(/ §/, '')
+ subtype = nil
+ entries << [type, node['id'], type]
+ elsif node.name == 'h3' && node['id']
+ subtype = node.content.gsub(/ §/, '')
+ name = "#{type}: #{subtype}"
+ entries << [name, node['id'], type]
+ end
+ end
+
+ entries
+ end
+ end
+ end
+end
diff --git a/lib/docs/scrapers/zig.rb b/lib/docs/scrapers/zig.rb
new file mode 100644
index 00000000..004b8757
--- /dev/null
+++ b/lib/docs/scrapers/zig.rb
@@ -0,0 +1,24 @@
+module Docs
+ class Zig < UrlScraper
+ self.name = 'Zig'
+ self.type = 'simple'
+ self.release = '0.9.0'
+ self.base_url = 'https://ziglang.org/documentation/0.9.0/'
+ self.links = {
+ home: 'https://ziglang.org/',
+ code: 'https://github.com/ziglang/zig'
+ }
+
+ html_filters.push 'zig/entries', 'zig/clean_html'
+
+ options[:follow_links] = false
+ options[:attribution] = <<-HTML
+ © 2015–2021, Zig contributors
+ HTML
+
+ def get_latest_version(opts)
+ tags = get_github_tags('ziglang', 'zig', opts)
+ tags[0]['name']
+ end
+ end
+end
diff --git a/public/icons/docs/zig/16.png b/public/icons/docs/zig/16.png
new file mode 100644
index 00000000..67a96b5b
Binary files /dev/null and b/public/icons/docs/zig/16.png differ
diff --git a/public/icons/docs/zig/16@2x.png b/public/icons/docs/zig/16@2x.png
new file mode 100644
index 00000000..3b9d9ef2
Binary files /dev/null and b/public/icons/docs/zig/16@2x.png differ
diff --git a/public/icons/docs/zig/SOURCE b/public/icons/docs/zig/SOURCE
new file mode 100644
index 00000000..9b31c377
--- /dev/null
+++ b/public/icons/docs/zig/SOURCE
@@ -0,0 +1,2 @@
+https://github.com/ziglang/logo/blob/master/zig-favicon.png
+https://github.com/ziglang/logo/blob/master/zig-mark.svg