| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129 | 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);};
 |