aboutsummaryrefslogtreecommitdiff
path: root/lib/output.js
diff options
context:
space:
mode:
Diffstat (limited to 'lib/output.js')
-rw-r--r--lib/output.js134
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 }
+ };
+
+};