Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(handlebars) support for segment-literals and escaped mustaches #2184

Merged
merged 12 commits into from
Oct 15, 2019
Merged
80 changes: 54 additions & 26 deletions src/languages/handlebars.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,63 +6,91 @@ Description: Matcher for Handlebars as well as EmberJS additions.
Website: https://handlebarsjs.com
Category: template
*/
function(hljs) {
function (hljs) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This kind of change just bit me today. :) Although a few of the other languages are also so different.

var BUILT_INS = {'builtin-name': 'each in with if else unless bindattr action collection debugger log outlet template unbound view yield lookup'};
function MUSTACHE_CONTENTS() {
return {
className: 'name',
begin: /[a-zA-Z\.-]+/,

var IDENTIFIER_PLAIN_OR_QUOTED = {
begin: /".*?"|'.*?'|\[.*?\]|\w+/
};

function BLOCK_MUSTACHE_CONTENTS() {
return hljs.inherit(EXPRESSION_OR_HELPER_CALL(), {
className: 'name'
});
}

function BASIC_MUSTACHE_CONTENTS() {
return hljs.inherit(EXPRESSION_OR_HELPER_CALL(), {
// relevance 0 for backward compatibility concerning auto-detection
relevance: 0
});
}

function EXPRESSION_OR_HELPER_CALL() {
return hljs.inherit(IDENTIFIER_PLAIN_OR_QUOTED, {
keywords: BUILT_INS,
starts: {
endsWithParent: true, relevance: 0,
contains: [
hljs.QUOTE_STRING_MODE
]
}
starts: HELPER_PARAMETERS()
});
}

function HELPER_PARAMETERS() {
return {
endsWithParent: true,
relevance: 0,
contains: [
hljs.inherit(IDENTIFIER_PLAIN_OR_QUOTED, {
relevance: 0
})
]
};
}

var ESCAPE_MUSTACHE_WITH_PRECEEDING_BACKSLASH = {begin: /\\\{\{/, skip: true};
var PREVENT_ESCAPE_WITH_ANOTHER_PRECEEDING_BACKSLASH = {begin: /\\\\(?=\{\{)/, skip: true};

return {
aliases: ['hbs', 'html.hbs', 'html.handlebars'],
case_insensitive: true,
subLanguage: 'xml',
contains: [
ESCAPE_MUSTACHE_WITH_PRECEEDING_BACKSLASH,
PREVENT_ESCAPE_WITH_ANOTHER_PRECEEDING_BACKSLASH,
hljs.COMMENT(/\{\{!--/, /--\}\}/),
hljs.COMMENT(/\{\{!/, /\}\}/),
// raw block (open) {{{{raw}}}} verbatim xml {{{{/raw}} {{handlebars}}
{
// open raw block "{{{{raw}}}} content not evaluated {{{{/raw}}}}"
className: 'template-tag',
begin: /\{\{\{\{(?!\/)/, end: /\}\}\}\}/,
contains: [MUSTACHE_CONTENTS()],
starts: {
end: /\{\{\{\{\//,
returnEnd: true,
subLanguage: 'xml'
}
contains: [BLOCK_MUSTACHE_CONTENTS()],
starts: {end: /\{\{\{\{\//, returnEnd: true, subLanguage: 'xml'}
},
// raw block (close)
{
// close raw block
className: 'template-tag',
begin: /\{\{\{\{\//, end: /\}\}\}\}/,
contains: [MUSTACHE_CONTENTS()]
contains: [BLOCK_MUSTACHE_CONTENTS()]
},
// standard blocks {{#block}} ... {{/block}}
{
// open block statement
className: 'template-tag',
begin: /\{\{[#\/]/, end: /\}\}/,
contains: [MUSTACHE_CONTENTS()],
contains: [BLOCK_MUSTACHE_CONTENTS()],
},
// triple mustaches {{{unescapedOutput}}}
{
// template variable or helper-call that is NOT html-escaped
className: 'template-variable',
begin: /\{\{\{/, end: /\}\}\}/,
keywords: BUILT_INS
keywords: BUILT_INS,
contains: [BASIC_MUSTACHE_CONTENTS()]
},
// standard mustaches {{{htmlEscapedOutput}}}
{
// template variable or helper-call that is html-escaped
className: 'template-variable',
begin: /\{\{/, end: /\}\}/,
keywords: BUILT_INS
keywords: BUILT_INS,
contains: [
BASIC_MUSTACHE_CONTENTS()
]
}
]
};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<span class="xml">text </span><span class="hljs-template-tag">{{#<span class="hljs-name">abc</span> abcd.[lite"'ral}}segment] }}</span><span class="xml">a</span><span class="hljs-template-tag">{{/<span class="hljs-name">abc</span>}}</span><span class="xml">

text </span><span class="hljs-template-tag">{{#<span class="hljs-name">abc</span> abcd."lite]'ral}}segment" }}</span><span class="xml">a</span><span class="hljs-template-tag">{{/<span class="hljs-name">abc</span>}}</span><span class="xml">

text </span><span class="hljs-template-tag">{{#<span class="hljs-name">abc</span> abcd.'lite]"ral}}segment' }}</span><span class="xml">a</span><span class="hljs-template-tag">{{/<span class="hljs-name">abc</span>}}</span><span class="xml">

text

</span>
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
text {{#abc abcd.[lite"'ral}}segment] }}a{{/abc}}

text {{#abc abcd."lite]'ral}}segment" }}a{{/abc}}

text {{#abc abcd.'lite]"ral}}segment' }}a{{/abc}}

text

Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<span class="xml">text </span><span class="hljs-template-tag">{{#<span class="hljs-name">[ab}}c]</span> param }}</span><span class="xml">a</span><span class="hljs-template-tag">{{/<span class="hljs-name">[ab}}c]</span>}}</span><span class="xml">

text </span><span class="hljs-template-tag">{{#<span class="hljs-name">'ab}}c'</span> param}}</span><span class="xml">a</span><span class="hljs-template-tag">{{/<span class="hljs-name">'ab}}c'</span>}}</span><span class="xml">

text </span><span class="hljs-template-tag">{{#<span class="hljs-name">"ab}}c"</span> param}}</span><span class="xml">a</span><span class="hljs-template-tag">{{/<span class="hljs-name">"ab}}c"</span>}}</span><span class="xml">

text </span><span class="hljs-template-tag">{{#<span class="hljs-name">""</span> param}}</span><span class="xml">a</span><span class="hljs-template-tag">{{/<span class="hljs-name">""</span>}}</span><span class="xml">

text </span><span class="hljs-template-tag">{{#<span class="hljs-name">''</span> param}}</span><span class="xml">a</span><span class="hljs-template-tag">{{/<span class="hljs-name">''</span>}}</span><span class="xml">

text </span><span class="hljs-template-tag">{{#<span class="hljs-name">[]</span> param}}</span><span class="xml">a</span><span class="hljs-template-tag">{{/<span class="hljs-name">[]</span>}}</span><span class="xml">

text
</span>
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
text {{#[ab}}c] param }}a{{/[ab}}c]}}

text {{#'ab}}c' param}}a{{/'ab}}c'}}

text {{#"ab}}c" param}}a{{/"ab}}c"}}

text {{#"" param}}a{{/""}}

text {{#'' param}}a{{/''}}

text {{#[] param}}a{{/[]}}

text
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<span class="xml">text </span><span class="hljs-template-tag">{{#<span class="hljs-name">abc</span> "lite]'ral}}segment" }}</span><span class="xml">a</span><span class="hljs-template-tag">{{/<span class="hljs-name">abc</span>}}</span><span class="xml">

text </span><span class="hljs-template-tag">{{#<span class="hljs-name">abc</span> 'lite]"ral}}segment' }}</span><span class="xml">a</span><span class="hljs-template-tag">{{/<span class="hljs-name">abc</span>}}</span><span class="xml">

text </span><span class="hljs-template-tag">{{#<span class="hljs-name">abc</span> [lite"'ral}}segment] }}</span><span class="xml">a</span><span class="hljs-template-tag">{{/<span class="hljs-name">abc</span>}}</span><span class="xml">

text
</span>
7 changes: 7 additions & 0 deletions test/markup/handlebars/block-expression-variants-in-param.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
text {{#abc "lite]'ral}}segment" }}a{{/abc}}

text {{#abc 'lite]"ral}}segment' }}a{{/abc}}

text {{#abc [lite"'ral}}segment] }}a{{/abc}}

text
22 changes: 22 additions & 0 deletions test/markup/handlebars/escaped-mustaches.expect.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<span class="xml">\{{no-expression}}

\{{{no-expression}}}

\{{#no}} block \{{/no}}

\{{\{{no}}}} block \{{\{{/no}}}}

\{{!-- no comment --}}

\{{! no comment }}

<span class="hljs-comment">&lt;!-- escaped escapings --&gt;</span>

\\</span><span class="hljs-template-variable">{{expression}}</span><span class="xml">

\\\</span><span class="hljs-template-variable">{{expression}}</span><span class="xml">

\\\\</span><span class="hljs-template-variable">{{expression}}</span><span class="xml">

\\\</span><span class="hljs-comment">{{! comment }}</span><span class="xml">
</span>
21 changes: 21 additions & 0 deletions test/markup/handlebars/escaped-mustaches.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
\{{no-expression}}

\{{{no-expression}}}

\{{#no}} block \{{/no}}

\{{\{{no}}}} block \{{\{{/no}}}}

\{{!-- no comment --}}

\{{! no comment }}

<!-- escaped escapings -->

\\{{expression}}

\\\{{expression}}

\\\\{{expression}}

\\\{{! comment }}
27 changes: 27 additions & 0 deletions test/markup/handlebars/expression-variants.expect.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<span class="xml">text

</span><span class="hljs-template-variable">{{ "lite]'ral}}segment" }}</span><span class="xml"> text

</span><span class="hljs-template-variable">{{ 'lite]"ral}}segment' }}</span><span class="xml"> text

</span><span class="hljs-template-variable">{{ [lite"'ral}}segment] }}</span><span class="xml"> text

</span><span class="hljs-template-variable">{{ abc "lite]'ral}}segment" }}</span><span class="xml"> text

</span><span class="hljs-template-variable">{{ abc 'lite]"ral}}segment' }}</span><span class="xml"> text

</span><span class="hljs-template-variable">{{ abc [lite"'ral}}segment] }}</span><span class="xml"> text


</span><span class="hljs-template-variable">{{ abcd.[lite"'ral}}segment] }}</span><span class="xml"> text

</span><span class="hljs-template-variable">{{ abcd."lite]'ral}}segment" }}</span><span class="xml"> text

</span><span class="hljs-template-variable">{{ abcd.'lite]"ral}}segment' }}</span><span class="xml"> text

</span><span class="hljs-template-variable">{{ abcd.''}}</span><span class="xml"> text

</span><span class="hljs-template-variable">{{ abcd."" }}</span><span class="xml"> text

</span><span class="hljs-template-variable">{{ abcd.[] }}</span><span class="xml"> text
</span>
26 changes: 26 additions & 0 deletions test/markup/handlebars/expression-variants.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
text

{{ "lite]'ral}}segment" }} text

{{ 'lite]"ral}}segment' }} text

{{ [lite"'ral}}segment] }} text

{{ abc "lite]'ral}}segment" }} text

{{ abc 'lite]"ral}}segment' }} text

{{ abc [lite"'ral}}segment] }} text


{{ abcd.[lite"'ral}}segment] }} text

{{ abcd."lite]'ral}}segment" }} text

{{ abcd.'lite]"ral}}segment' }} text

{{ abcd.''}} text

{{ abcd."" }} text

{{ abcd.[] }} text