Skip to content

Instantly share code, notes, and snippets.

@grayrest
Created November 2, 2008 20:26
Show Gist options
  • Save grayrest/21743 to your computer and use it in GitHub Desktop.
Save grayrest/21743 to your computer and use it in GitHub Desktop.
Ubiquity JSON Pretty Printer
/*
json2.js
2008-03-14
Public Domain
No warranty expressed or implied. Use at your own risk.
See http://www.JSON.org/js.html
This is a reference implementation. You are free to copy, modify, or
redistribute.
*/
if (!this.JSON) {
JSON = function () {
function f(n) { // Format integers to have at least two digits.
return n < 10 ? '0' + n : n;
}
Date.prototype.toJSON = function () {
return this.getUTCFullYear() + '-' +
f(this.getUTCMonth() + 1) + '-' +
f(this.getUTCDate()) + 'T' +
f(this.getUTCHours()) + ':' +
f(this.getUTCMinutes()) + ':' +
f(this.getUTCSeconds()) + 'Z';
};
var m = { // table of character substitutions
'\b': '\\b',
'\t': '\\t',
'\n': '\\n',
'\f': '\\f',
'\r': '\\r',
'"' : '\\"',
'\\': '\\\\'
};
function stringify(value, whitelist) {
var a, // The array holding the partial texts.
i, // The loop counter.
k, // The member key.
l, // Length.
r = /["\\\x00-\x1f\x7f-\x9f]/g,
v; // The member value.
switch (typeof value) {
case 'string':
return r.test(value) ?
'"' + value.replace(r, function (a) {
var c = m[a];
if (c) {
return c;
}
c = a.charCodeAt();
return '\\u00' + Math.floor(c / 16).toString(16) +
(c % 16).toString(16);
}) + '"' :
'"' + value + '"';
case 'number':
return isFinite(value) ? String(value) : 'null';
case 'boolean':
case 'null':
return String(value);
case 'object':
if (!value) {
return 'null';
}
if (typeof value.toJSON === 'function') {
return stringify(value.toJSON());
}
a = [];
if (typeof value.length === 'number' &&
!(value.propertyIsEnumerable('length'))) {
l = value.length;
for (i = 0; i < l; i += 1) {
a.push(stringify(value[i], whitelist) || 'null');
}
return '[' + a.join(',') + ']';
}
if (whitelist) {
l = whitelist.length;
for (i = 0; i < l; i += 1) {
k = whitelist[i];
if (typeof k === 'string') {
v = stringify(value[k], whitelist);
if (v) {
a.push(stringify(k) + ':' + v);
}
}
}
} else {
for (k in value) {
if (typeof k === 'string') {
v = stringify(value[k], whitelist);
if (v) {
a.push(stringify(k) + ':' + v);
}
}
}
}
return '{' + a.join(',') + '}';
}
}
return {
stringify: stringify,
parse: function (text, filter) {
var j;
function walk(k, v) {
var i, n;
if (v && typeof v === 'object') {
for (i in v) {
if (Object.prototype.hasOwnProperty.apply(v, [i])) {
n = walk(i, v[i]);
if (n !== undefined) {
v[i] = n;
} else {
delete v[i];
}
}
}
}
return filter(k, v);
}
if (/^[\],:{}\s]*$/.test(text.replace(/\\["\\\/bfnrtu]/g, '@').
replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']').
replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
j = eval('(' + text + ')');
return typeof filter === 'function' ? walk('', j) : j;
}
throw new SyntaxError('parseJSON');
}
};
}();
}
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy
// of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.
// JSON pretty printing
function prettyPrintJSON(val, indent, linesep, depth) {
indent = indent != null ? indent : 4;
linesep = linesep != null ? linesep : "\n";
depth = depth != null ? depth : 1;
var propsep = linesep.length ? "," + linesep : ", ";
var tab = [];
for (var i = 0; i < indent * depth; i++) tab.push("");
tab = tab.join(" ");
switch (typeof val) {
case "boolean":
case "number":
case "string":
return "<span class=\"__v__ __"+(typeof val)+"__\">"+JSON.stringify(val)+"</span>";
case "object": {
if (val === null) return "null";
if (val.constructor == Date) return JSON.stringify(val);
var buf = [];
if (val.constructor == Array) {
buf.push("[");
for (var index = 0; index < val.length; index++) {
buf.push(index > 0 ? propsep : linesep);
buf.push(
tab, prettyPrintJSON(val[index], indent, linesep, depth + 1)
);
}
if (index >= 0) buf.push(linesep, tab.substr(indent));
buf.push("]");
} else {
buf.push("{");
var index = 0;
for (var key in val) {
if (!val.hasOwnProperty(key)) continue;
buf.push(index > 0 ? propsep : linesep);
buf.push(
tab, '<span class="__k__">', JSON.stringify(key), "</span>: ",
prettyPrintJSON(val[key], indent, linesep, depth + 1)
);
index++;
}
if (index >= 0) buf.push(linesep, tab.substr(indent));
buf.push("}");
}
return buf.join("");
}
}
}
var template =
'<style type="text/css">.__pretty__container{font-family: monospace; white-space: pre; color: #333;} .__k__{color: #000;} .__number__,.__boolean__{color: #33aa33;}</style><span class="__pretty__container">${json}</span>';
function pageLoad_json_pretty(doc){
var uri = doc.documentURI;
if(!(uri.substr(0,4) == "http" || uri.substr(0,4) == "file"))
return;
if(doc.contentType != "text/plain")
return;
var text = doc.body.firstChild.textContent;
if(text.substr(0,1) != '{')
return;
try{
doc.defaultView.location = "javascript:document.open();document.write(atob(\""+doc.defaultView.btoa(CmdUtils.renderTemplate(
template,
{"json": prettyPrintJSON(JSON.parse(text))}
))+"\"));document.close()";
} catch (e){}
}
CmdUtils.CreateCommand({
name: "json-prettyprint",
//icon: "http://example.com/example.png",
homepage: "http://gr.ayre.st/commands/",
author: { name: "Karl Guertin", email: "[email protected]"},
license: "Public Domain",
description: "Pretty prints the selected JSON",
//help: "how to use your command",
takes: {"input": noun_arb_text},
execute: function(input) {
try{
CmdUtils.setSelection(
CmdUtils.renderTemplate(
template,
{"json": prettyPrintJSON(JSON.parse(input.text))}
)
);
} catch (e){}
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment