Skip to content

Commit c7f29a4

Browse files
committed
tweak quotes handling
1 parent 1b231bc commit c7f29a4

File tree

4 files changed

+105
-85
lines changed

4 files changed

+105
-85
lines changed

.verb.md

+22-16
Original file line numberDiff line numberDiff line change
@@ -105,26 +105,26 @@ split('a.{b.c}', {brackets: true});
105105
split('a.{b.{c.d}.e}.f', {brackets: true});
106106
//=> [ 'a', '{b.{c.d}.e}', 'f' ]
107107

108-
// support only the specified brackets
109-
split('[a.b].(c.d)', {brackets: {'[': ']'}});
110-
//=> [ '[a.b]', '(c', 'd)' ]
108+
// support only the specified bracket types
109+
split('«a.b».⟨c.d', {brackets: {'«': '»', '': ''}});
110+
//=> [ '«a.b»', '⟨c.d⟩' ]
111111
```
112112

113-
### options.sep
113+
### options.separator
114114

115115
**Type**: `string`
116116

117117
**Default**: `.`
118118

119-
The separator/character to split on.
119+
The separator/character to split on. Aliased as `options.sep` for backwards compatibility with versions <4.0.
120120

121121
**Example**
122122

123123
```js
124-
split('a.b,c', {sep: ','});
124+
split('a.b,c', {separator: ','});
125125
//=> ['a.b', 'c']
126126

127-
// you can also pass the separator as string as the last argument
127+
// you can also pass the separator as a string as the last argument
128128
split('a.b,c', ',');
129129
//=> ['a.b', 'c']
130130
```
@@ -216,27 +216,33 @@ Pass a function as the last argument to customize how tokens are added to the ar
216216
**Example**
217217

218218
```js
219-
var arr = split('a.b', function(tok) {
220-
if (tok.arr[tok.arr.length - 1] === 'a') {
221-
tok.split = false;
219+
var res = split('a.b', function(token) {
220+
if (token.tokens[0] === 'a') {
221+
token.split = false;
222222
}
223223
});
224-
console.log(arr);
224+
console.log(res);
225225
//=> ['a.b']
226226
```
227227

228228
**Properties**
229229

230-
The `tok` object has the following properties:
230+
The `token` object has the following properties:
231231

232-
- `tok.val` (string) The current value about to be pushed onto the result array
233-
- `tok.idx` (number) the current index in the string
234-
- `tok.str` (string) the entire string
235-
- `tok.arr` (array) the result array
232+
- `token.val` (string) The current value about to be pushed onto the result array
233+
- `token.index` (number) the current index in the string
234+
- `token.input` (string) the entire input string
235+
- `token.tokens` (array) the result array
236236

237237

238238
## Release history
239239

240+
### v4.0.0 - 2017-11-22
241+
242+
**Changed**
243+
244+
- `options.quotes` should now be formatted as an object
245+
240246
### v3.0.0 - 2017-06-17
241247

242248
**Added**

example.js

+11-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
var split = require('./');
2-
// var arr = split('a.b', function(tok) {
3-
// if (tok.arr[tok.arr.length - 1] === 'a') {
4-
// tok.split = false;
2+
// var arr = split('a.b', function(token) {
3+
// if (token.arr[token.arr.length - 1] === 'a') {
4+
// token.split = false;
55
// }
66
// });
77
// console.log(arr);
@@ -11,3 +11,11 @@ var brackets = split('a.{a.{b.c}.}.c', {brackets: true});
1111
var brackets = split('a.{a.{b.c.}.c', {brackets: true});
1212
console.log(brackets);
1313
//=> ['a.b']
14+
15+
var res = split('a.b', function(token) {
16+
if (token.tokens[0] === 'a') {
17+
token.split = false;
18+
}
19+
});
20+
console.log(res);
21+
//=> ['a.b']

index.js

+69-59
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99

1010
var extend = require('extend-shallow');
1111

12-
module.exports = function(str, options, fn) {
13-
if (typeof str !== 'string') {
12+
module.exports = function(input, options, fn) {
13+
if (typeof input !== 'string') {
1414
throw new TypeError('expected a string');
1515
}
1616

@@ -21,23 +21,26 @@ module.exports = function(str, options, fn) {
2121

2222
// allow separator to be defined as a string
2323
if (typeof options === 'string') {
24-
options = { sep: options };
24+
options = { separator: options };
2525
}
2626

27-
var opts = extend({sep: '.'}, options);
28-
var quotes = opts.quotes || {
29-
'"': '"',
30-
"'": "'",
31-
'`': '`',
32-
'“': '”'
27+
var defaults = {
28+
separator: '.',
29+
doubleQuoteRegex: /^["]/,
30+
singleQuoteRegex: /^[']/,
31+
quoteRegex: /^['"`]/,
32+
quotes: {
33+
'"': '"',
34+
"'": "'",
35+
'`': '`',
36+
'‘': '’',
37+
'“': '”'
38+
}
3339
};
3440

35-
if (Array.isArray(quotes)) {
36-
quotes = quotes.reduce(function(acc, ele) {
37-
acc[ele] = ele;
38-
return acc;
39-
}, {});
40-
}
41+
var opts = extend({}, defaults, options);
42+
var sep = opts.sep || opts.separator;
43+
var quotes = opts.quotes;
4144

4245
var brackets;
4346
if (opts.brackets === true) {
@@ -51,57 +54,56 @@ module.exports = function(str, options, fn) {
5154
brackets = opts.brackets;
5255
}
5356

54-
var tokens = [];
55-
var stack = [];
56-
var arr = [''];
57-
var sep = opts.sep;
58-
var len = str.length;
59-
var idx = -1;
57+
var len = input.length;
58+
var index = -1;
6059
var closeIdx;
60+
var stack = [];
61+
var tokens = [''];
62+
var arr = [];
6163

6264
function expected() {
6365
if (brackets && stack.length) {
6466
return brackets[stack[stack.length - 1]];
6567
}
6668
}
6769

68-
while (++idx < len) {
69-
var ch = str[idx];
70-
var next = str[idx + 1];
71-
var tok = { val: ch, idx: idx, arr: arr, str: str };
72-
tokens.push(tok);
70+
while (++index < len) {
71+
var ch = input[index];
72+
var next = input[index + 1];
73+
var tok = { val: ch, index: index, tokens: tokens, input: input };
74+
arr.push(tok);
7375

7476
if (ch === '\\') {
75-
tok.val = keepEscaping(opts, str, idx) === true ? (ch + next) : next;
77+
tok.val = keepEscaping(opts, input, index) === true ? (ch + next) : next;
7678
tok.escaped = true;
7779
if (typeof fn === 'function') {
7880
fn(tok);
7981
}
80-
arr[arr.length - 1] += tok.val;
81-
idx++;
82+
tokens[tokens.length - 1] += tok.val;
83+
index++;
8284
continue;
8385
}
8486

8587
if (brackets && brackets[ch]) {
8688
stack.push(ch);
8789
var e = expected();
88-
var i = idx + 1;
90+
var i = index + 1;
8991

90-
if (str.indexOf(e, i + 1) !== -1) {
92+
if (input.indexOf(e, i + 1) !== -1) {
9193
while (stack.length && i < len) {
92-
var s = str[++i];
94+
var s = input[++i];
9395
if (s === '\\') {
9496
s++;
9597
continue;
9698
}
9799

98100
if (quotes[s]) {
99-
i = getClosingQuote(str, quotes[s], i + 1);
101+
i = getClosingQuote(input, quotes[s], i + 1);
100102
continue;
101103
}
102104

103105
e = expected();
104-
if (stack.length && str.indexOf(e, i + 1) === -1) {
106+
if (stack.length && input.indexOf(e, i + 1) === -1) {
105107
break;
106108
}
107109

@@ -118,66 +120,74 @@ module.exports = function(str, options, fn) {
118120

119121
closeIdx = i;
120122
if (closeIdx === -1) {
121-
arr[arr.length - 1] += ch;
123+
tokens[tokens.length - 1] += ch;
122124
continue;
123125
}
124126

125-
ch = str.slice(idx, closeIdx + 1);
127+
ch = input.slice(index, closeIdx + 1);
126128
tok.val = ch;
127-
tok.idx = idx = closeIdx;
129+
tok.index = index = closeIdx;
128130
}
129131

130132
if (quotes[ch]) {
131-
closeIdx = getClosingQuote(str, quotes[ch], idx + 1);
133+
closeIdx = getClosingQuote(input, quotes[ch], index + 1);
132134
if (closeIdx === -1) {
133-
arr[arr.length - 1] += ch;
135+
tokens[tokens.length - 1] += ch;
134136
continue;
135137
}
136138

137139
if (keepQuotes(ch, opts) === true) {
138-
ch = str.slice(idx, closeIdx + 1);
140+
ch = input.slice(index, closeIdx + 1);
139141
} else {
140-
ch = str.slice(idx + 1, closeIdx);
142+
ch = input.slice(index + 1, closeIdx);
141143
}
142144

143145
tok.val = ch;
144-
tok.idx = idx = closeIdx;
146+
tok.index = index = closeIdx;
145147
}
146148

147149
if (typeof fn === 'function') {
148-
fn(tok, tokens);
150+
fn(tok, arr);
149151
ch = tok.val;
150-
idx = tok.idx;
152+
index = tok.index;
151153
}
152154

153155
if (tok.val === sep && tok.split !== false) {
154-
arr.push('');
156+
tokens.push('');
155157
continue;
156158
}
157159

158-
arr[arr.length - 1] += tok.val;
160+
tokens[tokens.length - 1] += tok.val;
159161
}
160162

161-
return arr;
163+
return tokens;
162164
};
163165

164166
function getClosingQuote(str, ch, i, brackets) {
165-
var idx = str.indexOf(ch, i);
166-
if (str.charAt(idx - 1) === '\\') {
167-
return getClosingQuote(str, ch, idx + 1);
167+
var index = str.indexOf(ch, i);
168+
if (str.charAt(index - 1) === '\\') {
169+
return getClosingQuote(str, ch, index + 1);
168170
}
169-
return idx;
171+
return index;
170172
}
171173

172-
function keepQuotes(ch, opts) {
173-
if (opts.keepDoubleQuotes === true && (ch === '"' || ch === '“' || ch === '”')) return true;
174-
if (opts.keepSingleQuotes === true && ch === "'") return true;
175-
return opts.keepQuotes;
174+
function keepQuotes(ch, options) {
175+
if (options.keepDoubleQuotes === true && isDoubleQuote(ch, options)) return true;
176+
if (options.keepSingleQuotes === true && isSingleQuote(ch, options)) return true;
177+
return options.keepQuotes;
176178
}
177179

178-
function keepEscaping(opts, str, idx) {
179-
if (typeof opts.keepEscaping === 'function') {
180-
return opts.keepEscaping(str, idx);
180+
function keepEscaping(options, str, index) {
181+
if (typeof options.keepEscaping === 'function') {
182+
return options.keepEscaping(str, index);
181183
}
182-
return opts.keepEscaping === true || str[idx + 1] === '\\';
184+
return options.keepEscaping === true || str[index + 1] === '\\';
185+
}
186+
187+
function isDoubleQuote(ch, options) {
188+
return options.doubleQuoteRegex.test(ch);
189+
}
190+
191+
function isSingleQuote(ch, options) {
192+
return options.singleQuoteRegex.test(ch);
183193
}

test.js

+3-7
Original file line numberDiff line numberDiff line change
@@ -121,10 +121,6 @@ describe('split-string', function() {
121121
assert.deepEqual(split('a,b,c', {sep: ','}), ['a', 'b', 'c']);
122122
});
123123

124-
it('should allow custom quotes array', function() {
125-
assert.deepEqual(split('a.^b.c^', {quotes: ['^']}), ['a', 'b.c']);
126-
});
127-
128124
it('should allow custom quotes object', function() {
129125
assert.deepEqual(split('a.^b.c$', {quotes: {'^': '$'}}), ['a', 'b.c']);
130126
});
@@ -141,8 +137,8 @@ describe('split-string', function() {
141137
if (!/[@!*+]/.test(tok.val)) return;
142138
var stack = [];
143139
var val = tok.val;
144-
var str = tok.str;
145-
var i = tok.idx;
140+
var str = tok.input;
141+
var i = tok.index;
146142

147143
while (++i < str.length) {
148144
var ch = str[i];
@@ -161,8 +157,8 @@ describe('split-string', function() {
161157
}
162158

163159
tok.split = false;
160+
tok.index = i;
164161
tok.val = val;
165-
tok.idx = i;
166162
}
167163

168164
var opts = {sep: ',', brackets: null};

0 commit comments

Comments
 (0)