UNPKG

css-doodle

Version:

A web component for drawing patterns with CSS

103 lines (92 loc) 2.55 kB
import { is_empty } from '../utils/index.js'; import { scan, iterator } from './tokenizer.js'; function parse(input, option = {symbol: ',', noSpace: false, verbose: false }) { let group = []; let skip = false; let tokens = []; let parenStack = []; let quoteStack = []; let lastGroupName = ''; let symbolList = option.symbol || ','; let symbolCounter = {}; let symbolCounterMax = {}; let symbolsToCompare = []; if (is_empty(input)) { return group; } if (!Array.isArray(symbolList)) { symbolList = [symbolList]; } symbolList.forEach(item => { let [symbol, max = Infinity] = String(item).split(/\s+/); symbolCounter[symbol] = 0; symbolCounterMax[symbol] = max; }); const allSymbols = Object.keys(symbolCounterMax); const iter = iterator(scan(input)); updateSymbols(); function updateSymbols() { symbolsToCompare = allSymbols.filter(s => { return symbolCounter[s] < symbolCounterMax[s]; }); } function isSeperator(token) { return option.noSpace ? token.isSymbol(symbolsToCompare) : (token.isSymbol(symbolsToCompare) || token.isSpace()); } function addGroup(tokens) { let value = joinTokens(tokens); if (option.verbose) { if (lastGroupName.length || value.length) { group.push({ group: lastGroupName, value }); } } else { group.push(value); } } while (iter.next()) { let { prev, curr, next } = iter.get(); if (curr.isSymbol('(')) { parenStack.push(curr.value); } if (curr.isSymbol(')')) { parenStack.pop(); } if (curr.status === 'open') { quoteStack.push(curr.value); } if (curr.status === 'close') { quoteStack.pop(); } let emptyStack = (!parenStack.length && !quoteStack.length); if (emptyStack) { let isNextSpace = option.noSpace && curr.isSpace() && isSeperator(next); let isPrevSpace = option.noSpace && curr.isSpace() && isSeperator(prev); if (curr.isSpace() && !tokens.length) { continue; } if (isNextSpace || isPrevSpace) { continue; } } if (emptyStack && isSeperator(curr)) { symbolCounter[curr.value] += 1; let groupName = lastGroupName; addGroup(tokens); lastGroupName = curr.value; tokens = []; updateSymbols(); } else { tokens.push(curr); } } if (tokens.length) { addGroup(tokens); } return group; } function joinTokens(tokens) { return tokens.map(n => n.value).join(''); } export default parse;