2 * split-string <https://github.com/jonschlinkert/split-string>
4 * Copyright (c) 2015-2017, Jon Schlinkert.
5 * Released under the MIT License.
10 var extend = require('extend-shallow');
12 module.exports = function(str, options, fn) {
13 if (typeof str !== 'string') {
14 throw new TypeError('expected a string');
17 if (typeof options === 'function') {
22 // allow separator to be defined as a string
23 if (typeof options === 'string') {
24 options = { sep: options };
27 var opts = extend({sep: '.'}, options);
28 var quotes = opts.quotes || ['"', "'", '`'];
31 if (opts.brackets === true) {
38 } else if (opts.brackets) {
39 brackets = opts.brackets;
51 if (brackets && stack.length) {
52 return brackets[stack[stack.length - 1]];
58 var next = str[idx + 1];
59 var tok = { val: ch, idx: idx, arr: arr, str: str };
63 tok.val = keepEscaping(opts, str, idx) === true ? (ch + next) : next;
65 if (typeof fn === 'function') {
68 arr[arr.length - 1] += tok.val;
73 if (brackets && brackets[ch]) {
78 if (str.indexOf(e, i + 1) !== -1) {
79 while (stack.length && i < len) {
86 if (quotes.indexOf(s) !== -1) {
87 i = getClosingQuote(str, s, i + 1);
92 if (stack.length && str.indexOf(e, i + 1) === -1) {
108 if (closeIdx === -1) {
109 arr[arr.length - 1] += ch;
113 ch = str.slice(idx, closeIdx + 1);
115 tok.idx = idx = closeIdx;
118 if (quotes.indexOf(ch) !== -1) {
119 closeIdx = getClosingQuote(str, ch, idx + 1);
120 if (closeIdx === -1) {
121 arr[arr.length - 1] += ch;
125 if (keepQuotes(ch, opts) === true) {
126 ch = str.slice(idx, closeIdx + 1);
128 ch = str.slice(idx + 1, closeIdx);
132 tok.idx = idx = closeIdx;
135 if (typeof fn === 'function') {
141 if (tok.val === sep && tok.split !== false) {
146 arr[arr.length - 1] += tok.val;
152 function getClosingQuote(str, ch, i, brackets) {
153 var idx = str.indexOf(ch, i);
154 if (str.charAt(idx - 1) === '\\') {
155 return getClosingQuote(str, ch, idx + 1);
160 function keepQuotes(ch, opts) {
161 if (opts.keepDoubleQuotes === true && ch === '"') return true;
162 if (opts.keepSingleQuotes === true && ch === "'") return true;
163 return opts.keepQuotes;
166 function keepEscaping(opts, str, idx) {
167 if (typeof opts.keepEscaping === 'function') {
168 return opts.keepEscaping(str, idx);
170 return opts.keepEscaping === true || str[idx + 1] === '\\';