Projekt

Obecné

Profil

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

    
3
var brackets = require('expand-brackets');
4
var define = require('define-property');
5
var utils = require('./utils');
6

    
7
/**
8
 * Characters to use in text regex (we want to "not" match
9
 * characters that are matched by other parsers)
10
 */
11

    
12
var TEXT_REGEX = '([!@*?+]?\\(|\\)|[*?.+\\\\]|\\[:?(?=.*\\])|:?\\])+';
13
var not = utils.createRegex(TEXT_REGEX);
14

    
15
/**
16
 * Extglob parsers
17
 */
18

    
19
function parsers(extglob) {
20
  extglob.state = extglob.state || {};
21

    
22
  /**
23
   * Use `expand-brackets` parsers
24
   */
25

    
26
  extglob.use(brackets.parsers);
27
  extglob.parser.sets.paren = extglob.parser.sets.paren || [];
28
  extglob.parser
29

    
30
    /**
31
     * Extglob open: "*("
32
     */
33

    
34
    .capture('paren.open', function() {
35
      var parsed = this.parsed;
36
      var pos = this.position();
37
      var m = this.match(/^([!@*?+])?\(/);
38
      if (!m) return;
39

    
40
      var prev = this.prev();
41
      var prefix = m[1];
42
      var val = m[0];
43

    
44
      var open = pos({
45
        type: 'paren.open',
46
        parsed: parsed,
47
        val: val
48
      });
49

    
50
      var node = pos({
51
        type: 'paren',
52
        prefix: prefix,
53
        nodes: [open]
54
      });
55

    
56
      // if nested negation extglobs, just cancel them out to simplify
57
      if (prefix === '!' && prev.type === 'paren' && prev.prefix === '!') {
58
        prev.prefix = '@';
59
        node.prefix = '@';
60
      }
61

    
62
      define(node, 'rest', this.input);
63
      define(node, 'parsed', parsed);
64
      define(node, 'parent', prev);
65
      define(open, 'parent', node);
66

    
67
      this.push('paren', node);
68
      prev.nodes.push(node);
69
    })
70

    
71
    /**
72
     * Extglob close: ")"
73
     */
74

    
75
    .capture('paren.close', function() {
76
      var parsed = this.parsed;
77
      var pos = this.position();
78
      var m = this.match(/^\)/);
79
      if (!m) return;
80

    
81
      var parent = this.pop('paren');
82
      var node = pos({
83
        type: 'paren.close',
84
        rest: this.input,
85
        parsed: parsed,
86
        val: m[0]
87
      });
88

    
89
      if (!this.isType(parent, 'paren')) {
90
        if (this.options.strict) {
91
          throw new Error('missing opening paren: "("');
92
        }
93
        node.escaped = true;
94
        return node;
95
      }
96

    
97
      node.prefix = parent.prefix;
98
      parent.nodes.push(node);
99
      define(node, 'parent', parent);
100
    })
101

    
102
    /**
103
     * Escape: "\\."
104
     */
105

    
106
    .capture('escape', function() {
107
      var pos = this.position();
108
      var m = this.match(/^\\(.)/);
109
      if (!m) return;
110

    
111
      return pos({
112
        type: 'escape',
113
        val: m[0],
114
        ch: m[1]
115
      });
116
    })
117

    
118
    /**
119
     * Question marks: "?"
120
     */
121

    
122
    .capture('qmark', function() {
123
      var parsed = this.parsed;
124
      var pos = this.position();
125
      var m = this.match(/^\?+(?!\()/);
126
      if (!m) return;
127
      extglob.state.metachar = true;
128
      return pos({
129
        type: 'qmark',
130
        rest: this.input,
131
        parsed: parsed,
132
        val: m[0]
133
      });
134
    })
135

    
136
    /**
137
     * Character parsers
138
     */
139

    
140
    .capture('star', /^\*(?!\()/)
141
    .capture('plus', /^\+(?!\()/)
142
    .capture('dot', /^\./)
143
    .capture('text', not);
144
};
145

    
146
/**
147
 * Expose text regex string
148
 */
149

    
150
module.exports.TEXT_REGEX = TEXT_REGEX;
151

    
152
/**
153
 * Extglob parsers
154
 */
155

    
156
module.exports = parsers;
(3-3/4)