Projekt

Obecné

Profil

Stáhnout (3.91 KB) Statistiky
| Větev: | Revize:
1 3a515b92 cagy
'use strict';
2
3
var brackets = require('expand-brackets');
4
5
/**
6
 * Extglob compilers
7
 */
8
9
module.exports = function(extglob) {
10
  function star() {
11
    if (typeof extglob.options.star === 'function') {
12
      return extglob.options.star.apply(this, arguments);
13
    }
14
    if (typeof extglob.options.star === 'string') {
15
      return extglob.options.star;
16
    }
17
    return '.*?';
18
  }
19
20
  /**
21
   * Use `expand-brackets` compilers
22
   */
23
24
  extglob.use(brackets.compilers);
25
  extglob.compiler
26
27
    /**
28
     * Escaped: "\\*"
29
     */
30
31
    .set('escape', function(node) {
32
      return this.emit(node.val, node);
33
    })
34
35
    /**
36
     * Dot: "."
37
     */
38
39
    .set('dot', function(node) {
40
      return this.emit('\\' + node.val, node);
41
    })
42
43
    /**
44
     * Question mark: "?"
45
     */
46
47
    .set('qmark', function(node) {
48
      var val = '[^\\\\/.]';
49
      var prev = this.prev();
50
51
      if (node.parsed.slice(-1) === '(') {
52
        var ch = node.rest.charAt(0);
53
        if (ch !== '!' && ch !== '=' && ch !== ':') {
54
          return this.emit(val, node);
55
        }
56
        return this.emit(node.val, node);
57
      }
58
59
      if (prev.type === 'text' && prev.val) {
60
        return this.emit(val, node);
61
      }
62
63
      if (node.val.length > 1) {
64
        val += '{' + node.val.length + '}';
65
      }
66
      return this.emit(val, node);
67
    })
68
69
    /**
70
     * Plus: "+"
71
     */
72
73
    .set('plus', function(node) {
74
      var prev = node.parsed.slice(-1);
75
      if (prev === ']' || prev === ')') {
76
        return this.emit(node.val, node);
77
      }
78
      var ch = this.output.slice(-1);
79
      if (!this.output || (/[?*+]/.test(ch) && node.parent.type !== 'bracket')) {
80
        return this.emit('\\+', node);
81
      }
82
      if (/\w/.test(ch) && !node.inside) {
83
        return this.emit('+\\+?', node);
84
      }
85
      return this.emit('+', node);
86
    })
87
88
    /**
89
     * Star: "*"
90
     */
91
92
    .set('star', function(node) {
93
      var prev = this.prev();
94
      var prefix = prev.type !== 'text' && prev.type !== 'escape'
95
        ? '(?!\\.)'
96
        : '';
97
98
      return this.emit(prefix + star.call(this, node), node);
99
    })
100
101
    /**
102
     * Parens
103
     */
104
105
    .set('paren', function(node) {
106
      return this.mapVisit(node.nodes);
107
    })
108
    .set('paren.open', function(node) {
109
      var capture = this.options.capture ? '(' : '';
110
111
      switch (node.parent.prefix) {
112
        case '!':
113
        case '^':
114
          return this.emit(capture + '(?:(?!(?:', node);
115
        case '*':
116
        case '+':
117
        case '?':
118
        case '@':
119
          return this.emit(capture + '(?:', node);
120
        default: {
121
          var val = node.val;
122
          if (this.options.bash === true) {
123
            val = '\\' + val;
124
          } else if (!this.options.capture && val === '(' && node.parent.rest[0] !== '?') {
125
            val += '?:';
126
          }
127
128
          return this.emit(val, node);
129
        }
130
      }
131
    })
132
    .set('paren.close', function(node) {
133
      var capture = this.options.capture ? ')' : '';
134
135
      switch (node.prefix) {
136
        case '!':
137
        case '^':
138
          var prefix = /^(\)|$)/.test(node.rest) ? '$' : '';
139
          var str = star.call(this, node);
140
141
          // if the extglob has a slash explicitly defined, we know the user wants
142
          // to match slashes, so we need to ensure the "star" regex allows for it
143
          if (node.parent.hasSlash && !this.options.star && this.options.slash !== false) {
144
            str = '.*?';
145
          }
146
147
          return this.emit(prefix + ('))' + str + ')') + capture, node);
148
        case '*':
149
        case '+':
150
        case '?':
151
          return this.emit(')' + node.prefix + capture, node);
152
        case '@':
153
          return this.emit(')' + capture, node);
154
        default: {
155
          var val = (this.options.bash === true ? '\\' : '') + ')';
156
          return this.emit(val, node);
157
        }
158
      }
159
    })
160
161
    /**
162
     * Text
163
     */
164
165
    .set('text', function(node) {
166
      var val = node.val.replace(/[\[\]]/g, '\\$&');
167
      return this.emit(val, node);
168
    });
169
};