172 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			172 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| /*!
 | |
|  * 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] === '\\';
 | |
| }
 |