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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 53e8fd630d625edc34d2af45cb65d234e054b4e2
4
- data.tar.gz: 967f1fe69f119a8b5d49e1464863ceea4d659273
3
+ metadata.gz: ffd7e1b6d8e702a1ac021f7c8dceb24bce52b4a6
4
+ data.tar.gz: 956fa2524dd0f720b04b932fef9ce133311b49bf
5
5
  SHA512:
6
- metadata.gz: ee1f23f2a450d83b425a5fa05e982cb8d98d18c0f7095c3e25d2f2df4934f481d51131cc4337c3a35baf4c2240b0f42fcb2465d0a89db0c6be7f9338354f3722
7
- data.tar.gz: 595c40ed30181960f70d572461a5bb6e2554caccd28554afdd90278a6bd76fa4476862003f47945f9d8a4312393696346d30ef22704eb4f476e2a107d2ec1581
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
 
@@ -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>
@@ -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
+ }
@@ -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
- pieces = o.map{ |v| build[ v,"#{indent} #{apad}" ] }
62
- pieces[0].sub! /^#{indent} #{apad}/, "#{indent}[#{apad}"
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{ |x| build[ x, indent2 ] }.join ",\n"}\n#{indent}]"
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{ |a,b| [a,b].join(colon) }.join(comma)
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.last << opad << "}"
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]
@@ -2,7 +2,7 @@
2
2
  require 'date'
3
3
  Gem::Specification.new do |s|
4
4
  s.name = "neatjson"
5
- s.version = "0.3.4"
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.3.4
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-16 00:00:00.000000000 Z
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
- - lib/neatjson.rb
22
- - test/test_neatjson.rb
21
+ - ".yardopts"
23
22
  - LICENSE.txt
24
23
  - README.md
25
- - .yardopts
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.0.14
49
+ rubygems_version: 2.4.6
48
50
  signing_key:
49
51
  specification_version: 4
50
52
  summary: Pretty, powerful, flexible JSON generation.