<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>SOON from JSON</title>
</head>
<body>
<div class="main">
<textarea id="json" placeholder="JSON"></textarea>
<div class="buttons"><button id="go">-></button><br><br><button id="back"><-</button></div>
<textarea id="soon" placeholder="SOON"></textarea>
</div>
</body>
</html>
textarea {
height: 400px;
width: 40%;
}
.main textarea,
.main button {
vertical-align: middle;
}
.main .buttons {
display: inline-block;
}
"use strict";
var SOON = (function () {
function SOON() {
}
SOON.prototype.array = function (arr) {
var stack = [];
var length = arr.length;
for (var i = 0; i < length; i++) {
stack.push(this.stringify(arr[i]));
}
stack.push("A" + length);
return stack.join(' ');
};
SOON.prototype.object = function (obj) {
var stack = [];
var length = 0;
for (var key in obj) {
stack.push(this.stringify(obj[key]));
stack.push("\"" + key + "\"");
length++;
}
stack.push("O" + length);
return stack.join(' ');
};
SOON.prototype.string = function (str) {
return "\"" + str + "\"";
};
SOON.prototype.number = function (num) {
return "" + num;
};
SOON.prototype.boolean = function (bool) {
return bool ? 'True' : 'False';
};
SOON.prototype.stringify = function (obj) {
var stack = [];
if (Array.isArray(obj)) {
stack.push(this.array(obj));
}
else if (typeof obj === 'string') {
stack.push(this.string(obj));
}
else if (typeof obj === 'number') {
stack.push(this.number(obj));
}
else if (typeof obj === 'boolean') {
stack.push(this.boolean(obj));
}
else if (obj === null || obj === undefined) {
stack.push('Null');
}
else {
stack.push(this.object(obj));
}
return stack.join(' ');
};
SOON.prototype.parse = function (son) {
var stack = [];
var _son = son.split(' ');
var sonItems = [];
for (var i = 0; i < _son.length; i++) {
if (/^".*[^"]$/.test(_son[i])) {
var _sonItem = [];
while (!/^[^"].*"$/.test(_son[i])) {
_sonItem.push(_son[i++]);
}
_sonItem.push(_son[i]);
sonItems.push(_sonItem.join(' '));
}
else {
if (_son[i] === 'True') {
sonItems.push(true);
}
else if (_son[i] === 'False') {
sonItems.push(false);
}
else if (_son[i] === 'Null') {
sonItems.push(null);
}
else {
sonItems.push(_son[i]);
}
}
}
for (var i = 0; i < sonItems.length; i++) {
var item = sonItems[i];
if (typeof item === 'string' && /^A/i.test(item)) {
var matches = item.match(/A(\d+)/i);
if (!matches || matches.length <= 0) {
throw new Error('Error: invalid array length.');
}
var length_1 = Number(matches[1]);
var array = [];
for (var _i = 0; _i < length_1; _i++) {
if (stack.length === 0) {
throw new Error('Error: stack is empty.');
}
var value = stack.pop();
if (typeof value === 'string') {
if (/^".*"$/.test(value)) {
array.unshift(value.replace(/^"|"$/g, ''));
}
else if (value === 'True' || value === 'False') {
array.unshift(value === 'True' ? true : false);
}
else if (value === 'Null') {
array.unshift(null);
}
else {
array.unshift(Number(value));
}
}
else {
array.unshift(value);
}
}
stack.push(array);
}
else if (typeof item === 'string' && /^O/i.test(item)) {
var matches = item.match(/O(\d+)/i);
if (!matches || matches.length <= 0) {
throw new Error('Error: invalid object length.');
}
var length_2 = Number(matches[1]);
var object = {};
for (var _i = 0; _i < length_2; _i++) {
if (stack.length === 0) {
throw new Error('Error: stack is empty.');
}
var key = stack.pop().replace(/^"|"$/g, '');
if (stack.length === 0) {
throw new Error('Error: stack is empty.');
}
var value = stack.pop();
if (typeof value === 'string') {
if (/^".*"$/.test(value)) {
object[key] = value.replace(/^"|"$/g, '');
}
else if (value === 'True' || value === 'False') {
object[key] = (value === 'True' ? true : false);
}
else if (value === 'Null') {
object[key] = null;
}
else {
object[key] = Number(value);
}
}
else {
object[key] = value;
}
}
stack.push(object);
}
else {
stack.push(item);
}
}
return stack[0];
};
return SOON;
}());
var soon = new SOON();
document.getElementById('go').onclick = function() {
document.getElementById('soon').value = soon.stringify(JSON.parse(document.getElementById('json').value));
}
document.getElementById('back').onclick = function() {
document.getElementById('json').value = JSON.stringify(soon.parse(document.getElementById('soon').value), null, ' ');
}
Output
This bin was created anonymously and its free preview time has expired (learn why). — Get a free unrestricted account
Dismiss xKeyboard Shortcuts
Shortcut | Action |
---|---|
ctrl + [num] | Toggle nth panel |
ctrl + 0 | Close focused panel |
ctrl + enter | Re-render output. If console visible: run JS in console |
Ctrl + l | Clear the console |
ctrl + / | Toggle comment on selected lines |
ctrl + ] | Indents selected lines |
ctrl + [ | Unindents selected lines |
tab | Code complete & Emmet expand |
ctrl + shift + L | Beautify code in active panel |
ctrl + s | Save & lock current Bin from further changes |
ctrl + shift + s | Open the share options |
ctrl + y | Archive Bin |
Complete list of JS Bin shortcuts |
JS Bin URLs
URL | Action |
---|---|
/ | Show the full rendered output. This content will update in real time as it's updated from the /edit url. |
/edit | Edit the current bin |
/watch | Follow a Code Casting session |
/embed | Create an embeddable version of the bin |
/latest | Load the very latest bin (/latest goes in place of the revision) |
/[username]/last | View the last edited bin for this user |
/[username]/last/edit | Edit the last edited bin for this user |
/[username]/last/watch | Follow the Code Casting session for the latest bin for this user |
/quiet | Remove analytics and edit button from rendered output |
.js | Load only the JavaScript for a bin |
.css | Load only the CSS for a bin |
Except for username prefixed urls, the url may start with http://jsbin.com/abc and the url fragments can be added to the url to view it differently. |