-
Notifications
You must be signed in to change notification settings - Fork 20
/
Copy pathneatjson.js
144 lines (136 loc) · 6.75 KB
/
neatjson.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
(function(exports){
exports.neatJSON = neatJSON;
function neatJSON(value,opts){
opts = opts || {}
if (!('wrap' in opts)) opts.wrap = 80;
if (opts.wrap==true) opts.wrap = -1;
if (!('indent' in opts)) opts.indent = ' ';
if (!('arrayPadding' in opts)) opts.arrayPadding = ('padding' in opts) ? opts.padding : 0;
if (!('objectPadding' in opts)) opts.objectPadding = ('padding' in opts) ? opts.padding : 0;
if (!('beforeComma' in opts)) opts.beforeComma = ('aroundComma' in opts) ? opts.aroundComma : 0;
if (!('afterComma' in opts)) opts.afterComma = ('aroundComma' in opts) ? opts.aroundComma : 0;
if (!('beforeColon' in opts)) opts.beforeColon = ('aroundColon' in opts) ? opts.aroundColon : 0;
if (!('afterColon' in opts)) opts.afterColon = ('aroundColon' in opts) ? opts.aroundColon : 0;
if (!('beforeColon1' in opts)) opts.beforeColon1 = ('aroundColon1' in opts) ? opts.aroundColon1 : ('beforeColon' in opts) ? opts.beforeColon : 0;
if (!('afterColon1' in opts)) opts.afterColon1 = ('aroundColon1' in opts) ? opts.aroundColon1 : ('afterColon' in opts) ? opts.afterColon : 0;
if (!('beforeColonN' in opts)) opts.beforeColonN = ('aroundColonN' in opts) ? opts.aroundColonN : ('beforeColon' in opts) ? opts.beforeColon : 0;
if (!('afterColonN' in opts)) opts.afterColonN = ('aroundColonN' in opts) ? opts.aroundColonN : ('afterColon' in opts) ? opts.afterColon : 0;
if (!('forceFloatsIn' in opts)) opts.forceFloatsIn = [];
const apad = repeat(' ',opts.arrayPadding),
opad = repeat(' ',opts.objectPadding),
comma = repeat(' ',opts.beforeComma)+','+repeat(' ',opts.afterComma),
colon1 = repeat(' ',opts.beforeColon1)+':'+repeat(' ',opts.afterColon1),
colonN = repeat(' ',opts.beforeColonN)+':'+repeat(' ',opts.afterColonN);
const build = memoize();
return build(value,'',opts.forceFloats);
function memoize(){
const memo = new Map;
return function(o,indent,floatsForced){
const byFloats = floatsForced ? {o,floatsForced} : o;
let byIndent=memo.get(byFloats);
if (!byIndent) memo.set(byFloats,byIndent={});
if (!byIndent[indent]) byIndent[indent] = rawBuild(o,indent,floatsForced);
return byIndent[indent];
}
}
function rawBuild(o,indent,floatsForced){
if (o===null || o===undefined) return indent+'null';
else{
if (typeof o==='number'){
if (o===Infinity) {
return indent+'9e9999';
}else if (o===-Infinity){
return indent+'-9e9999';
}else if (Number.isNaN(o)){
return indent+'"NaN"';
}else{
const treatAsFloat = floatsForced || (o === +o && o !== (o|0));
let result = ((treatAsFloat && ('decimals' in opts)) ? o.toFixed(opts.decimals) : (o+''));
if (opts.trimTrailingZeros) result = (+result)+'';
if (floatsForced && result.indexOf('.')==-1) result += '.0';
return indent + result;
}
}else if (o instanceof Array){
if (!o.length) return indent+"[]";
let pieces = o.map(function(v){ return build(v,'',floatsForced) });
const oneLine = indent+'['+apad+pieces.join(comma)+apad+']';
if (opts.wrap===false || oneLine.length<=opts.wrap) return oneLine;
if (opts.short){
const indent2 = indent+' '+apad;
pieces = o.map(function(v){ return build(v,indent2,floatsForced) });
pieces[0] = pieces[0].replace(indent2,indent+'['+apad);
pieces[pieces.length-1] = pieces[pieces.length-1]+apad+']';
return pieces.join(',\n');
}else{
const indent2 = indent+opts.indent;
return indent+'[\n'+o.map(function(v){ return build(v,indent2,floatsForced) }).join(',\n')+'\n'+(opts.indentLast?indent2:indent)+']';
}
}else if (o instanceof Object){
let sortedKV=[], i=0;
const sort = opts.sort || opts.sorted;
for (let k in o){
const kv = sortedKV[i++] = [k,o[k]];
if (sort===true) kv[2] = k;
else if (typeof sort==='function') kv[2]=sort(k,o[k],o);
}
if (!sortedKV.length) return indent+'{}';
if (sort) sortedKV = sortedKV.sort(function(a,b){ a=a[2]; b=b[2]; return a<b?-1:a>b?1:0 });
const sortedKeys = sortedKV.map(([k]) => k);
let keyvals=sortedKV.map(([k,v],i) => [JSON.stringify(k), build(v,'',(opts.forceFloats || opts.forceFloatsIn.includes(k)))].join(colon1) ).join(comma);
const oneLine = indent+"{"+opad+keyvals+opad+"}";
if (opts.wrap===false || oneLine.length<opts.wrap) return oneLine;
if (opts.short){
keyvals = sortedKV.map(function(kv){ return [indent+' '+opad+JSON.stringify(kv[0]), kv[1]] });
keyvals[0][0] = keyvals[0][0].replace(indent+' ',indent+'{');
if (opts.aligned){
let longest = 0;
for (let i=keyvals.length;i--;) if (keyvals[i][0].length>longest) longest = keyvals[i][0].length;
const padding = repeat(' ',longest);
for (let i=keyvals.length;i--;) keyvals[i][0] = padRight(padding,keyvals[i][0]);
}
for (let i=keyvals.length;i--;){
let k=keyvals[i][0], v=keyvals[i][1];
const indent2 = repeat(' ',(k+colonN).length);
floatsForced = (opts.forceFloats || opts.forceFloatsIn.includes(sortedKeys[i]));
const oneLine = k+colonN+build(v,'',floatsForced);
keyvals[i] = (opts.wrap===false || oneLine.length<=opts.wrap || !v || typeof v!="object") ? oneLine : (k+colonN+build(v,indent2,floatsForced).replace(/^\s+/,''));
}
return keyvals.join(',\n') + opad + '}';
}else{
const keyvals=sortedKV.map(function(kvs){ kvs[0] = indent+opts.indent+JSON.stringify(kvs[0]); return kvs });
if (opts.aligned){
let longest = 0;
for (let i=keyvals.length;i--;) if (keyvals[i][0].length>longest) longest = keyvals[i][0].length;
const padding = repeat(' ',longest);
for (let i=keyvals.length;i--;) keyvals[i][0] = padRight(padding,keyvals[i][0]);
}
const indent2 = indent+opts.indent;
for (let i=keyvals.length;i--;){
const k=keyvals[i][0], v=keyvals[i][1];
floatsForced = opts.forceFloats || opts.forceFloatsIn.includes(sortedKeys[i]);
const oneLine = k+colonN+build(v,'',floatsForced);
keyvals[i] = (opts.wrap===false || oneLine.length<=opts.wrap || !v || typeof v!="object") ? oneLine : (k+colonN+build(v,indent2,floatsForced).replace(/^\s+/,''));
}
return indent+'{\n'+keyvals.join(',\n')+'\n'+(opts.indentLast?indent2:indent)+'}'
}
}else{
return indent+JSON.stringify(o);
}
}
}
function repeat(str,times){ // http://stackoverflow.com/a/17800645/405017
let result = '';
while(true){
if (times & 1) result += str;
times >>= 1;
if (times) str += str;
else break;
}
return result;
}
function padRight(pad, str){
return (str + pad).substring(0, pad.length);
}
}
neatJSON.version = "0.10.6";
})(typeof exports === 'undefined' ? this : exports);