Projekt

Obecné

Profil

Stáhnout (3.91 KB) Statistiky
| Větev: | Revize:
1
'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
};
(1-1/4)