Skip to content

Commit

Permalink
wip: adjustments for integrating handlebars rules
Browse files Browse the repository at this point in the history
- hash-parameters
- subexpressions

wip: adjustments for integrating handlebars rules

- hash-parameters
- subexpressions

wip: update tests

some minor adaptions

wip: fix test cases

wip: try to honor path expressions correctly

wip: fix tests and refactor language definition

wip: update keywords, remove debug output

wip: {{else}} is a keyword and not a helper call

wip: fix test for else-variants

- else is not a built-in (except for the keyword {{else}})

wip: fix hashes and number literals, add string literals

- the hash-value must start after the equals-sign
- number and string modes must be in front of identifiers, because they are a subset

wip: make "as" in block-parameters a "keyword"

fixup: revert tests to old tests from origin/master

fixup: adjust expected test results for failing tests

add else variant tests
  • Loading branch information
nknapp committed Apr 10, 2020
1 parent 512ae5f commit 9468f00
Show file tree
Hide file tree
Showing 13 changed files with 148 additions and 135 deletions.
144 changes: 123 additions & 21 deletions src/languages/handlebars.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,39 +6,133 @@ Description: Matcher for Handlebars as well as EmberJS additions.
Website: https://handlebarsjs.com
Category: template
*/
export default function (hljs) {

export default function(hljs) {
var BUILT_INS = {'builtin-name': 'each in with if else unless bindattr action collection debugger log outlet template unbound view yield lookup'};
var BUILT_INS = {
'builtin-name': 'action bindattr collection component concat debugger '
+ 'each each-in get hash if in input link-to loc log lookup '
+ 'mut outlet partial query-params render template textarea unbound '
+ 'unless view with yield'
};

var IDENTIFIER_PLAIN_OR_QUOTED = {
begin: /".*?"|'.*?'|\[.*?\]|\w+/
var LITERALS = {
'literal': 'true false undefined null'
};

var EXPRESSION_OR_HELPER_CALL = hljs.inherit(IDENTIFIER_PLAIN_OR_QUOTED, {
keywords: BUILT_INS,
// as defined in https://handlebarsjs.com/guide/expressions.html#literal-segments
// this regex matches literal segments like ' abc ' or [ abc ] as well as helpers and paths
// like a/b, ./abc/cde, and abc.bcd
var IDENFIFIER_REGEX = /(".*?"|'.*?'|\[.*?\]|[^\s!"#%&'()*+,.\/;<=>@\[\\\]^`{|}~]+|\.|\/)+/;

// identifier followed by a equal-sign (without the equal sign)
var HASH_PARAM_REGEX = /(".*?"|'.*?'|\[.*?\]|[^\s!"#%&'()*+,.\/;<=>@\[\\\]^`{|}~]+)(?==)/;

var HELPER_NAME_OR_PATH_EXPRESSION = {
begin: IDENFIFIER_REGEX,
lexemes: /[\w.\/]+/
};

var HELPER_PARAMETER = hljs.inherit(HELPER_NAME_OR_PATH_EXPRESSION, {
keywords: LITERALS
});

var SUB_EXPRESSION = {
illegal: /\}\}/,
begin: /\(/, end: /\)/
// the "contains" is added below when all necessary sub-modes are defined
};

var HASH = {
// fka "attribute-assignment", parameters of the form 'key=value'
className: 'attr',
illegal: /\}\}/,
begin: HASH_PARAM_REGEX,
relevance: 0,
starts: {
// helper params
endsWithParent: true,
relevance: 0,
contains: [hljs.inherit(IDENTIFIER_PLAIN_OR_QUOTED, {relevance: 0})]
begin: /=/,
end: /=/,
starts: {
contains: [
hljs.NUMBER_MODE,
hljs.QUOTE_STRING_MODE,
hljs.APOS_STRING_MODE,
HELPER_PARAMETER,
SUB_EXPRESSION
]
}
}
};

var BLOCK_PARAMS = {
// parameters of the form '{{#with x as | y |}}...{{/with}}'
begin: /as\s+\|/,
keywords: { keyword: 'as' },
end: /\|/,
contains: [
{
// define sub-mode in order to prevent highlighting of block-parameter named "as"
begin: /\w+/,
keywords: ''
}
]
}

var HELPER_PARAMETERS = {
contains: [
hljs.NUMBER_MODE,
hljs.QUOTE_STRING_MODE,
hljs.APOS_STRING_MODE,
BLOCK_PARAMS,
HASH,
HELPER_PARAMETER,
SUB_EXPRESSION
],
returnEnd: true
// the property "end" is defined through inheritance when the mode is used. If depends
// on the surrounding mode, but "endsWithParent" does not work here (i.e. it includes the
// end-token of the surrounding mode)
};

var SUB_EXPRESSION_CONTENTS = hljs.inherit(HELPER_NAME_OR_PATH_EXPRESSION, {
className: 'name',
keywords: BUILT_INS,
starts: hljs.inherit(HELPER_PARAMETERS, {
end: /\)/,
})
});

SUB_EXPRESSION.contains = [
SUB_EXPRESSION_CONTENTS
];

var OPENING_BLOCK_MUSTACHE_CONTENTS = hljs.inherit(HELPER_NAME_OR_PATH_EXPRESSION, {
keywords: BUILT_INS,
className: 'name',
starts: hljs.inherit(HELPER_PARAMETERS, {
end: /}}/,
})
});

var BLOCK_MUSTACHE_CONTENTS = hljs.inherit(EXPRESSION_OR_HELPER_CALL, {
var CLOSING_BLOCK_MUSTACHE_CONTENTS = hljs.inherit(HELPER_NAME_OR_PATH_EXPRESSION, {
keywords: BUILT_INS,
className: 'name'
});

var BASIC_MUSTACHE_CONTENTS = hljs.inherit(EXPRESSION_OR_HELPER_CALL, {
// relevance 0 for backward compatibility concerning auto-detection
relevance: 0

var BASIC_MUSTACHE_CONTENTS = hljs.inherit(HELPER_NAME_OR_PATH_EXPRESSION, {
className: 'name',
keywords: BUILT_INS,
starts: hljs.inherit(HELPER_PARAMETERS, {
end: /}}/,
})
});

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

return {
name: 'Handlebars',
aliases: ['hbs', 'html.hbs', 'html.handlebars'],
aliases: ['hbs', 'html.hbs', 'html.handlebars', 'htmlbars'],
case_insensitive: true,
subLanguage: 'xml',
contains: [
Expand All @@ -50,33 +144,41 @@ export default function(hljs) {
// open raw block "{{{{raw}}}} content not evaluated {{{{/raw}}}}"
className: 'template-tag',
begin: /\{\{\{\{(?!\/)/, end: /\}\}\}\}/,
contains: [BLOCK_MUSTACHE_CONTENTS],
contains: [OPENING_BLOCK_MUSTACHE_CONTENTS],
starts: {end: /\{\{\{\{\//, returnEnd: true, subLanguage: 'xml'}
},
{
// close raw block
className: 'template-tag',
begin: /\{\{\{\{\//, end: /\}\}\}\}/,
contains: [BLOCK_MUSTACHE_CONTENTS]
contains: [CLOSING_BLOCK_MUSTACHE_CONTENTS]
},
{
// open block statement
className: 'template-tag',
begin: /\{\{[#\/]/, end: /\}\}/,
contains: [BLOCK_MUSTACHE_CONTENTS],
begin: /\{\{#/, end: /\}\}/,
contains: [OPENING_BLOCK_MUSTACHE_CONTENTS],
},
{
className: 'keyword',
begin: /\{\{else\}\}/
},
{
// closing block statement
className: 'template-tag',
begin: /\{\{\//, end: /\}\}/,
contains: [CLOSING_BLOCK_MUSTACHE_CONTENTS],
},
{
// template variable or helper-call that is NOT html-escaped
className: 'template-variable',
begin: /\{\{\{/, end: /\}\}\}/,
keywords: BUILT_INS,
contains: [BASIC_MUSTACHE_CONTENTS]
},
{
// template variable or helper-call that is html-escaped
className: 'template-variable',
begin: /\{\{/, end: /\}\}/,
keywords: BUILT_INS,
contains: [BASIC_MUSTACHE_CONTENTS]
}
]
Expand Down
80 changes: 0 additions & 80 deletions src/languages/htmlbars.js

This file was deleted.

9 changes: 0 additions & 9 deletions test/detect/htmlbars/default.txt

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<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">
<span class="xml">text </span><span class="hljs-template-tag">{{#<span class="hljs-name">abc</span> <span class="hljs-string">"lite]'ral}}segment"</span> }}</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> <span class="hljs-string">'lite]"ral}}segment'</span> }}</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">

Expand Down
4 changes: 2 additions & 2 deletions test/markup/handlebars/built-ins.expect.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

</span><span class="hljs-template-tag">{{#<span class="hljs-name"><span class="hljs-builtin-name">each</span></span> test}}</span><span class="xml">abc</span><span class="hljs-template-tag">{{/<span class="hljs-name"><span class="hljs-builtin-name">each</span></span>}}</span><span class="xml">

</span><span class="hljs-template-variable">{{<span class="hljs-builtin-name">lookup</span> abc}}</span><span class="xml">
</span><span class="hljs-template-variable">{{<span class="hljs-name"><span class="hljs-builtin-name">lookup</span></span> abc}}</span><span class="xml">

</span><span class="hljs-template-variable">{{<span class="hljs-builtin-name">log</span> test}}</span><span class="xml">
</span><span class="hljs-template-variable">{{<span class="hljs-name"><span class="hljs-builtin-name">log</span></span> test}}</span><span class="xml">
</span>
2 changes: 1 addition & 1 deletion test/markup/handlebars/comments.expect.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<span class="hljs-comment">{{!-- a comment {{expression}} --}}</span><span class="xml"> </span><span class="hljs-template-variable">{{expression}}</span><span class="xml">
<span class="hljs-comment">{{!-- a comment {{expression}} --}}</span><span class="xml"> </span><span class="hljs-template-variable">{{<span class="hljs-name">expression</span>}}</span><span class="xml">

</span><span class="hljs-comment">{{! a simple comment }}</span><span class="xml">
</span>
6 changes: 3 additions & 3 deletions test/markup/handlebars/escaped-mustaches.expect.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@

<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">{{<span class="hljs-name">expression</span>}}</span><span class="xml">

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

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

\\\</span><span class="hljs-comment">{{! comment }}</span><span class="xml">
</span>
24 changes: 12 additions & 12 deletions test/markup/handlebars/expression-variants.expect.txt
Original file line number Diff line number Diff line change
@@ -1,27 +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">{{ <span class="hljs-name">"lite]'ral}}segment"</span> }}</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">{{ <span class="hljs-name">'lite]"ral}}segment'</span> }}</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">{{ <span class="hljs-name">[lite"'ral}}segment]</span> }}</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">{{ <span class="hljs-name">abc</span> <span class="hljs-string">"lite]'ral}}segment"</span> }}</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">{{ <span class="hljs-name">abc</span> <span class="hljs-string">'lite]"ral}}segment'</span> }}</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">{{ <span class="hljs-name">abc</span> [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">{{ <span class="hljs-name">abcd.[lite"'ral}}segment]</span> }}</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">{{ <span class="hljs-name">abcd."lite]'ral}}segment"</span> }}</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">{{ <span class="hljs-name">abcd.'lite]"ral}}segment'</span> }}</span><span class="xml"> text

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

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

</span><span class="hljs-template-variable">{{ abcd.[] }}</span><span class="xml"> text
</span><span class="hljs-template-variable">{{ <span class="hljs-name">abcd.[]</span> }}</span><span class="xml"> text
</span>
2 changes: 1 addition & 1 deletion test/markup/handlebars/partial-call.expect.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
<span class="hljs-template-variable">{{&gt; partial}}</span><span class="xml">
<span class="hljs-template-variable">{{&gt; <span class="hljs-name"><span class="hljs-builtin-name">partial</span></span>}}</span><span class="xml">
</span>
2 changes: 1 addition & 1 deletion test/markup/handlebars/raw-block.expect.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
<span class="hljs-template-tag">{{{{#<span class="hljs-name">raw</span>}}}}</span><span class="xml"> {{verbatim}} content </span><span class="hljs-template-tag">{{{{/<span class="hljs-name">raw</span>}}}}</span><span class="xml"> </span><span class="hljs-template-variable">{{var}}</span><span class="xml">
<span class="hljs-template-tag">{{{{#<span class="hljs-name">raw</span>}}}}</span><span class="xml"> {{verbatim}} content </span><span class="hljs-template-tag">{{{{/<span class="hljs-name">raw</span>}}}}</span><span class="xml"> </span><span class="hljs-template-variable">{{<span class="hljs-name">var</span>}}</span><span class="xml">
</span>
2 changes: 1 addition & 1 deletion test/markup/handlebars/simple-expression.expect.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
<span class="hljs-template-variable">{{abc}}</span><span class="xml">
<span class="hljs-template-variable">{{<span class="hljs-name">abc</span>}}</span><span class="xml">
</span>
2 changes: 1 addition & 1 deletion test/markup/handlebars/sub-expressions.expect.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
<span class="hljs-template-variable">{{helper (subExpression 1 2)}}</span><span class="xml">
<span class="hljs-template-variable">{{<span class="hljs-name">helper</span> (<span class="hljs-name">subExpression</span> <span class="hljs-number">1</span> <span class="hljs-number">2</span>)}}</span><span class="xml">
</span>
2 changes: 1 addition & 1 deletion test/markup/handlebars/triple-mustache.expect.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
<span class="hljs-template-variable">{{{raw}}}</span><span class="xml">
<span class="hljs-template-variable">{{{<span class="hljs-name">raw</span>}}}</span><span class="xml">
</span>

0 comments on commit 9468f00

Please sign in to comment.