neatjson 0.3.4 → 0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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.
|