neatjson 0.3.4 → 0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +3 -0
- data/html/neatjson.html +151 -0
- data/html/neatjson.js +106 -0
- data/lib/neatjson.rb +6 -6
- data/neatjson.gemspec +2 -2
- metadata +10 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ffd7e1b6d8e702a1ac021f7c8dceb24bce52b4a6
|
4
|
+
data.tar.gz: 956fa2524dd0f720b04b932fef9ce133311b49bf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c41fa707a6227ac5eec7673626f5e0dddcde3f37b946788b6625f9ac22613e93493f0fb02616215550c7af19eb22f33098a856778826238e7e62d3d9b9b73ec9
|
7
|
+
data.tar.gz: 8b1f03bdb86c45d6a6b28197b5e7cfd0091dd8f8feab2123d1a4a758da2c0341e5a533098c1a1a03ac49a04e2dc68a23a3cb5d453ce82c746e14f383e96ccce5
|
data/README.md
CHANGED
@@ -157,6 +157,9 @@ For other communication you can [email the author directly](mailto:!@phrogz.net?
|
|
157
157
|
|
158
158
|
## HISTORY
|
159
159
|
|
160
|
+
* **v0.4** - April 18th, 2015
|
161
|
+
* Add JavaScript version with online runner.
|
162
|
+
|
160
163
|
* **v0.3.2** - April 16th, 2015
|
161
164
|
* Force YARD to use Markdown for documentation.
|
162
165
|
|
data/html/neatjson.html
ADDED
@@ -0,0 +1,151 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html><head>
|
3
|
+
<meta charset="utf-8">
|
4
|
+
<title>NeatJSON Online</title>
|
5
|
+
<style type="text/css">
|
6
|
+
h1 { background:#444; color:#ccc; text-align:center; margin:0; padding:0.2em 0; margin-bottom:1em; }
|
7
|
+
html, body { height:100%; min-height:100%; padding:0; margin:0; background:#eee; }
|
8
|
+
#input, #output, #code { display:block; width:90%; margin:1em auto; height:35%; background:#fff; }
|
9
|
+
#code { height:1em; background:none; }
|
10
|
+
#output { border:1px solid green; background:rgba(100,255,0,0.5); color:#080 }
|
11
|
+
label { padding-right:0.6em }
|
12
|
+
#options { width:90%; margin:1em auto }
|
13
|
+
.option { display:inline-block; margin-right:2em; user-select:none; -webkit-user-select:none; }
|
14
|
+
input[type="range"] { width:5em }
|
15
|
+
b { background:yellow }
|
16
|
+
</style>
|
17
|
+
</head><body>
|
18
|
+
<h1>NeatJSON Online v0.4</h1>
|
19
|
+
<div id="options">
|
20
|
+
<div class="option-row">
|
21
|
+
<span class="option">
|
22
|
+
<label><input type="checkbox" id="wrap" checked> Wrap?</label>
|
23
|
+
<label id="wrapopts1">width <input type="text" id="wrapSize" value="40" size="3"></label>
|
24
|
+
<label id="wrapopts2"><input type="checkbox" id="short"> Short?</label>
|
25
|
+
<label id="wrapopts3"><input type="checkbox" id="aligned"> Align Keys?</label>
|
26
|
+
</span>
|
27
|
+
<span class="option"><label><input type="checkbox" id="sorted"> Sort Keys?</label></span>
|
28
|
+
<span class="option">
|
29
|
+
<label><input type="checkbox" id="useDecimals"> Format Decimals?</label>
|
30
|
+
<input type="text" id="decimals" value="3" size="3" min="0" max="10" style="visibility:hidden">
|
31
|
+
</span>
|
32
|
+
</div><div class="option-row">
|
33
|
+
<span class="option"><label>Indent Spaces <input type="range" id="indent" value="2" min="0" max="5" step="1"></label></span>
|
34
|
+
<span class="option"><label>Array Padding<input type="range" id="arrayPadding" value="0" min="0" max="3" step="1"></label></span>
|
35
|
+
<span class="option"><label>Object Padding<input type="range" id="objectPadding" value="0" min="0" max="3" step="1"></label></span>
|
36
|
+
</div><div class="option-row">
|
37
|
+
<span class="option"><label>Before Comma<input type="range" id="beforeComma" value="0" min="0" max="3" step="1"></label></span>
|
38
|
+
<span class="option"><label>After Comma<input type="range" id="afterComma" value="0" min="0" max="3" step="1"></label></span>
|
39
|
+
<span class="option"><label>Before Colon<input type="range" id="beforeColon" value="0" min="0" max="3" step="1"></label></span>
|
40
|
+
<span class="option"><label>After Colon<input type="range" id="afterColon" value="0" min="0" max="3" step="1"></label></span>
|
41
|
+
</div>
|
42
|
+
</div>
|
43
|
+
|
44
|
+
<textarea id="input">["foo","bar",{"dogs":42,"piggies":0,"cats":7},{"jimmy":[1,2,3,4,5],"jammy":3.14159265358979,"hot":"pajammy"}]</textarea>
|
45
|
+
<pre id="code"></pre>
|
46
|
+
<pre id="output"></pre>
|
47
|
+
<script type="text/javascript" src="neatjson.js"></script>
|
48
|
+
<script type="text/javascript">
|
49
|
+
var opts = document.querySelectorAll('input');
|
50
|
+
[].forEach.call(opts,function(opt){
|
51
|
+
opt.addEventListener('input',neaten,false);
|
52
|
+
opt.addEventListener('change',neaten,false);
|
53
|
+
opt.addEventListener('click',neaten,false);
|
54
|
+
})
|
55
|
+
|
56
|
+
var inp = document.querySelector('#input'),
|
57
|
+
cde = document.querySelector('#code'),
|
58
|
+
out = document.querySelector('#output');
|
59
|
+
var opts;
|
60
|
+
|
61
|
+
var wrap = document.querySelector('#wrap'),
|
62
|
+
wdth = document.querySelector('#wrapSize'),
|
63
|
+
shrt = document.querySelector('#short'),
|
64
|
+
dec0 = document.querySelector('#useDecimals'),
|
65
|
+
decN = document.querySelector('#decimals'),
|
66
|
+
sort = document.querySelector('#sorted'),
|
67
|
+
algn = document.querySelector('#aligned'),
|
68
|
+
indN = document.querySelector('#indent'),
|
69
|
+
arrayPadding = document.querySelector('#arrayPadding'),
|
70
|
+
objectPadding = document.querySelector('#objectPadding'),
|
71
|
+
beforeComma = document.querySelector('#beforeComma'),
|
72
|
+
afterComma = document.querySelector('#afterComma'),
|
73
|
+
beforeColon = document.querySelector('#beforeColon'),
|
74
|
+
afterColon = document.querySelector('#afterColon');
|
75
|
+
|
76
|
+
window.onload = neaten;
|
77
|
+
inp.addEventListener('input',neaten,false);
|
78
|
+
|
79
|
+
function neaten(){
|
80
|
+
try{
|
81
|
+
changeOptions();
|
82
|
+
if (isEmpty(opts)){
|
83
|
+
code.innerHTML = "var json = neatJSON(obj);";
|
84
|
+
}else{
|
85
|
+
var parts=[];
|
86
|
+
for (var k in opts) parts.push('<b>'+k+'</b>:'+JSON.stringify(opts[k]));
|
87
|
+
code.innerHTML = "var json = neatJSON(obj,{ "+parts.join(', ')+" });";
|
88
|
+
}
|
89
|
+
out.innerHTML = neatJSON(JSON.parse(inp.value),opts);
|
90
|
+
}catch(e){
|
91
|
+
out.innerHTML = e;
|
92
|
+
}
|
93
|
+
}
|
94
|
+
|
95
|
+
function changeOptions() {
|
96
|
+
opts = {};
|
97
|
+
if (!wrap.checked || wdth.value!=80) opts.wrap = wrap.checked ? (wdth.value=='' ? true : wdth.value*1) : false;
|
98
|
+
if (wrap.checked && shrt.checked) opts.short = true;
|
99
|
+
document.querySelector('#wrapopts1').style.visibility = wrap.checked ? '' : 'hidden';
|
100
|
+
document.querySelector('#wrapopts2').style.visibility = wrap.checked ? '' : 'hidden';
|
101
|
+
document.querySelector('#wrapopts3').style.visibility = wrap.checked ? '' : 'hidden';
|
102
|
+
|
103
|
+
if (indN.value!=2 && (wrap.checked && !shrt.checked)) opts.indent = repeat(' ',indN.value*1);
|
104
|
+
|
105
|
+
if (dec0.checked){
|
106
|
+
opts.decimals = decN.value*1;
|
107
|
+
decN.style.visibility = '';
|
108
|
+
}else{
|
109
|
+
decN.style.visibility = 'hidden';
|
110
|
+
}
|
111
|
+
|
112
|
+
if (sort.checked) opts.sorted = true;
|
113
|
+
if (wrap.checked && algn.checked) opts.aligned = true;
|
114
|
+
|
115
|
+
if (arrayPadding.value!=0 && objectPadding.value==arrayPadding.value){
|
116
|
+
opts.padding = arrayPadding.value*1;
|
117
|
+
}else{
|
118
|
+
if (arrayPadding.value!=0) opts.arrayPadding = arrayPadding.value*1;
|
119
|
+
if (objectPadding.value!=0) opts.objectPadding = objectPadding.value*1;
|
120
|
+
}
|
121
|
+
if (beforeComma.value!=0 && beforeComma.value==afterComma.value){
|
122
|
+
opts.aroundComma = beforeComma.value*1;
|
123
|
+
}else{
|
124
|
+
if (beforeComma.value!=0) opts.beforeComma = beforeComma.value*1;
|
125
|
+
if (afterComma.value!=0) opts.afterComma = afterComma.value*1;
|
126
|
+
}
|
127
|
+
if (beforeColon.value!=0 && beforeColon.value==afterColon.value){
|
128
|
+
opts.aroundColon = beforeColon.value*1;
|
129
|
+
}else{
|
130
|
+
if (beforeColon.value!=0) opts.beforeColon = beforeColon.value*1;
|
131
|
+
if (afterColon.value!=0) opts.afterColon = afterColon.value*1;
|
132
|
+
}
|
133
|
+
}
|
134
|
+
|
135
|
+
function repeat(str,times){ // http://stackoverflow.com/a/17800645/405017
|
136
|
+
var result = '';
|
137
|
+
while(true){
|
138
|
+
if (times & 1) result += str;
|
139
|
+
times >>= 1;
|
140
|
+
if (times) str += str;
|
141
|
+
else break;
|
142
|
+
}
|
143
|
+
return result;
|
144
|
+
}
|
145
|
+
|
146
|
+
function isEmpty(obj){
|
147
|
+
for (var k in obj) return false;
|
148
|
+
return true;
|
149
|
+
}
|
150
|
+
</script>
|
151
|
+
</body></html>
|
data/html/neatjson.js
ADDED
@@ -0,0 +1,106 @@
|
|
1
|
+
function neatJSON(value,opts){
|
2
|
+
opts = opts || {}
|
3
|
+
if (!('wrap' in opts)) opts.wrap = 80;
|
4
|
+
if (opts.wrap==true) opts.wrap = -1;
|
5
|
+
if (!('indent' in opts)) opts.indent = ' ';
|
6
|
+
if (!('arrayPadding' in opts)) opts.arrayPadding = ('padding' in opts) ? opts.padding : 0;
|
7
|
+
if (!('objectPadding' in opts)) opts.objectPadding = ('padding' in opts) ? opts.padding : 0;
|
8
|
+
if (!('afterComma' in opts)) opts.afterComma = ('aroundComma' in opts) ? opts.aroundComma : 0;
|
9
|
+
if (!('beforeComma' in opts)) opts.beforeComma = ('aroundComma' in opts) ? opts.aroundComma : 0;
|
10
|
+
if (!('afterColon' in opts)) opts.afterColon = ('aroundColon' in opts) ? opts.aroundColon : 0;
|
11
|
+
if (!('beforeColon' in opts)) opts.beforeColon = ('aroundColon' in opts) ? opts.aroundColon : 0;
|
12
|
+
|
13
|
+
var apad = repeat(' ',opts.arrayPadding),
|
14
|
+
opad = repeat(' ',opts.objectPadding),
|
15
|
+
comma = repeat(' ',opts.beforeComma)+','+repeat(' ',opts.afterComma),
|
16
|
+
colon = repeat(' ',opts.beforeColon)+':'+repeat(' ',opts.afterColon);
|
17
|
+
|
18
|
+
return build(value,'');
|
19
|
+
|
20
|
+
function build(o,indent){
|
21
|
+
if (o===null || o===undefined) return indent+'null';
|
22
|
+
else{
|
23
|
+
switch(o.constructor){
|
24
|
+
case Number:
|
25
|
+
return indent + (('decimals' in opts) ? o.toFixed(opts.decimals) : (o+''));
|
26
|
+
|
27
|
+
case Array:
|
28
|
+
var pieces = o.map(function(v){ return build(v,'') });
|
29
|
+
var oneLine = indent+'['+apad+pieces.join(comma)+apad+']';
|
30
|
+
if (opts.wrap===false || oneLine.length<=opts.wrap) return oneLine;
|
31
|
+
if (opts.short){
|
32
|
+
var indent2 = indent+' '+apad;
|
33
|
+
pieces = o.map(function(v){ return build(v,indent2) });
|
34
|
+
pieces[0] = pieces[0].replace(indent2,indent+'['+apad);
|
35
|
+
pieces[pieces.length-1] = pieces[pieces.length-1]+apad+']';
|
36
|
+
return pieces.join(',\n');
|
37
|
+
}else{
|
38
|
+
var indent2 = indent+opts.indent;
|
39
|
+
return indent+'[\n'+o.map(function(v){ return build(v,indent2) }).join(',\n')+'\n'+indent+']';
|
40
|
+
}
|
41
|
+
|
42
|
+
case Object:
|
43
|
+
var keyvals=[],i=0;
|
44
|
+
for (var k in o) keyvals[i++] = [JSON.stringify(k), build(o[k],'')];
|
45
|
+
if (opts.sorted) keyvals = keyvals.sort(function(kv1,kv2){ kv1=kv1[0]; kv2=kv2[0]; return kv1<kv2?-1:kv1>kv2?1:0 });
|
46
|
+
keyvals = keyvals.map(function(kv){ return kv.join(colon) }).join(comma);
|
47
|
+
var oneLine = indent+"{"+opad+keyvals+opad+"}";
|
48
|
+
if (opts.wrap===false || oneLine.length<opts.wrap) return oneLine;
|
49
|
+
if (opts.short){
|
50
|
+
var keyvals=[],i=0;
|
51
|
+
for (var k in o) keyvals[i++] = [indent+' '+opad+JSON.stringify(k),o[k]];
|
52
|
+
if (opts.sorted) keyvals = keyvals.sort(function(kv1,kv2){ kv1=kv1[0]; kv2=kv2[0]; return kv1<kv2?-1:kv1>kv2?1:0 });
|
53
|
+
keyvals[0][0] = keyvals[0][0].replace(indent+' ',indent+'{');
|
54
|
+
if (opts.aligned){
|
55
|
+
var longest = 0;
|
56
|
+
for (var i=keyvals.length;i--;) if (keyvals[i][0].length>longest) longest = keyvals[i][0].length;
|
57
|
+
var padding = repeat(' ',longest);
|
58
|
+
for (var i=keyvals.length;i--;) keyvals[i][0] = padRight(padding,keyvals[i][0]);
|
59
|
+
}
|
60
|
+
for (var i=keyvals.length;i--;){
|
61
|
+
var k=keyvals[i][0], v=keyvals[i][1];
|
62
|
+
var indent2 = repeat(' ',(k+colon).length);
|
63
|
+
var oneLine = k+colon+build(v,'');
|
64
|
+
// console.log(opts.wrap, oneLine.length, !v, typeof v)
|
65
|
+
keyvals[i] = (opts.wrap===false || oneLine.length<=opts.wrap || !v || typeof v!="object") ? oneLine : (k+colon+build(v,indent2).replace(/^\s+/,''));
|
66
|
+
}
|
67
|
+
return keyvals.join(',\n') + opad + '}';
|
68
|
+
}else{
|
69
|
+
var keyvals=[],i=0;
|
70
|
+
for (var k in o) keyvals[i++] = [indent+opts.indent+JSON.stringify(k),o[k]];
|
71
|
+
if (opts.sorted) keyvals = keyvals.sort(function(kv1,kv2){ kv1=kv1[0]; kv2=kv2[0]; return kv1<kv2?-1:kv1>kv2?1:0 });
|
72
|
+
if (opts.aligned){
|
73
|
+
var longest = 0;
|
74
|
+
for (var i=keyvals.length;i--;) if (keyvals[i][0].length>longest) longest = keyvals[i][0].length;
|
75
|
+
var padding = repeat(' ',longest);
|
76
|
+
for (var i=keyvals.length;i--;) keyvals[i][0] = padRight(padding,keyvals[i][0]);
|
77
|
+
}
|
78
|
+
var indent2 = indent+opts.indent;
|
79
|
+
for (var i=keyvals.length;i--;){
|
80
|
+
var k=keyvals[i][0], v=keyvals[i][1];
|
81
|
+
var oneLine = k+colon+build(v,'');
|
82
|
+
keyvals[i] = (opts.wrap===false || oneLine.length<=opts.wrap || !v || typeof v!="object") ? oneLine : (k+colon+build(v,indent2).replace(/^\s+/,''));
|
83
|
+
}
|
84
|
+
return indent+'{\n'+keyvals.join(',\n')+'\n'+indent+'}'
|
85
|
+
}
|
86
|
+
|
87
|
+
default:
|
88
|
+
return indent+JSON.stringify(o);
|
89
|
+
}
|
90
|
+
}
|
91
|
+
}
|
92
|
+
|
93
|
+
function repeat(str,times){ // http://stackoverflow.com/a/17800645/405017
|
94
|
+
var result = '';
|
95
|
+
while(true){
|
96
|
+
if (times & 1) result += str;
|
97
|
+
times >>= 1;
|
98
|
+
if (times) str += str;
|
99
|
+
else break;
|
100
|
+
}
|
101
|
+
return result;
|
102
|
+
}
|
103
|
+
function padRight(pad, str){
|
104
|
+
return (str + pad).substring(0, pad.length);
|
105
|
+
}
|
106
|
+
}
|
data/lib/neatjson.rb
CHANGED
@@ -58,19 +58,20 @@ module JSON
|
|
58
58
|
if !opts[:wrap] || (one_line.length <= opts[:wrap])
|
59
59
|
one_line
|
60
60
|
elsif opts[:short]
|
61
|
-
|
62
|
-
pieces
|
61
|
+
indent2 = "#{indent} #{apad}"
|
62
|
+
pieces = o.map{ |v| build[ v,indent2 ] }
|
63
|
+
pieces[0].sub! indent2, "#{indent}[#{apad}"
|
63
64
|
pieces.last << apad << "]"
|
64
65
|
pieces.join ",\n"
|
65
66
|
else
|
66
67
|
indent2 = "#{indent}#{opts[:indent]}"
|
67
|
-
"#{indent}[\n#{o.map{ |
|
68
|
+
"#{indent}[\n#{o.map{ |v| build[ v, indent2 ] }.join ",\n"}\n#{indent}]"
|
68
69
|
end
|
69
70
|
|
70
71
|
when Hash
|
71
72
|
keyvals = o.map{ |k,v| [ k.to_s.inspect, build[v,''] ] }
|
72
73
|
keyvals = keyvals.sort_by(&:first) if opts[:sorted]
|
73
|
-
keyvals = keyvals.map{ |
|
74
|
+
keyvals = keyvals.map{ |kv| kv.join(colon) }.join(comma)
|
74
75
|
one_line = "#{indent}{#{opad}#{keyvals}#{opad}}"
|
75
76
|
if !opts[:wrap] || (one_line.length <= opts[:wrap])
|
76
77
|
one_line
|
@@ -92,8 +93,7 @@ module JSON
|
|
92
93
|
one_line
|
93
94
|
end
|
94
95
|
end
|
95
|
-
keyvals.
|
96
|
-
keyvals.join ",\n"
|
96
|
+
keyvals.join(",\n") << opad << "}"
|
97
97
|
else
|
98
98
|
keyvals = o.map{ |k,v| ["#{indent}#{opts[:indent]}#{k.to_s.inspect}",v] }
|
99
99
|
keyvals = keyvals.sort_by(&:first) if opts[:sorted]
|
data/neatjson.gemspec
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
require 'date'
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = "neatjson"
|
5
|
-
s.version = "0.
|
5
|
+
s.version = "0.4"
|
6
6
|
s.date = Date.today.iso8601
|
7
7
|
s.authors = ["Gavin Kistner"]
|
8
8
|
s.email = "gavin@phrogz.net"
|
@@ -12,6 +12,6 @@ Gem::Specification.new do |s|
|
|
12
12
|
s.license = "MIT license (MIT)"
|
13
13
|
s.platform = Gem::Platform::RUBY
|
14
14
|
s.require_paths = ['lib']
|
15
|
-
s.files = Dir.glob("{lib,test}/**/*") + ['LICENSE.txt', 'README.md', '.yardopts', __FILE__]
|
15
|
+
s.files = Dir.glob("{lib,test,html}/**/*") + ['LICENSE.txt', 'README.md', '.yardopts', __FILE__]
|
16
16
|
s.has_rdoc = 'yard'
|
17
17
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: neatjson
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: '0.4'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Gavin Kistner
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-04-
|
11
|
+
date: 2015-04-18 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Generate JSON strings from Ruby objects with flexible formatting options.
|
14
14
|
The most important feature is that it can behave like pp, keeping arrays and objects
|
@@ -18,12 +18,14 @@ executables: []
|
|
18
18
|
extensions: []
|
19
19
|
extra_rdoc_files: []
|
20
20
|
files:
|
21
|
-
-
|
22
|
-
- test/test_neatjson.rb
|
21
|
+
- ".yardopts"
|
23
22
|
- LICENSE.txt
|
24
23
|
- README.md
|
25
|
-
- .
|
24
|
+
- html/neatjson.html
|
25
|
+
- html/neatjson.js
|
26
|
+
- lib/neatjson.rb
|
26
27
|
- neatjson.gemspec
|
28
|
+
- test/test_neatjson.rb
|
27
29
|
homepage: http://github.com/Phrogz/NeatJSON
|
28
30
|
licenses:
|
29
31
|
- MIT license (MIT)
|
@@ -34,17 +36,17 @@ require_paths:
|
|
34
36
|
- lib
|
35
37
|
required_ruby_version: !ruby/object:Gem::Requirement
|
36
38
|
requirements:
|
37
|
-
- -
|
39
|
+
- - ">="
|
38
40
|
- !ruby/object:Gem::Version
|
39
41
|
version: '0'
|
40
42
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
41
43
|
requirements:
|
42
|
-
- -
|
44
|
+
- - ">="
|
43
45
|
- !ruby/object:Gem::Version
|
44
46
|
version: '0'
|
45
47
|
requirements: []
|
46
48
|
rubyforge_project:
|
47
|
-
rubygems_version: 2.
|
49
|
+
rubygems_version: 2.4.6
|
48
50
|
signing_key:
|
49
51
|
specification_version: 4
|
50
52
|
summary: Pretty, powerful, flexible JSON generation.
|