Projekt

Obecné

Profil

Stáhnout (2.4 KB) Statistiky
| Větev: | Revize:
1
'use strict';
2

    
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');
8

    
9
/**
10
 * Customize Snapdragon parser and renderer
11
 */
12

    
13
function Braces(options) {
14
  this.options = extend({}, options);
15
}
16

    
17
/**
18
 * Initialize braces
19
 */
20

    
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;
28

    
29
  compilers(this.snapdragon, opts);
30
  parsers(this.snapdragon, opts);
31

    
32
  /**
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.
37
   */
38

    
39
  utils.define(this.snapdragon, 'parse', function(pattern, options) {
40
    var parsed = Snapdragon.prototype.parse.apply(this, arguments);
41
    this.parser.ast.input = pattern;
42

    
43
    var stack = this.parser.stack;
44
    while (stack.length) {
45
      addParent({type: 'brace.close', val: ''}, stack.pop());
46
    }
47

    
48
    function addParent(node, parent) {
49
      utils.define(node, 'parent', parent);
50
      parent.nodes.push(node);
51
    }
52

    
53
    // add non-enumerable parser reference
54
    utils.define(parsed, 'parser', this.parser);
55
    return parsed;
56
  });
57
};
58

    
59
/**
60
 * Decorate `.parse` method
61
 */
62

    
63
Braces.prototype.parse = function(ast, options) {
64
  if (ast && typeof ast === 'object' && ast.nodes) return ast;
65
  this.init(options);
66
  return this.snapdragon.parse(ast, options);
67
};
68

    
69
/**
70
 * Decorate `.compile` method
71
 */
72

    
73
Braces.prototype.compile = function(ast, options) {
74
  if (typeof ast === 'string') {
75
    ast = this.parse(ast, options);
76
  } else {
77
    this.init(options);
78
  }
79
  return this.snapdragon.compile(ast, options);
80
};
81

    
82
/**
83
 * Expand
84
 */
85

    
86
Braces.prototype.expand = function(pattern) {
87
  var ast = this.parse(pattern, {expand: true});
88
  return this.compile(ast, {expand: true});
89
};
90

    
91
/**
92
 * Optimize
93
 */
94

    
95
Braces.prototype.optimize = function(pattern) {
96
  var ast = this.parse(pattern, {optimize: true});
97
  return this.compile(ast, {optimize: true});
98
};
99

    
100
/**
101
 * Expose `Braces`
102
 */
103

    
104
module.exports = Braces;
(1-1/4)