1 /*! `handlebars` grammar compiled for Highlight.js 11.11.1 */
3 var hljsGrammar
= (function () {
9 Author: Robin Ward <robin.ward@gmail.com>
10 Description: Matcher for Handlebars as well as EmberJS additions.
11 Website: https://handlebarsjs.com
15 function handlebars(hljs
) {
16 const regex
= hljs
.regex
;
62 // as defined in https://handlebarsjs.com/guide/expressions.html#literal-segments
63 // this regex matches literal segments like ' abc ' or [ abc ] as well as helpers and paths
64 // like a/b, ./abc/cde, and abc.bcd
66 const DOUBLE_QUOTED_ID_REGEX
= /""|"[^"]+"/;
67 const SINGLE_QUOTED_ID_REGEX
= /''|'[^']+'/;
68 const BRACKET_QUOTED_ID_REGEX
= /\[\]|\[[^\]]+\]/;
69 const PLAIN_ID_REGEX
= /[^\s!"#%&'()*+,.\/;<=>@\[\\\]^`{|}~]+/;
70 const PATH_DELIMITER_REGEX
= /(\.|\/)/;
71 const ANY_ID
= regex
.either(
72 DOUBLE_QUOTED_ID_REGEX
,
73 SINGLE_QUOTED_ID_REGEX
,
74 BRACKET_QUOTED_ID_REGEX
,
78 const IDENTIFIER_REGEX
= regex
.concat(
79 regex
.optional(/\.|\.\/|\//), // relative or absolute path
81 regex
.anyNumberOfTimes(regex
.concat(
87 // identifier followed by a equal-sign (without the equal sign)
88 const HASH_PARAM_REGEX
= regex
.concat(
90 BRACKET_QUOTED_ID_REGEX
, '|',
95 const HELPER_NAME_OR_PATH_EXPRESSION
= { begin: IDENTIFIER_REGEX
};
97 const HELPER_PARAMETER
= hljs
.inherit(HELPER_NAME_OR_PATH_EXPRESSION
, { keywords: LITERALS
});
99 const SUB_EXPRESSION
= {
102 // the "contains" is added below when all necessary sub-modes are defined
106 // fka "attribute-assignment", parameters of the form 'key=value'
108 begin: HASH_PARAM_REGEX
,
113 starts: { contains: [
115 hljs
.QUOTE_STRING_MODE
,
116 hljs
.APOS_STRING_MODE
,
123 const BLOCK_PARAMS
= {
124 // parameters of the form '{{#with x as | y |}}...{{/with}}'
126 keywords: { keyword: 'as' },
130 // define sub-mode in order to prevent highlighting of block-parameter named "as"
135 const HELPER_PARAMETERS
= {
138 hljs
.QUOTE_STRING_MODE
,
139 hljs
.APOS_STRING_MODE
,
146 // the property "end" is defined through inheritance when the mode is used. If depends
147 // on the surrounding mode, but "endsWithParent" does not work here (i.e. it includes the
148 // end-token of the surrounding mode)
151 const SUB_EXPRESSION_CONTENTS
= hljs
.inherit(HELPER_NAME_OR_PATH_EXPRESSION
, {
154 starts: hljs
.inherit(HELPER_PARAMETERS
, { end: /\)/ })
157 SUB_EXPRESSION
.contains
= [ SUB_EXPRESSION_CONTENTS
];
159 const OPENING_BLOCK_MUSTACHE_CONTENTS
= hljs
.inherit(HELPER_NAME_OR_PATH_EXPRESSION
, {
162 starts: hljs
.inherit(HELPER_PARAMETERS
, { end: /\}\}/ })
165 const CLOSING_BLOCK_MUSTACHE_CONTENTS
= hljs
.inherit(HELPER_NAME_OR_PATH_EXPRESSION
, {
170 const BASIC_MUSTACHE_CONTENTS
= hljs
.inherit(HELPER_NAME_OR_PATH_EXPRESSION
, {
173 starts: hljs
.inherit(HELPER_PARAMETERS
, { end: /\}\}/ })
176 const ESCAPE_MUSTACHE_WITH_PRECEEDING_BACKSLASH
= {
180 const PREVENT_ESCAPE_WITH_ANOTHER_PRECEEDING_BACKSLASH
= {
181 begin: /\\\\(?=\{\{)/,
193 case_insensitive: true,
196 ESCAPE_MUSTACHE_WITH_PRECEEDING_BACKSLASH
,
197 PREVENT_ESCAPE_WITH_ANOTHER_PRECEEDING_BACKSLASH
,
198 hljs
.COMMENT(/\{\{!--/, /--\}\}/),
199 hljs
.COMMENT(/\{\{!/, /\}\}/),
201 // open raw block "{{{{raw}}}} content not evaluated {{{{/raw}}}}"
202 className: 'template-tag',
203 begin: /\{\{\{\{(?!\/)/,
205 contains: [ OPENING_BLOCK_MUSTACHE_CONTENTS
],
214 className: 'template-tag',
217 contains: [ CLOSING_BLOCK_MUSTACHE_CONTENTS
]
220 // open block statement
221 className: 'template-tag',
224 contains: [ OPENING_BLOCK_MUSTACHE_CONTENTS
]
227 className: 'template-tag',
228 begin: /\{\{(?=else\}\})/,
233 className: 'template-tag',
234 begin: /\{\{(?=else if)/,
239 // closing block statement
240 className: 'template-tag',
243 contains: [ CLOSING_BLOCK_MUSTACHE_CONTENTS
]
246 // template variable or helper-call that is NOT html-escaped
247 className: 'template-variable',
250 contains: [ BASIC_MUSTACHE_CONTENTS
]
253 // template variable or helper-call that is html-escaped
254 className: 'template-variable',
257 contains: [ BASIC_MUSTACHE_CONTENTS
]
267 hljs
.registerLanguage('handlebars', hljsGrammar
);