135 lines
3.5 KiB
JavaScript
135 lines
3.5 KiB
JavaScript
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 }
|
|
};
|
|
|
|
};
|