UNPKG

3.01 kBJavaScriptView Raw
1var extend = require('./utils').extend;
2
3function isFlag(token) {
4 return token.slice(0, 1) === '[' && token.slice(-1) === ']';
5}
6function isAlternation(token) {
7 return token.slice(0, 1) === '(' && token.slice(-1) === ')';
8}
9function removeEmptyStrings(texts) {
10 return texts.filter(function (text) { return text !== ''; });
11}
12function createPermutations(tokens, index) {
13 if (index === tokens.length) {
14 return [{ text: '', flags: {}, alternations: [] }];
15 }
16
17 var token = tokens[index];
18 var tail = createPermutations(tokens, index + 1);
19 if (isFlag(token)) {
20 var flag = token.slice(1, -1);
21 return tail
22 .map(function (pattern) {
23 var flags = {};
24 flags[flag] = true;
25 return {
26 text: (flag + " " + (pattern.text)),
27 flags: extend(flags, pattern.flags),
28 alternations: pattern.alternations
29 };
30 })
31 .concat(
32 tail.map(function (pattern) {
33 var flags = {};
34 flags[flag] = false;
35 return {
36 text: pattern.text,
37 flags: extend(flags, pattern.flags),
38 alternations: pattern.alternations
39 };
40 })
41 );
42 } else if (isAlternation(token)) {
43 return token
44 .substr(1, token.length - 2) // Remove parentheses
45 .split(/\|/)
46 .reduce(
47 function (result, alternation) { return result.concat(
48 tail.map(function (ref) {
49 var text = ref.text;
50 var flags = ref.flags;
51 var alternations = ref.alternations;
52
53 return ({
54 // Make sure that an empty alternation doesn't produce two spaces:
55 text: alternation ? alternation + text : text.replace(/^ /, ''),
56
57 flags: flags,
58 alternations: [alternation ].concat( alternations)
59 });
60 })
61 ); },
62 []
63 );
64 } else {
65 return tail.map(function (ref) {
66 var text = ref.text;
67 var flags = ref.flags;
68 var alternations = ref.alternations;
69
70 return ({
71 text: token + text,
72 flags: flags,
73 alternations: alternations
74 });
75 });
76 }
77}
78
79function expandAssertion(pattern) {
80 pattern = pattern.replace(/(\[[^\]]+\]) ?/g, '$1');
81 var splitRegex = /\[[^\]]+\]|\([^)]+\)/g;
82 var tokens = [];
83 var m;
84 var lastIndex = 0;
85 while ((m = splitRegex.exec(pattern))) {
86 tokens.push(pattern.slice(lastIndex, m.index));
87 tokens.push(pattern.slice(m.index, splitRegex.lastIndex));
88 lastIndex = splitRegex.lastIndex;
89 }
90 tokens.push(pattern.slice(lastIndex));
91 tokens = removeEmptyStrings(tokens);
92 var permutations = createPermutations(tokens, 0);
93 permutations.forEach(function (permutation) {
94 permutation.text = permutation.text.trim();
95 if (permutation.text === '') {
96 // This can only happen if the pattern only contains flags
97 throw new Error('Assertion patterns must not only contain flags');
98 }
99 });
100 return permutations;
101}
102
103module.exports = expandAssertion;