'use strict'; function isNodeType(node, type) { return node && node.type === type; } function serializeMultiplier(multiplier) { if (multiplier.min === 0 && multiplier.max === 0) { return '*'; } if (multiplier.min === 0 && multiplier.max === 1) { return '?'; } if (multiplier.min === 1 && multiplier.max === 0) { return multiplier.comma ? '#' : '+'; } if (multiplier.min === 1 && multiplier.max === 1) { return ''; } return ( (multiplier.comma ? '#' : '') + '{' + multiplier.min + (multiplier.min !== multiplier.max ? ',' + (multiplier.max !== 0 ? multiplier.max : '') : '') + '}' ); } function generateSequence(node, forceBraces, decorate) { var result = ''; if (node.explicit || forceBraces) { result += '[' + (!isNodeType(node.terms[0], 'Comma') ? ' ' : ''); } result += node.terms.map(function(term) { return generate(term, forceBraces, decorate); }).join(node.combinator === ' ' ? ' ' : ' ' + node.combinator + ' '); if (node.explicit || forceBraces) { result += ' ]'; } return result; } function generateParentheses(group, forceBraces, decorate) { if (!group.terms.length) { return '()'; } return '( ' + generateSequence(group, forceBraces, decorate) + ' )'; } function generate(node, forceBraces, decorate) { var result; switch (node.type) { case 'Group': result = generateSequence(node, forceBraces, decorate) + (node.disallowEmpty ? '!' : '') + serializeMultiplier(node.multiplier); break; case 'Keyword': result = node.name; break; case 'Function': result = node.name + generateParentheses(node.children, forceBraces, decorate); break; case 'Parentheses': // replace for seq('(' seq(...node.children) ')') result = generateParentheses(node.children, forceBraces, decorate); break; case 'Type': result = '<' + node.name + '>'; break; case 'Property': result = '<\'' + node.name + '\'>'; break; case 'Combinator': // remove? case 'Slash': // replace for String? '/' case 'Percent': // replace for String? '%' case 'String': case 'Comma': result = node.value; break; default: throw new Error('Unknown node type `' + node.type + '`'); } if (typeof decorate === 'function') { result = decorate(result, node); } return result; } module.exports = generate;