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 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.