(function () {

function serializeRules(rules) {
    return "[\n    " + rules.map(serializeRule).join(",\n    ") + "\n]";
}

function serializePostprocessor(p) {
    return p ? ', "postprocess": ' + p.toString()
             : '';
}

function serializeSymbol(s) {
    return (s instanceof RegExp) ? s.toString()
                                 : JSON.stringify(s);
}

function serializeRule(rule) {
    return '{'
        + '"name": ' + JSON.stringify(rule.name)
        + ', "symbols": [' + rule.symbols.map(serializeSymbol).join(', ') + ']'
        + serializePostprocessor(rule.postprocess)
        + '}';
}

var generate = function (parser, exportName) {
    var output = "// Generated automatically by nearley\n";
    output +=  "// http://github.com/Hardmath123/nearley\n";
    output += "(function () {\n";
    output += "function id(x) {return x[0]; }\n";
    output += parser.body.join('\n');
    output += "var grammar = {\n";
    output += "    ParserRules: " + serializeRules(parser.rules) + "\n";
    output += "  , ParserStart: " + JSON.stringify(parser.start) + "\n";
    output += "}\n";
    output += "if (typeof module !== 'undefined'"
        + "&& typeof module.exports !== 'undefined') {\n";
    output += "   module.exports = grammar;\n";
    output += "} else {\n";
    output += "   window." + exportName + " = grammar;\n";
    output += "}\n";
    output += "})();\n";
    return output;
};


if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') {
   module.exports = generate;
} else {
   window.generate = generate;
}
})();

@@ -131,40 +131,107 @@
 ion 
-serializePostprocessor(p
+dedentFunc(func) %7B%0A    var lines = func.toString().split(/%5Cn/);%0A%0A    if (lines.length === 1
 ) %7B%0A    
 retu
@@ -230,71 +230,355 @@
     
+   
+ 
 return 
-p ? ', %22postprocess%22: ' + p.toString()%0A             : ''
+%5Blines%5B0%5D.replace(/%5E%5Cs+%7C%5Cs+$/g, '')%5D;%0A    %7D%0A%0A    var match = /%5E%5Cs*/.exec(lines%5Blines.length-1%5D);%0A    var indent = match%5B0%5D;%0A    return lines%0A        .map(function dedent(line) %7B%0A            if (line.slice(0, indent.length) === indent) %7B%0A                return line.slice(indent.length);%0A            %7D%0A            return line;%0A        %7D)
 ;%0A%7D%0A
@@ -752,28 +752,33 @@
     
-return
+var ret =
  '%7B'
+;
 %0A
-  
     
- 
+ret
  +
+=
  '%22n
@@ -812,26 +812,28 @@
 le.name)
+;
 %0A
-   
     
+ret
  +
+=
  ', %22sym
@@ -898,73 +898,323 @@
  '%5D'
+;
 %0A    
-    + serializePostprocessor(rule.postprocess)%0A        + '%7D'
+if (rule.postprocess) %7B%0A        var lines = dedentFunc(rule.postprocess);%0A        ret += ', %22postprocess%22: ' + lines.map(function indent(line, i) %7B%0A            if (i %3E 0) %7B%0A                line = '    ' + line;%0A            %7D%0A            return line;%0A        %7D).join('%5Cn');%0A    %7D%0A    ret += '%7D';%0A    return ret
 ;%0A%7D%0A

rework postprocessor serialization to be more consistent