From c805f85987702a19cb1e935d09fc15bcf4868cc9 Mon Sep 17 00:00:00 2001 From: Michael Schmidt Date: Tue, 5 Mar 2019 16:56:13 +0100 Subject: [PATCH] Ruby/ERB: Fixed block comments (#1768) This fixes block comments in Ruby and ERB. --- components/prism-erb.js | 4 +- components/prism-erb.min.js | 2 +- components/prism-ruby.js | 2 +- components/prism-ruby.min.js | 2 +- tests/languages/erb/issue1767.test | 56 +++++++++++++++++++++++ tests/languages/ruby/comment_feature.test | 5 +- 6 files changed, 65 insertions(+), 6 deletions(-) create mode 100644 tests/languages/erb/issue1767.test diff --git a/components/prism-erb.js b/components/prism-erb.js index 8eccbb917d..5e58528b3a 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 c5113182e3..ed22abd662 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 13e43f1d61..b1a2e10a29 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 2976e90e9e..d15aab8316 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 0000000000..6a5a1f2cc3 --- /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 c41478e841..7e0616672c 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.