Ruby/ERB: Fixed block comments (#1768) This fixes block comments in Ruby and ERB.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
diff --git a/components/prism-erb.js b/components/prism-erb.js
index 8eccbb9..5e58528 100644
--- a/components/prism-erb.js
+++ b/components/prism-erb.js
@@ -9,7 +9,7 @@
});
Prism.hooks.add('before-tokenize', function(env) {
- var erbPattern = /<%=?[\s\S]+?%>/g;
+ var erbPattern = /<%=?(?:[^\r\n]|[\r\n](?!=begin)|[\r\n]=begin\s[\s\S]*?^=end)+?%>/gm;
Prism.languages['markup-templating'].buildPlaceholders(env, 'erb', erbPattern);
});
@@ -17,4 +17,4 @@
Prism.languages['markup-templating'].tokenizePlaceholders(env, 'erb');
});
-}(Prism));
\ No newline at end of file
+}(Prism));
diff --git a/components/prism-erb.min.js b/components/prism-erb.min.js
index c511318..ed22abd 100644
--- a/components/prism-erb.min.js
+++ b/components/prism-erb.min.js
@@ -1 +1 @@
-!function(e){e.languages.erb=e.languages.extend("ruby",{}),e.languages.insertBefore("erb","comment",{delimiter:{pattern:/^<%=?|%>$/,alias:"punctuation"}}),e.hooks.add("before-tokenize",function(a){var n=/<%=?[\s\S]+?%>/g;e.languages["markup-templating"].buildPlaceholders(a,"erb",n)}),e.hooks.add("after-tokenize",function(a){e.languages["markup-templating"].tokenizePlaceholders(a,"erb")})}(Prism);
\ No newline at end of file
+!function(e){e.languages.erb=e.languages.extend("ruby",{}),e.languages.insertBefore("erb","comment",{delimiter:{pattern:/^<%=?|%>$/,alias:"punctuation"}}),e.hooks.add("before-tokenize",function(n){var a=/<%=?(?:[^\r\n]|[\r\n](?!=begin)|[\r\n]=begin\s[\s\S]*?^=end)+?%>/gm;e.languages["markup-templating"].buildPlaceholders(n,"erb",a)}),e.hooks.add("after-tokenize",function(n){e.languages["markup-templating"].tokenizePlaceholders(n,"erb")})}(Prism);
\ No newline at end of file
diff --git a/components/prism-ruby.js b/components/prism-ruby.js
index 13e43f1..b1a2e10 100644
--- a/components/prism-ruby.js
+++ b/components/prism-ruby.js
@@ -9,7 +9,7 @@
'comment': [
/#.*/,
{
- pattern: /^=begin(?:\r?\n|\r)(?:.*(?:\r?\n|\r))*?=end/m,
+ pattern: /^=begin\s[\s\S]*?^=end/m,
greedy: true
}
],
diff --git a/components/prism-ruby.min.js b/components/prism-ruby.min.js
index 2976e90..d15aab8 100644
--- a/components/prism-ruby.min.js
+++ b/components/prism-ruby.min.js
@@ -1 +1 @@
-!function(e){e.languages.ruby=e.languages.extend("clike",{comment:[/#.*/,{pattern:/^=begin(?:\r?\n|\r)(?:.*(?:\r?\n|\r))*?=end/m,greedy:!0}],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|protected|private|public|raise|redo|require|rescue|retry|return|self|super|then|throw|true|undef|unless|until|when|while|yield)\b/});var n={pattern:/#\{[^}]+\}/,inside:{delimiter:{pattern:/^#\{|\}$/,alias:"tag"},rest:e.languages.ruby}};delete e.languages.ruby.function,e.languages.insertBefore("ruby","keyword",{regex:[{pattern:/%r([^a-zA-Z0-9\s{(\[<])(?:(?!\1)[^\\]|\\[\s\S])*\1[gim]{0,3}/,greedy:!0,inside:{interpolation:n}},{pattern:/%r\((?:[^()\\]|\\[\s\S])*\)[gim]{0,3}/,greedy:!0,inside:{interpolation:n}},{pattern:/%r\{(?:[^#{}\\]|#(?:\{[^}]+\})?|\\[\s\S])*\}[gim]{0,3}/,greedy:!0,inside:{interpolation:n}},{pattern:/%r\[(?:[^\[\]\\]|\\[\s\S])*\][gim]{0,3}/,greedy:!0,inside:{interpolation:n}},{pattern:/%r<(?:[^<>\\]|\\[\s\S])*>[gim]{0,3}/,greedy:!0,inside:{interpolation:n}},{pattern:/(^|[^\/])\/(?!\/)(\[.+?]|\\.|[^\/\\\r\n])+\/[gim]{0,3}(?=\s*($|[\r\n,.;})]))/,lookbehind:!0,greedy:!0}],variable:/[@$]+[a-zA-Z_]\w*(?:[?!]|\b)/,symbol:{pattern:/(^|[^:]):[a-zA-Z_]\w*(?:[?!]|\b)/,lookbehind:!0},"method-definition":{pattern:/(\bdef\s+)[\w.]+/,lookbehind:!0,inside:{"function":/\w+$/,rest:e.languages.ruby}}}),e.languages.insertBefore("ruby","number",{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/,constant:/\b[A-Z]\w*(?:[?!]|\b)/}),e.languages.ruby.string=[{pattern:/%[qQiIwWxs]?([^a-zA-Z0-9\s{(\[<])(?:(?!\1)[^\\]|\\[\s\S])*\1/,greedy:!0,inside:{interpolation:n}},{pattern:/%[qQiIwWxs]?\((?:[^()\\]|\\[\s\S])*\)/,greedy:!0,inside:{interpolation:n}},{pattern:/%[qQiIwWxs]?\{(?:[^#{}\\]|#(?:\{[^}]+\})?|\\[\s\S])*\}/,greedy:!0,inside:{interpolation:n}},{pattern:/%[qQiIwWxs]?\[(?:[^\[\]\\]|\\[\s\S])*\]/,greedy:!0,inside:{interpolation:n}},{pattern:/%[qQiIwWxs]?<(?:[^<>\\]|\\[\s\S])*>/,greedy:!0,inside:{interpolation:n}},{pattern:/("|')(?:#\{[^}]+\}|\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0,inside:{interpolation:n}}],e.languages.rb=e.languages.ruby}(Prism);
\ No newline at end of file
+!function(e){e.languages.ruby=e.languages.extend("clike",{comment:[/#.*/,{pattern:/^=begin\s[\s\S]*?^=end/m,greedy:!0}],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|protected|private|public|raise|redo|require|rescue|retry|return|self|super|then|throw|true|undef|unless|until|when|while|yield)\b/});var n={pattern:/#\{[^}]+\}/,inside:{delimiter:{pattern:/^#\{|\}$/,alias:"tag"},rest:e.languages.ruby}};delete e.languages.ruby.function,e.languages.insertBefore("ruby","keyword",{regex:[{pattern:/%r([^a-zA-Z0-9\s{(\[<])(?:(?!\1)[^\\]|\\[\s\S])*\1[gim]{0,3}/,greedy:!0,inside:{interpolation:n}},{pattern:/%r\((?:[^()\\]|\\[\s\S])*\)[gim]{0,3}/,greedy:!0,inside:{interpolation:n}},{pattern:/%r\{(?:[^#{}\\]|#(?:\{[^}]+\})?|\\[\s\S])*\}[gim]{0,3}/,greedy:!0,inside:{interpolation:n}},{pattern:/%r\[(?:[^\[\]\\]|\\[\s\S])*\][gim]{0,3}/,greedy:!0,inside:{interpolation:n}},{pattern:/%r<(?:[^<>\\]|\\[\s\S])*>[gim]{0,3}/,greedy:!0,inside:{interpolation:n}},{pattern:/(^|[^\/])\/(?!\/)(\[.+?]|\\.|[^\/\\\r\n])+\/[gim]{0,3}(?=\s*($|[\r\n,.;})]))/,lookbehind:!0,greedy:!0}],variable:/[@$]+[a-zA-Z_]\w*(?:[?!]|\b)/,symbol:{pattern:/(^|[^:]):[a-zA-Z_]\w*(?:[?!]|\b)/,lookbehind:!0},"method-definition":{pattern:/(\bdef\s+)[\w.]+/,lookbehind:!0,inside:{"function":/\w+$/,rest:e.languages.ruby}}}),e.languages.insertBefore("ruby","number",{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/,constant:/\b[A-Z]\w*(?:[?!]|\b)/}),e.languages.ruby.string=[{pattern:/%[qQiIwWxs]?([^a-zA-Z0-9\s{(\[<])(?:(?!\1)[^\\]|\\[\s\S])*\1/,greedy:!0,inside:{interpolation:n}},{pattern:/%[qQiIwWxs]?\((?:[^()\\]|\\[\s\S])*\)/,greedy:!0,inside:{interpolation:n}},{pattern:/%[qQiIwWxs]?\{(?:[^#{}\\]|#(?:\{[^}]+\})?|\\[\s\S])*\}/,greedy:!0,inside:{interpolation:n}},{pattern:/%[qQiIwWxs]?\[(?:[^\[\]\\]|\\[\s\S])*\]/,greedy:!0,inside:{interpolation:n}},{pattern:/%[qQiIwWxs]?<(?:[^<>\\]|\\[\s\S])*>/,greedy:!0,inside:{interpolation:n}},{pattern:/("|')(?:#\{[^}]+\}|\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0,inside:{interpolation:n}}],e.languages.rb=e.languages.ruby}(Prism);
\ No newline at end of file
diff --git a/tests/languages/erb/issue1767.test b/tests/languages/erb/issue1767.test
new file mode 100644
index 0000000..6a5a1f2
--- /dev/null
+++ b/tests/languages/erb/issue1767.test
@@ -0,0 +1,56 @@
+<%# this is a block comment %>
+<%
+=begin %>
+ block comment
+ (both lines of both the begin and end tags must be at the start of their lines)
+<%
+=end %>
+
+<%# this is not %>
+ <%
+ =begin %>
+ not a comment
+ <%
+ =end %>
+
+----------------------------------------------------
+
+[
+ ["erb", [
+ ["delimiter", "<%"],
+ ["comment", "# this is a block comment "],
+ ["delimiter", "%>"]
+ ]],
+
+ ["erb", [
+ ["delimiter", "<%"],
+ ["comment", "=begin %>\n\tblock comment\n\t(both lines of both the begin and end tags must be at the start of their lines)\n<%\n=end"],
+ ["delimiter", "%>"]
+ ]],
+
+ ["erb", [
+ ["delimiter", "<%"],
+ ["comment", "# this is not "],
+ ["delimiter", "%>"]
+ ]],
+
+ ["erb", [
+ ["delimiter", "<%"],
+ ["operator", "="],
+ ["keyword", "begin"],
+ ["delimiter", "%>"]
+ ]],
+
+ "\n\tnot a comment\n\t",
+
+ ["erb", [
+ ["delimiter", "<%"],
+ ["operator", "="],
+ ["keyword", "end"],
+ ["delimiter", "%>"]
+ ]]
+]
+
+----------------------------------------------------
+
+Checks for block comments (#1767).
diff --git a/tests/languages/ruby/comment_feature.test b/tests/languages/ruby/comment_feature.test
index c41478e..7e06166 100644
--- a/tests/languages/ruby/comment_feature.test
+++ b/tests/languages/ruby/comment_feature.test
@@ -5,6 +5,8 @@ foo bar baz
=end
=begin
=end
+=begin foo
+=end
#{comment}
----------------------------------------------------
@@ -14,9 +16,10 @@ foo bar baz
["comment", "# foobar"],
["comment", "=begin\r\nfoo bar baz\r\n=end"],
["comment", "=begin\r\n=end"],
+ ["comment", "=begin foo\r\n=end"],
["comment", "#{comment}"]
]
----------------------------------------------------
-Checks for comments.
\ No newline at end of file
+Checks for comments.