SON of JSON
by Tonio Loewald
August 29, 2015
HTML
<h1>SON of JSON</h1>
<pre>
simple-stuff: hello, world
array:
:first
:second
:
name: third
favorite-color: pink
:fourth
mixed:
:test
foo: bar
:another test
baz: bro
nest:
bird: egg
suit: radiation-proof
elt-list:
:
type: div
content:
:
type: p
attributes:
class: foo
content: Some text
:
type: p
attributes:
style: color: red;
content: More text
</pre>
CSS
.failure {
color: red;
}
.success {
color: #090;
}
[data-result]:after {
content: attr(data-result);
margin-left: 8px;
padding: 0 4px;
background-color: #ffa;
}
[data-exception]:after {
content: attr(data-exception);
margin-left: 8px;
padding: 0 4px;
background-color: #faa;
}
JavaScript
console.clear();
function Sack(source, spaces){
if(spaces === undefined){
spaces = 2;
}
var tabEquivalent = new RegExp(' {' + spaces + '}', 'g');
this.parsed = false;
this.source = source.replace(/ {2}/g, '\t');
if(this.source.match(/^\t* /)){
console.error('odd number of leading spaces in input', this.source.match(/^\t* /g));
}
this.values = {};
return this;
}
Sack.prototype = {
parse: function(){
if(!this.parsed){
var lines = this.source.split(/\n/);
var idx = 0;
while(lines.length){
var line = lines.shift();
if(line.trim() && line.substr(0,1) !== '\t'){
var cut = line.indexOf(':');
if(cut === -1){
throw "bad input, expected colon: " + line;
}
var key = line.substr(0, cut) || idx;
idx += 1;
var value = line.substr(cut + 1);
// skip first space if present
if(value.length && value.substr(0,1) === ' '){
value = value.substr(1);
}
if(value !== ''){
if(value.trim() === ''){
console.warn('Possible trailing space: ' + line);
}
this.values[key] = value;
} else {
value = [];
var line = '';
while(lines.length && lines[0].substr(0,1) === '\t'){
line = lines.shift();
value.push(line.substr(1));
}
value = value.join('\n');
this.values[key] = new Sack(value);
}
}
}
this.parsed = true;
}
return this;
...