Projekt

Obecné

Profil

Stáhnout (2.4 KB) Statistiky
| Větev: | Revize:
1 3a515b92 cagy
'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;