Skip to content

Commit

Permalink
Ruby: Add % notations for strings and regexps. Fix #590
Browse files Browse the repository at this point in the history
  • Loading branch information
Golmote committed Sep 3, 2015
1 parent 9bae186 commit 2d37800
Show file tree
Hide file tree
Showing 4 changed files with 381 additions and 40 deletions.
126 changes: 98 additions & 28 deletions components/prism-ruby.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,37 +4,107 @@
* Adds the following new token classes:
* constant, builtin, variable, symbol, regex
*/
Prism.languages.ruby = Prism.languages.extend('clike', {
'comment': /#(?!\{[^\r\n]*?\}).*/,
'keyword': /\b(alias|and|BEGIN|begin|break|case|class|def|define_method|defined|do|each|else|elsif|END|end|ensure|false|for|if|in|module|new|next|nil|not|or|raise|redo|require|rescue|retry|return|self|super|then|throw|true|undef|unless|until|when|while|yield)\b/
});
(function(Prism) {
Prism.languages.ruby = Prism.languages.extend('clike', {
'comment': /#(?!\{[^\r\n]*?\}).*/,
'keyword': /\b(alias|and|BEGIN|begin|break|case|class|def|define_method|defined|do|each|else|elsif|END|end|ensure|false|for|if|in|module|new|next|nil|not|or|raise|redo|require|rescue|retry|return|self|super|then|throw|true|undef|unless|until|when|while|yield)\b/
});

Prism.languages.insertBefore('ruby', 'keyword', {
'regex': {
pattern: /(^|[^/])\/(?!\/)(\[.+?]|\\.|[^/\r\n])+\/[gim]{0,3}(?=\s*($|[\r\n,.;})]))/,
lookbehind: true
},
'variable': /[@$]+[a-zA-Z_][a-zA-Z_0-9]*(?:[?!]|\b)/,
'symbol': /:[a-zA-Z_][a-zA-Z_0-9]*(?:[?!]|\b)/
});
var interpolation = {
pattern: /#\{[^}]+\}/,
inside: {
'delimiter': {
pattern: /^#\{|\}$/,
alias: 'tag'
},
rest: Prism.util.clone(Prism.languages.ruby)
}
};

Prism.languages.insertBefore('ruby', 'keyword', {
'regex': [
{
pattern: /%r([^a-zA-Z0-9\s\{\(\[<])(?:[^\\]|\\[\s\S])*?\1[gim]{0,3}/,
inside: {
'interpolation': interpolation
}
},
{
pattern: /%r\((?:[^()\\]|\\[\s\S])*\)[gim]{0,3}/,
inside: {
'interpolation': interpolation
}
},
{
// Here we need to specifically allow interpolation
pattern: /%r\{(?:[^#{}\\]|#(?:\{[^}]+\})?|\\[\s\S])*\}[gim]{0,3}/,
inside: {
'interpolation': interpolation
}
},
{
pattern: /%r\[(?:[^\[\]\\]|\\[\s\S])*\][gim]{0,3}/,
inside: {
'interpolation': interpolation
}
},
{
pattern: /%r<(?:[^<>\\]|\\[\s\S])*>[gim]{0,3}/,
inside: {
'interpolation': interpolation
}
},
{
pattern: /(^|[^/])\/(?!\/)(\[.+?]|\\.|[^/\r\n])+\/[gim]{0,3}(?=\s*($|[\r\n,.;})]))/,
lookbehind: true
}
],
'variable': /[@$]+[a-zA-Z_][a-zA-Z_0-9]*(?:[?!]|\b)/,
'symbol': /:[a-zA-Z_][a-zA-Z_0-9]*(?:[?!]|\b)/
});

Prism.languages.insertBefore('ruby', 'number', {
'builtin': /\b(Array|Bignum|Binding|Class|Continuation|Dir|Exception|FalseClass|File|Stat|File|Fixnum|Fload|Hash|Integer|IO|MatchData|Method|Module|NilClass|Numeric|Object|Proc|Range|Regexp|String|Struct|TMS|Symbol|ThreadGroup|Thread|Time|TrueClass)\b/,
'constant': /\b[A-Z][a-zA-Z_0-9]*(?:[?!]|\b)/
});
Prism.languages.insertBefore('ruby', 'number', {
'builtin': /\b(Array|Bignum|Binding|Class|Continuation|Dir|Exception|FalseClass|File|Stat|File|Fixnum|Fload|Hash|Integer|IO|MatchData|Method|Module|NilClass|Numeric|Object|Proc|Range|Regexp|String|Struct|TMS|Symbol|ThreadGroup|Thread|Time|TrueClass)\b/,
'constant': /\b[A-Z][a-zA-Z_0-9]*(?:[?!]|\b)/
});

Prism.languages.ruby.string = {
pattern: /("|')(#\{[^}]+\}|\\(?:\r?\n|\r)|\\?.)*?\1/,
inside: {
'interpolation': {
pattern: /#\{[^}]+\}/,
Prism.languages.ruby.string = [
{
pattern: /%[qQiIwWxs]?([^a-zA-Z0-9\s\{\(\[<])(?:[^\\]|\\[\s\S])*?\1/,
inside: {
'interpolation': interpolation
}
},
{
pattern: /%[qQiIwWxs]?\((?:[^()\\]|\\[\s\S])*\)/,
inside: {
'interpolation': interpolation
}
},
{
// Here we need to specifically allow interpolation
pattern: /%[qQiIwWxs]?\{(?:[^#{}\\]|#(?:\{[^}]+\})?|\\[\s\S])*\}/,
inside: {
'interpolation': interpolation
}
},
{
pattern: /%[qQiIwWxs]?\[(?:[^\[\]\\]|\\[\s\S])*\]/,
inside: {
'interpolation': interpolation
}
},
{
pattern: /%[qQiIwWxs]?<(?:[^<>\\]|\\[\s\S])*>/,
inside: {
'interpolation': interpolation
}
},
{
pattern: /("|')(#\{[^}]+\}|\\(?:\r?\n|\r)|\\?.)*?\1/,
inside: {
'delimiter': {
pattern: /^#\{|\}$/,
alias: 'tag'
},
rest: Prism.util.clone(Prism.languages.ruby)
'interpolation': interpolation
}
}
}
};
];
}(Prism));
2 changes: 1 addition & 1 deletion components/prism-ruby.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

32 changes: 31 additions & 1 deletion tests/languages/ruby/regex_feature.test
Original file line number Diff line number Diff line change
@@ -1,13 +1,43 @@
/[foo]\/bar/gim
/[bar]/,
/./i;
%r!foo?bar#{39+3}!
%r(foo?bar#{39+3})
%r{foo?bar#{39+3}}
%r[foo?bar#{39+3}]
%r<foo?bar#{39+3}>

----------------------------------------------------

[
["regex", "/[foo]\\/bar/gim"],
["regex", "/[bar]/"], ["punctuation", ","],
["regex", "/./i"], ["punctuation", ";"]
["regex", "/./i"], ["punctuation", ";"],
["regex", ["%r!foo?bar", ["interpolation", [
["delimiter", "#{"],
["number", "39"], ["operator", "+"], ["number", "3"],
["delimiter", "}"]
]], "!"]],
["regex", ["%r(foo?bar", ["interpolation", [
["delimiter", "#{"],
["number", "39"], ["operator", "+"], ["number", "3"],
["delimiter", "}"]
]], ")"]],
["regex", ["%r{foo?bar", ["interpolation", [
["delimiter", "#{"],
["number", "39"], ["operator", "+"], ["number", "3"],
["delimiter", "}"]
]], "}"]],
["regex", ["%r[foo?bar", ["interpolation", [
["delimiter", "#{"],
["number", "39"], ["operator", "+"], ["number", "3"],
["delimiter", "}"]
]], "]"]],
["regex", ["%r<foo?bar", ["interpolation", [
["delimiter", "#{"],
["number", "39"], ["operator", "+"], ["number", "3"],
["delimiter", "}"]
]], ">"]]
]

----------------------------------------------------
Expand Down
Loading

0 comments on commit 2d37800

Please sign in to comment.