|
|
function noop(value) { return value; }
function generateMultiplier(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.max ? '{' + multiplier.min + '}' : '{' + multiplier.min + ',' + (multiplier.max !== 0 ? multiplier.max : '') + '}' ) ); }
function generateTypeOpts(node) { switch (node.type) { case 'Range': return ( ' [' + (node.min === null ? '-∞' : node.min) + ',' + (node.max === null ? '∞' : node.max) + ']' );
default: throw new Error('Unknown node type `' + node.type + '`'); } }
function generateSequence(node, decorate, forceBraces, compact) { var combinator = node.combinator === ' ' || compact ? node.combinator : ' ' + node.combinator + ' '; var result = node.terms.map(function(term) { return generate(term, decorate, forceBraces, compact); }).join(combinator);
if (node.explicit || forceBraces) { result = (compact || result[0] === ',' ? '[' : '[ ') + result + (compact ? ']' : ' ]'); }
return result; }
function generate(node, decorate, forceBraces, compact) { var result;
switch (node.type) { case 'Group': result = generateSequence(node, decorate, forceBraces, compact) + (node.disallowEmpty ? '!' : ''); break;
case 'Multiplier': // return since node is a composition
return ( generate(node.term, decorate, forceBraces, compact) + decorate(generateMultiplier(node), node) );
case 'Type': result = '<' + node.name + (node.opts ? decorate(generateTypeOpts(node.opts), node.opts) : '') + '>'; break;
case 'Property': result = '<\'' + node.name + '\'>'; break;
case 'Keyword': result = node.name; break;
case 'AtKeyword': result = '@' + node.name; break;
case 'Function': result = node.name + '('; break;
case 'String': case 'Token': result = node.value; break;
case 'Comma': result = ','; break;
default: throw new Error('Unknown node type `' + node.type + '`'); }
return decorate(result, node); }
module.exports = function(node, options) { var decorate = noop; var forceBraces = false; var compact = false;
if (typeof options === 'function') { decorate = options; } else if (options) { forceBraces = Boolean(options.forceBraces); compact = Boolean(options.compact); if (typeof options.decorate === 'function') { decorate = options.decorate; } }
return generate(node, decorate, forceBraces, compact); };
|