Ruby: Added heredoc literals (#2885)

Adds support for heredoc-style string literals in the Ruby syntax.

https://ruby-doc.org/core-2.7.0/doc/syntax/literals_rdoc.html#label-Here+Documents+-28heredocs-29

This isn't perfect, but it's a good start.
This commit is contained in:
Samuel Cochran 2021-05-14 21:04:43 +08:00 committed by GitHub
parent 74edb4e5f6
commit 20b77bffa4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 123 additions and 3 deletions

View File

@ -102,6 +102,35 @@
inside: {
'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': /^<<[-~]?/
}
},
'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': /^<<[-~]?'|'$/,
}
}
}
}
];

View File

@ -1 +1 @@
!function(e){e.languages.ruby=e.languages.extend("clike",{comment:[/#.*/,{pattern:/^=begin\s[\s\S]*?^=end/m,greedy:!0}],"class-name":{pattern:/(\b(?:class)\s+|\bcatch\s+\()[\w.\\]+/i,lookbehind:!0,inside:{punctuation:/[.\\]/}},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/});var n={pattern:/#\{[^}]+\}/,inside:{delimiter:{pattern:/^#\{|\}$/,alias:"tag"},rest:e.languages.ruby}};delete e.languages.ruby.function,e.languages.insertBefore("ruby","keyword",{regex:[{pattern:RegExp("%r(?:"+["([^a-zA-Z0-9\\s{(\\[<])(?:(?!\\1)[^\\\\]|\\\\[^])*\\1","\\((?:[^()\\\\]|\\\\[^])*\\)","\\{(?:[^#{}\\\\]|#(?:\\{[^}]+\\})?|\\\\[^])*\\}","\\[(?:[^\\[\\]\\\\]|\\\\[^])*\\]","<(?:[^<>\\\\]|\\\\[^])*>"].join("|")+")[egimnosux]{0,6}"),greedy:!0,inside:{interpolation:n}},{pattern:/(^|[^/])\/(?!\/)(?:\[[^\r\n\]]+\]|\\.|[^[/\\\r\n])+\/[egimnosux]{0,6}(?=\s*(?:$|[\r\n,.;})#]))/,lookbehind:!0,greedy:!0,inside:{interpolation:n}}],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:RegExp("%[qQiIwWxs]?(?:"+["([^a-zA-Z0-9\\s{(\\[<])(?:(?!\\1)[^\\\\]|\\\\[^])*\\1","\\((?:[^()\\\\]|\\\\[^])*\\)","\\{(?:[^#{}\\\\]|#(?:\\{[^}]+\\})?|\\\\[^])*\\}","\\[(?:[^\\[\\]\\\\]|\\\\[^])*\\]","<(?:[^<>\\\\]|\\\\[^])*>"].join("|")+")"),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);
!function(e){e.languages.ruby=e.languages.extend("clike",{comment:[/#.*/,{pattern:/^=begin\s[\s\S]*?^=end/m,greedy:!0}],"class-name":{pattern:/(\b(?:class)\s+|\bcatch\s+\()[\w.\\]+/i,lookbehind:!0,inside:{punctuation:/[.\\]/}},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/});var n={pattern:/#\{[^}]+\}/,inside:{delimiter:{pattern:/^#\{|\}$/,alias:"tag"},rest:e.languages.ruby}};delete e.languages.ruby.function,e.languages.insertBefore("ruby","keyword",{regex:[{pattern:RegExp("%r(?:"+["([^a-zA-Z0-9\\s{(\\[<])(?:(?!\\1)[^\\\\]|\\\\[^])*\\1","\\((?:[^()\\\\]|\\\\[^])*\\)","\\{(?:[^#{}\\\\]|#(?:\\{[^}]+\\})?|\\\\[^])*\\}","\\[(?:[^\\[\\]\\\\]|\\\\[^])*\\]","<(?:[^<>\\\\]|\\\\[^])*>"].join("|")+")[egimnosux]{0,6}"),greedy:!0,inside:{interpolation:n}},{pattern:/(^|[^/])\/(?!\/)(?:\[[^\r\n\]]+\]|\\.|[^[/\\\r\n])+\/[egimnosux]{0,6}(?=\s*(?:$|[\r\n,.;})#]))/,lookbehind:!0,greedy:!0,inside:{interpolation:n}}],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:RegExp("%[qQiIwWxs]?(?:"+["([^a-zA-Z0-9\\s{(\\[<])(?:(?!\\1)[^\\\\]|\\\\[^])*\\1","\\((?:[^()\\\\]|\\\\[^])*\\)","\\{(?:[^#{}\\\\]|#(?:\\{[^}]+\\})?|\\\\[^])*\\}","\\[(?:[^\\[\\]\\\\]|\\\\[^])*\\]","<(?:[^<>\\\\]|\\\\[^])*>"].join("|")+")"),greedy:!0,inside:{interpolation:n}},{pattern:/("|')(?:#\{[^}]+\}|#(?!\{)|\\(?:\r\n|[\s\S])|(?!\1)[^\\#\r\n])*\1/,greedy:!0,inside:{interpolation:n}},{pattern:/<<[-~]?([a-z_]\w*)[\r\n](?:.*[\r\n])*?[\t ]*\1/i,alias:"heredoc-string",greedy:!0,inside:{delimiter:{pattern:/^<<[-~]?[a-z_]\w*|[a-z_]\w*$/i,alias:"symbol",inside:{punctuation:/^<<[-~]?/}},interpolation:n}},{pattern:/<<[-~]?'([a-z_]\w*)'[\r\n](?:.*[\r\n])*?[\t ]*\1/i,alias:"heredoc-string",greedy:!0,inside:{delimiter:{pattern:/^<<[-~]?'[a-z_]\w*'|[a-z_]\w*$/i,alias:"symbol",inside:{punctuation:/^<<[-~]?'|'$/}}}}],e.languages.rb=e.languages.ruby}(Prism);

View File

@ -7,7 +7,10 @@ comment
<h2>Strings</h2>
<pre><code>"foo \"bar\" baz"
'foo \'bar\' baz'</code></pre>
'foo \'bar\' baz'
&lt;&lt;STRING
here's some #{string} contents
STRING</code></pre>
<h2>Regular expressions</h2>
<pre><code>/foo?[ ]*bar/</code></pre>

View File

@ -36,6 +36,25 @@ bar"
%x[foo #{ 42 }]
%x<foo #{ 42 }>
<<STRING
foo #{42} bar
STRING
<<-STRING
foo #{42} bar
STRING
<<~STRING
foo #{42} bar
STRING
<<'STRING'
foo #{42} bar
STRING
<<-'STRING'
foo #{42} bar
STRING
<<~'STRING'
foo #{42} bar
STRING
----------------------------------------------------
[
@ -279,9 +298,78 @@ bar"
["delimiter", "}"]
]],
">"
]],
["string", [
["delimiter", [
["punctuation", "<<"],
"STRING"
]],
"\r\n foo ",
["interpolation", [
["delimiter", "#{"],
["number", "42"],
["delimiter", "}"]
]],
" bar\r\n",
["delimiter", ["STRING"]]
]],
["string", [
["delimiter", [
["punctuation", "<<-"],
"STRING"
]],
"\r\n foo ",
["interpolation", [
["delimiter", "#{"],
["number", "42"],
["delimiter", "}"]
]],
" bar\r\n ",
["delimiter", ["STRING"]]
]],
["string", [
["delimiter", [
["punctuation", "<<~"],
"STRING"
]],
"\r\n foo ",
["interpolation", [
["delimiter", "#{"],
["number", "42"],
["delimiter", "}"]
]],
" bar\r\n ",
["delimiter", ["STRING"]]
]],
["string", [
["delimiter", [
["punctuation", "<<'"],
"STRING",
["punctuation", "'"]
]],
"\r\n foo #{42} bar\r\n",
["delimiter", ["STRING"]]
]],
["string", [
["delimiter", [
["punctuation", "<<-'"],
"STRING",
["punctuation", "'"]
]],
"\r\n foo #{42} bar\r\n ",
["delimiter", ["STRING"]]
]],
["string", [
["delimiter", [
["punctuation", "<<~'"],
"STRING",
["punctuation", "'"]
]],
"\r\n foo #{42} bar\r\n ",
["delimiter", ["STRING"]]
]]
]
----------------------------------------------------
Checks for strings and string interpolation.
Checks for strings and string interpolation.