Parse Handlebars and HTML.
Parse this:
<tag> value {{{obj.value}~}} </tag>
into this:
[
{ type:"htmlTagStart" },
{ type:"htmlTagNameStart" },
{ type:"literal", value:"tag" },
{ type:"htmlTagNameEnd" },
{ type:"htmlTagEnd" },
{ type:"literal", value:" value " },
{ type:"hbsTagStart", unescaped:true },
{ type:"hbsExpressionStart" },
{ type:"hbsPartStart" },
{ type:"hbsPath", value:["obj","value"] },
{ type:"hbsPartEnd" },
{ type:"hbsExpressionEnd" },
{ type:"hbsTagEnd", unescaped:true, strip:true },
// whitespace stripped
{ type:"htmlTagStart", closing:true },
{ type:"htmlTagNameStart" },
{ type:"literal", value:"tag" },
{ type:"htmlTagNameEnd" },
{ type:"htmlTagEnd" }
]
…for use in compiling to something like a virtual DOM, such that of handlebars-react.
For more information on the strengths, weaknesses and implementation details of this library, check out the wiki.
Node.js >= 5
is required; < 5.0
will need an ES6 compiler. Type this at the command line:
npm install handlebars-html-parser
Parse a template String into a linear program which contains HTML pieces and Handlebars expressions. A Promise
is returned for use in chaining.
Format a JavaScript String for increased legibility. This is a convenience function that will prevent your project from depending on multiple versions of uglify-js.
Runs a provided Function once per element in the generated linear program.
callback
has two arguments:
node
, the current node being processed in the linear programstate
, a mutable/reused object containing the current state of node
A map of node types. See the full list.
Type: Boolean
Default value: false
When true
, Handlebars comments will be converted to HTML comments.
Type: Boolean
Default value: false
When true
, Handlebars comments will be excluded from output. This can result in concatenated Strings, which optimizes compilation.
Type: Boolean
Default value: false
When true
, HTML comments will be excluded from output. This can result in concatenated Strings, which optimizes compilation.
Type: Boolean
Default value: false
When true
, will replace multiple standard whitespace characters (line breaks, tabs, regular spaces) with a single space. This helps improve runtime performance and lower compiled template file size.
, etc.<pre>
,<script>
,<style>
,<textarea>
elements<{{tag}}>
)<tag attr="value">
)white-space:pre
)Type: Boolean
Default value: false
When true
, the contents of CSS tags and attributes will be auto-prefixed and minified. Note: if any Handlebars expressions are contained within, minification will be skipped.
Type: Boolean
Default value: false
When true
, the contents of JavaScript tags, attributes and href="javascript:…"
links will be minified. Note: if any Handlebars expressions are contained within, minification will be skipped.
var HandlebarsHtmlParser = require("handlebars-html-parser")
var eachNode = HandlebarsHtmlParser.each
var NodeType = HandlebarsHtmlParser.type
var parser = new HandlebarsHtmlParser(options)
parser.parse("<tag>{{var}}</tag>")
.then( eachNode((node, state) => {
switch(node.type) {
case NodeType.HBS_EXPRESSION_START: {
// is expression start node
break
}
case NodeType.HTML_TAG_START: {
// is html tag start node
break
}
}
}))
.then(program => console.log("done!"))
How is this different from HTMLBars? HTMLBars builds an opinionated DOM whereas this library enables you to build a custom DOM with any and all reactive binding logic offloaded to a library of your choice.
Why not just extend the Handlebars AST? Less maintenance. The result of extending it would still require a custom compiler because the AST would be incompatible with the Handlebars compiler. Every breaking change made to Handlebars will require such to this parser, but likely not to its compiler.
inverseStrip
(in hbs ast) is used for{{{{raw-helper}}}} {{path}} {{{{/raw-helper}}}}
<{{tag}}></{{tag}}>
by aliasing to <hbshtml-start1-end3></hbshtml-start1-end3>
?{{this}}
,{{.}}
options.mustacheOnly
that disables helpers, expressions and whitespace control? would have to provide parse errorsoptions.xmlMode
with xmldoc ?