blob: 6ad80ef635a7482f9c76a7144c0be8abd386cbad [file] [log] [blame]
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 generateSequence(node, forceBraces, decorate) {
var result = node.terms.map(function(term) {
return generate(term, forceBraces, decorate);
}).join(node.combinator === ' ' ? ' ' : ' ' + node.combinator + ' ');
if (node.explicit || forceBraces) {
result = (result[0] !== ',' ? '[ ' : '[') + result + ' ]';
}
return result;
}
function generate(node, forceBraces, decorate) {
var result;
switch (node.type) {
case 'Group':
result =
generateSequence(node, forceBraces, decorate) +
(node.disallowEmpty ? '!' : '');
break;
case 'Multiplier':
// return since node is a composition
return (
generate(node.term, forceBraces, decorate) +
decorate(generateMultiplier(node), node)
);
case 'Type':
result = '<' + node.name + '>';
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;
if (typeof options === 'function') {
decorate = options;
} else if (options) {
forceBraces = Boolean(options.forceBraces);
if (typeof options.decorate === 'function') {
decorate = options.decorate;
}
}
return generate(node, forceBraces, decorate);
};