1 | 'use strict';
|
2 |
|
3 | var debug = require('debug')('braces');
|
4 | var Snapdragon = require('snapdragon');
|
5 | var compilers = require('./compilers');
|
6 | var parsers = require('./parsers');
|
7 | var utils = require('./utils');
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 | function Braces(options) {
|
14 | debug('initializing from <%s>', __filename);
|
15 | this.options = utils.extend({}, options);
|
16 | }
|
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 | Braces.prototype.init = function(options) {
|
23 | var opts = utils.createOptions({}, this.options, options);
|
24 | this.snapdragon = this.options.snapdragon || new Snapdragon(opts);
|
25 | this.compiler = this.snapdragon.compiler;
|
26 | this.parser = this.snapdragon.parser;
|
27 |
|
28 | compilers(this.snapdragon);
|
29 | parsers(this.snapdragon);
|
30 |
|
31 | |
32 |
|
33 |
|
34 |
|
35 |
|
36 |
|
37 |
|
38 | utils.define(this.snapdragon, 'parse', function(pattern, options) {
|
39 | var parsed = Snapdragon.prototype.parse.apply(this, arguments);
|
40 | this.parser.ast.input = pattern;
|
41 |
|
42 | var stack = this.parser.stack;
|
43 | while (stack.length) {
|
44 | addParent({type: 'brace.close', val: ''}, stack.pop());
|
45 | }
|
46 |
|
47 | function addParent(node, parent) {
|
48 | utils.define(node, 'parent', parent);
|
49 | parent.nodes.push(node);
|
50 | }
|
51 |
|
52 |
|
53 | utils.define(parsed, 'parser', this.parser);
|
54 | return parsed;
|
55 | });
|
56 | };
|
57 |
|
58 |
|
59 |
|
60 |
|
61 |
|
62 | Braces.prototype.lazyInit = function(options) {
|
63 | if (!this.isInitialized) {
|
64 | this.isInitialized = true;
|
65 | this.init(options);
|
66 | }
|
67 | };
|
68 |
|
69 |
|
70 |
|
71 |
|
72 |
|
73 | Braces.prototype.parse = function(ast, options) {
|
74 | if (utils.isObject(ast) && ast.nodes) return ast;
|
75 | this.lazyInit(options);
|
76 | return this.snapdragon.parse(ast, options);
|
77 | };
|
78 |
|
79 |
|
80 |
|
81 |
|
82 |
|
83 | Braces.prototype.compile = function(ast, options) {
|
84 | if (typeof ast === 'string') ast = this.parse(ast, options);
|
85 | this.lazyInit(options);
|
86 | return this.snapdragon.compile(ast, options);
|
87 | };
|
88 |
|
89 |
|
90 |
|
91 |
|
92 |
|
93 | Braces.prototype.expand = function(pattern) {
|
94 | var ast = this.parse(pattern, {expand: true});
|
95 | var res = this.compile(ast, {expand: true});
|
96 | return res.output;
|
97 | };
|
98 |
|
99 |
|
100 |
|
101 |
|
102 |
|
103 | Braces.prototype.optimize = function(pattern) {
|
104 | var ast = this.parse(pattern, {optimize: true});
|
105 | var res = this.compile(ast, {optimize: true});
|
106 | return res.output;
|
107 | };
|
108 |
|
109 |
|
110 |
|
111 |
|
112 |
|
113 | function visit(node, fn) {
|
114 | return node.nodes ? mapVisit(node.nodes, fn) : fn(node);
|
115 | }
|
116 |
|
117 |
|
118 |
|
119 |
|
120 |
|
121 | function mapVisit(nodes, fn) {
|
122 | var len = nodes.length;
|
123 | var idx = -1;
|
124 | while (++idx < len) {
|
125 | visit(nodes[idx], fn);
|
126 | }
|
127 | }
|
128 |
|
129 |
|
130 |
|
131 |
|
132 |
|
133 | module.exports = Braces;
|