|
|
- /*!
- * split-string <https://github.com/jonschlinkert/split-string>
- *
- * Copyright (c) 2015-2017, Jon Schlinkert.
- * Released under the MIT License.
- */
-
- 'use strict';
-
- var extend = require('extend-shallow');
-
- module.exports = function(str, options, fn) {
- if (typeof str !== 'string') {
- throw new TypeError('expected a string');
- }
-
- if (typeof options === 'function') {
- fn = options;
- options = null;
- }
-
- // allow separator to be defined as a string
- if (typeof options === 'string') {
- options = { sep: options };
- }
-
- var opts = extend({sep: '.'}, options);
- var quotes = opts.quotes || ['"', "'", '`'];
- var brackets;
-
- if (opts.brackets === true) {
- brackets = {
- '<': '>',
- '(': ')',
- '[': ']',
- '{': '}'
- };
- } else if (opts.brackets) {
- brackets = opts.brackets;
- }
-
- var tokens = [];
- var stack = [];
- var arr = [''];
- var sep = opts.sep;
- var len = str.length;
- var idx = -1;
- var closeIdx;
-
- function expected() {
- if (brackets && stack.length) {
- return brackets[stack[stack.length - 1]];
- }
- }
-
- while (++idx < len) {
- var ch = str[idx];
- var next = str[idx + 1];
- var tok = { val: ch, idx: idx, arr: arr, str: str };
- tokens.push(tok);
-
- if (ch === '\\') {
- tok.val = keepEscaping(opts, str, idx) === true ? (ch + next) : next;
- tok.escaped = true;
- if (typeof fn === 'function') {
- fn(tok);
- }
- arr[arr.length - 1] += tok.val;
- idx++;
- continue;
- }
-
- if (brackets && brackets[ch]) {
- stack.push(ch);
- var e = expected();
- var i = idx + 1;
-
- if (str.indexOf(e, i + 1) !== -1) {
- while (stack.length && i < len) {
- var s = str[++i];
- if (s === '\\') {
- s++;
- continue;
- }
-
- if (quotes.indexOf(s) !== -1) {
- i = getClosingQuote(str, s, i + 1);
- continue;
- }
-
- e = expected();
- if (stack.length && str.indexOf(e, i + 1) === -1) {
- break;
- }
-
- if (brackets[s]) {
- stack.push(s);
- continue;
- }
-
- if (e === s) {
- stack.pop();
- }
- }
- }
-
- closeIdx = i;
- if (closeIdx === -1) {
- arr[arr.length - 1] += ch;
- continue;
- }
-
- ch = str.slice(idx, closeIdx + 1);
- tok.val = ch;
- tok.idx = idx = closeIdx;
- }
-
- if (quotes.indexOf(ch) !== -1) {
- closeIdx = getClosingQuote(str, ch, idx + 1);
- if (closeIdx === -1) {
- arr[arr.length - 1] += ch;
- continue;
- }
-
- if (keepQuotes(ch, opts) === true) {
- ch = str.slice(idx, closeIdx + 1);
- } else {
- ch = str.slice(idx + 1, closeIdx);
- }
-
- tok.val = ch;
- tok.idx = idx = closeIdx;
- }
-
- if (typeof fn === 'function') {
- fn(tok, tokens);
- ch = tok.val;
- idx = tok.idx;
- }
-
- if (tok.val === sep && tok.split !== false) {
- arr.push('');
- continue;
- }
-
- arr[arr.length - 1] += tok.val;
- }
-
- return arr;
- };
-
- function getClosingQuote(str, ch, i, brackets) {
- var idx = str.indexOf(ch, i);
- if (str.charAt(idx - 1) === '\\') {
- return getClosingQuote(str, ch, idx + 1);
- }
- return idx;
- }
-
- function keepQuotes(ch, opts) {
- if (opts.keepDoubleQuotes === true && ch === '"') return true;
- if (opts.keepSingleQuotes === true && ch === "'") return true;
- return opts.keepQuotes;
- }
-
- function keepEscaping(opts, str, idx) {
- if (typeof opts.keepEscaping === 'function') {
- return opts.keepEscaping(str, idx);
- }
- return opts.keepEscaping === true || str[idx + 1] === '\\';
- }
|