Skip to content

Commit

Permalink
(handlebars) support for segment-literals and escaped mustaches (#2184)
Browse files Browse the repository at this point in the history
  • Loading branch information
nknapp authored and joshgoebel committed Oct 15, 2019
1 parent e859d30 commit bdf87d2
Show file tree
Hide file tree
Showing 11 changed files with 209 additions and 26 deletions.
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) {
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

0 comments on commit bdf87d2

Please sign in to comment.