Skip to content

Commit

Permalink
Groovy: Added string interpolation without hook (#3366)
Browse files Browse the repository at this point in the history
  • Loading branch information
RunDevelopment committed Mar 17, 2022
1 parent 1c533f4 commit 5617765
Show file tree
Hide file tree
Showing 6 changed files with 213 additions and 182 deletions.
113 changes: 55 additions & 58 deletions components/prism-groovy.js
@@ -1,68 +1,65 @@
Prism.languages.groovy = Prism.languages.extend('clike', {
'string': [
{
(function (Prism) {

var interpolation = {
pattern: /((?:^|[^\\$])(?:\\{2})*)\$(?:\w+|\{[^{}]*\})/,
lookbehind: true,
inside: {
'interpolation-punctuation': {
pattern: /^\$\{?|\}$/,
alias: 'punctuation'
},
'expression': {
pattern: /[\s\S]+/,
inside: null // see below
}
}
};

Prism.languages.groovy = Prism.languages.extend('clike', {
'string': {
// https://groovy-lang.org/syntax.html#_dollar_slashy_string
pattern: /("""|''')(?:[^\\]|\\[\s\S])*?\1|\$\/(?:[^/$]|\$(?:[/$]|(?![/$]))|\/(?!\$))*\/\$/,
pattern: /'''(?:[^\\]|\\[\s\S])*?'''|'(?:\\.|[^\\'\r\n])*'/,
greedy: true
},
{
'keyword': /\b(?:abstract|as|assert|boolean|break|byte|case|catch|char|class|const|continue|def|default|do|double|else|enum|extends|final|finally|float|for|goto|if|implements|import|in|instanceof|int|interface|long|native|new|package|private|protected|public|return|short|static|strictfp|super|switch|synchronized|this|throw|throws|trait|transient|try|void|volatile|while)\b/,
'number': /\b(?:0b[01_]+|0x[\da-f_]+(?:\.[\da-f_p\-]+)?|[\d_]+(?:\.[\d_]+)?(?:e[+-]?\d+)?)[glidf]?\b/i,
'operator': {
pattern: /(^|[^.])(?:~|==?~?|\?[.:]?|\*(?:[.=]|\*=?)?|\.[@&]|\.\.<|\.\.(?!\.)|-[-=>]?|\+[+=]?|!=?|<(?:<=?|=>?)?|>(?:>>?=?|=)?|&[&=]?|\|[|=]?|\/=?|\^=?|%=?)/,
lookbehind: true
},
'punctuation': /\.+|[{}[\];(),:$]/
});

Prism.languages.insertBefore('groovy', 'string', {
'shebang': {
pattern: /#!.+/,
alias: 'comment',
greedy: true
},
'interpolation-string': {
// TODO: Slash strings (e.g. /foo/) can contain line breaks but this will cause a lot of trouble with
// simple division (see JS regex), so find a fix maybe?
pattern: /(["'/])(?:\\.|(?!\1)[^\\\r\n])*\1/,
greedy: true
pattern: /"""(?:[^\\]|\\[\s\S])*?"""|(["/])(?:\\.|(?!\1)[^\\\r\n])*\1|\$\/(?:[^/$]|\$(?:[/$]|(?![/$]))|\/(?!\$))*\/\$/,
greedy: true,
inside: {
'interpolation': interpolation,
'string': /[\s\S]+/
}
}
],
'keyword': /\b(?:abstract|as|assert|boolean|break|byte|case|catch|char|class|const|continue|def|default|do|double|else|enum|extends|final|finally|float|for|goto|if|implements|import|in|instanceof|int|interface|long|native|new|package|private|protected|public|return|short|static|strictfp|super|switch|synchronized|this|throw|throws|trait|transient|try|void|volatile|while)\b/,
'number': /\b(?:0b[01_]+|0x[\da-f_]+(?:\.[\da-f_p\-]+)?|[\d_]+(?:\.[\d_]+)?(?:e[+-]?\d+)?)[glidf]?\b/i,
'operator': {
pattern: /(^|[^.])(?:~|==?~?|\?[.:]?|\*(?:[.=]|\*=?)?|\.[@&]|\.\.<|\.\.(?!\.)|-[-=>]?|\+[+=]?|!=?|<(?:<=?|=>?)?|>(?:>>?=?|=)?|&[&=]?|\|[|=]?|\/=?|\^=?|%=?)/,
lookbehind: true
},
'punctuation': /\.+|[{}[\];(),:$]/
});

Prism.languages.insertBefore('groovy', 'string', {
'shebang': {
pattern: /#!.+/,
alias: 'comment'
}
});

Prism.languages.insertBefore('groovy', 'punctuation', {
'spock-block': /\b(?:and|cleanup|expect|given|setup|then|when|where):/
});

Prism.languages.insertBefore('groovy', 'function', {
'annotation': {
pattern: /(^|[^.])@\w+/,
lookbehind: true,
alias: 'punctuation'
}
});
});

// Handle string interpolation
Prism.hooks.add('wrap', function (env) {
if (env.language === 'groovy' && env.type === 'string') {
var delimiter = env.content[0];
Prism.languages.insertBefore('groovy', 'punctuation', {
'spock-block': /\b(?:and|cleanup|expect|given|setup|then|when|where):/
});

if (delimiter != "'") {
var pattern = /([^\\])(?:\$(?:\{.*?\}|[\w.]+))/;
if (delimiter === '$') {
pattern = /([^\$])(?:\$(?:\{.*?\}|[\w.]+))/;
}

// To prevent double HTML-encoding we have to decode env.content first
env.content = env.content.replace(/&lt;/g, '<').replace(/&amp;/g, '&');
Prism.languages.insertBefore('groovy', 'function', {
'annotation': {
pattern: /(^|[^.])@\w+/,
lookbehind: true,
alias: 'punctuation'
}
});

env.content = Prism.highlight(env.content, {
'expression': {
pattern: pattern,
lookbehind: true,
inside: Prism.languages.groovy
}
});
interpolation.inside.expression.inside = Prism.languages.groovy;

env.classes.push(delimiter === '/' ? 'regex' : 'gstring');
}
}
});
}(Prism));
2 changes: 1 addition & 1 deletion components/prism-groovy.min.js

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

96 changes: 51 additions & 45 deletions tests/languages/groovy+sas/groovy_inclusion.test
Expand Up @@ -17,57 +17,63 @@ quit;

[
["step", "proc groovy"],
["proc-args",
[
["arg", "classpath"],
["operator", "="],
["arg-value", "cp"],
["punctuation", ";"]
]
],
[
"proc-groovy", [
["comment", "/* Testing a comment */"],
["submit-statement", "submit parseonly"],
[
"groovy", [
["punctuation", ";"],
["keyword", "class"],
["class-name", ["Speaker"]],
["punctuation", "{"],
["keyword", "def"],
["function", "say"],
["punctuation", "("],
" word ",
["punctuation", ")"],
["punctuation", "{"],
"\r\n println ",
["string", "\"----> \\\"${word}\\\"\""],
["punctuation", "}"],
["punctuation", "}"]
]
],
["submit-statement", "endsubmit"],
["punctuation", ";"]
]
],
["proc-args", [
["arg", "classpath"],
["operator", "="],
["arg-value", "cp"],
["punctuation", ";"]
]],
["proc-groovy", [
["comment", "/* Testing a comment */"],

["submit-statement", "submit parseonly"],
["groovy", [
["punctuation", ";"],

["keyword", "class"],
["class-name", ["Speaker"]],
["punctuation", "{"],

["keyword", "def"],
["function", "say"],
["punctuation", "("],
" word ",
["punctuation", ")"],
["punctuation", "{"],

"\r\n println ",
["interpolation-string", [
["string", "\"----> \\\""],
["interpolation", [
["interpolation-punctuation", "${"],
["expression", ["word"]],
["interpolation-punctuation", "}"]
]],
["string", "\\\"\""]
]],

["punctuation", "}"],

["punctuation", "}"]
]],
["submit-statement", "endsubmit"],
["punctuation", ";"]
]],
["step", "quit"],
["punctuation", ";"],

["step", "proc groovy"],
["proc-args",
[
["arg", "classpath"],
["operator", "="],
["arg-value", "cp"],
["punctuation", ";"]
]
],
["proc-groovy",[
["proc-args", [
["arg", "classpath"],
["operator", "="],
["arg-value", "cp"],
["punctuation", ";"]
]],
["proc-groovy", [
["keyword", "eval"],
["string", "\"s = new Speaker(); s.say( \"\"Hi\"\" )\""],
["punctuation", ";"]
]
],
]],
["step", "quit"],
["punctuation", ";"]
]
Expand Down
14 changes: 8 additions & 6 deletions tests/languages/groovy/issue1049.html.test
Expand Up @@ -7,9 +7,11 @@

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

<span class="token string gstring">"&amp;amp;"</span>
<span class="token string gstring">"&amp;amp;&amp;amp;"</span>
<span class="token string gstring">"&amp;lt;"</span>
<span class="token string gstring">"&amp;lt;&amp;lt;"</span>
<span class="token string gstring">"&amp;amp;lt;"</span>
<span class="token string gstring">"&amp;gt;"</span>
<span class="token interpolation-string"><span class="token string">"&amp;amp;"</span></span>
<span class="token interpolation-string">
<span class="token string">"&amp;amp;&amp;amp;"</span>
</span>
<span class="token interpolation-string"><span class="token string">"&amp;lt;"</span></span>
<span class="token interpolation-string"><span class="token string">"&amp;lt;&amp;lt;"</span></span>
<span class="token interpolation-string"><span class="token string">"&amp;amp;lt;"</span></span>
<span class="token interpolation-string"><span class="token string">"&amp;gt;"</span></span>

0 comments on commit 5617765

Please sign in to comment.