diff options
Diffstat (limited to 'lib/output.js')
-rw-r--r-- | lib/output.js | 134 |
1 files changed, 134 insertions, 0 deletions
diff --git a/lib/output.js b/lib/output.js new file mode 100644 index 00000000..2c4c6fdc --- /dev/null +++ b/lib/output.js @@ -0,0 +1,134 @@ +function OutputStream(options) { + options = defaults(options, { + indent_start : 0, + indent_level : 4, + quote_keys : false, + space_colon : false, + beautify : true, + ascii_only : false, + inline_script : false, + width : 80 + }); + + var indentation = 0; + var current_col = 0; + var OUTPUT = ""; + + function to_ascii(str) { + return str.replace(/[\u0080-\uffff]/g, function(ch) { + var code = ch.charCodeAt(0).toString(16); + while (code.length < 4) code = "0" + code; + return "\\u" + code; + }); + }; + + function make_string(str) { + var dq = 0, sq = 0; + str = str.replace(/[\\\b\f\n\r\t\x22\x27\u2028\u2029\0]/g, function(s){ + switch (s) { + case "\\": return "\\\\"; + case "\b": return "\\b"; + case "\f": return "\\f"; + case "\n": return "\\n"; + case "\r": return "\\r"; + case "\u2028": return "\\u2028"; + case "\u2029": return "\\u2029"; + case '"': ++dq; return '"'; + case "'": ++sq; return "'"; + case "\0": return "\\0"; + } + return s; + }); + if (options.ascii_only) str = to_ascii(str); + if (dq > sq) return "'" + str.replace(/\x27/g, "\\'") + "'"; + else return '"' + str.replace(/\x22/g, '\\"') + '"'; + }; + + function print(str) { + var nl = str.lastIndexOf("\n"); + if (nl >= 0) { + current_col = nl; + } else { + current_col += str.length; + } + OUTPUT += str; + }; + + function encode_string(str) { + var ret = make_string(str); + if (options.inline_script) + ret = ret.replace(/<\x2fscript([>\/\t\n\f\r ])/gi, "<\\/script$1"); + return ret; + }; + + function make_name(name) { + name = name.toString(); + if (options.ascii_only) + name = to_ascii(name); + return name; + }; + + function make_indent(line) { + if (line == null) + line = ""; + if (beautify) + line = repeat_string(" ", options.indent_start + indentation) + line; + return line; + }; + + function with_indent(col, cont) { + var save_indentation = indentation; + indentation = col; + var ret = cont(); + indentation = save_indentation; + return ret; + }; + + function indent() { + if (options.beautify) print(make_indent()); + }; + + function newline() { + if (options.beautify) { + print("\n"); + print(make_indent()); + } + }; + + function next_indent() { + return indentation + options.indent_level; + }; + + function with_block(cont) { + var ret; + print("{"); + with_indent(next_indent(), function(){ + newline(); + ret = cont(); + newline(); + }); + indent(); + print("}"); + return ret; + }; + + function with_parens(cont) { + print("("); + var ret = with_indent(current_col, cont); + print(")"); + return ret; + }; + + return { + get : function() { return OUTPUT }, + indent : indent, + newline : newline, + print : print, + string : function(str) { print(encode_string(str)) }, + with_indent : with_indent, + with_block : with_block, + with_parens : with_parens, + options : function() { return options } + }; + +}; |