3 var extend = require('extend-shallow');
4 var Snapdragon = require('snapdragon');
5 var compilers = require('./compilers');
6 var parsers = require('./parsers');
7 var utils = require('./utils');
10 * Customize Snapdragon parser and renderer
13 function Braces(options) {
14 this.options = extend({}, options);
21 Braces.prototype.init = function(options) {
22 if (this.isInitialized) return;
23 this.isInitialized = true;
24 var opts = utils.createOptions({}, this.options, options);
25 this.snapdragon = this.options.snapdragon || new Snapdragon(opts);
26 this.compiler = this.snapdragon.compiler;
27 this.parser = this.snapdragon.parser;
29 compilers(this.snapdragon, opts);
30 parsers(this.snapdragon, opts);
33 * Call Snapdragon `.parse` method. When AST is returned, we check to
34 * see if any unclosed braces are left on the stack and, if so, we iterate
35 * over the stack and correct the AST so that compilers are called in the correct
36 * order and unbalance braces are properly escaped.
39 utils.define(this.snapdragon, 'parse', function(pattern, options) {
40 var parsed = Snapdragon.prototype.parse.apply(this, arguments);
41 this.parser.ast.input = pattern;
43 var stack = this.parser.stack;
44 while (stack.length) {
45 addParent({type: 'brace.close', val: ''}, stack.pop());
48 function addParent(node, parent) {
49 utils.define(node, 'parent', parent);
50 parent.nodes.push(node);
53 // add non-enumerable parser reference
54 utils.define(parsed, 'parser', this.parser);
60 * Decorate `.parse` method
63 Braces.prototype.parse = function(ast, options) {
64 if (ast && typeof ast === 'object' && ast.nodes) return ast;
66 return this.snapdragon.parse(ast, options);
70 * Decorate `.compile` method
73 Braces.prototype.compile = function(ast, options) {
74 if (typeof ast === 'string') {
75 ast = this.parse(ast, options);
79 return this.snapdragon.compile(ast, options);
86 Braces.prototype.expand = function(pattern) {
87 var ast = this.parse(pattern, {expand: true});
88 return this.compile(ast, {expand: true});
95 Braces.prototype.optimize = function(pattern) {
96 var ast = this.parse(pattern, {optimize: true});
97 return this.compile(ast, {optimize: true});
104 module.exports = Braces;