Skip to content

Instantly share code, notes, and snippets.

@deanveloper
Last active July 16, 2018 17:26
Show Gist options
  • Save deanveloper/cc59e9a01f342f320063293bc5e182aa to your computer and use it in GitHub Desktop.
Save deanveloper/cc59e9a01f342f320063293bc5e182aa to your computer and use it in GitHub Desktop.
Converts JSON to an HTML string. JSON is assumed to already be HTML-Escaped.
//
// Author: Dean Bassett
//
// Converts JSON to an HTML string. JSON is assumed to already be HTML-Escaped.
// The name for function is inspired by the C function `atoi`.
//
// this converter takes an object with 3 attributes:
// tag (string, required): the html tag
// attributes (object): key-value pairs which represent the attributes for the tag
// content (many types)...
// (string): Represents a text node
// (object): Represents an HTML node, with fields as defined above
// (array): Represents many nodes, either type string or object
//
function jtoh(js) {
let contentStr = "";
function addContent(content) {
if (typeof content === "string" || typeof content === "number") {
contentStr += content+"";
} else if (typeof content === "object" && content !== null) {
contentStr += jtoh(content)
} else {
throw Error("Invalid content: " + content + " (type " + (typeof content) + ")");
}
}
// Calculate content
if (js.content === undefined) {
// let content be empty if not defined
} else if (Array.isArray(js.content)) {
for (let i = 0; i < js.content.length; i++) {
addContent(js.content[i]);
}
} else {
addContent(js.content);
}
// Calculate attributes
let attribStr = "";
if (js.attributes === undefined) {
// let attributes be empty if not defined
} else if (typeof js.attributes === "object" && js.attributes !== null) {
for (let k in js.attributes) {
let v = js.attributes[k];
if (typeof v !== "string" || typeof k !== "string") {
throw Error("Invalid attribute " + k + " :: " + v + " (types " + (typeof k) + " :: " + (typeof v) + ")");
}
attribStr += `${k}="${v}"`
}
} else {
throw Error("Invalid attributes object: " + js.attributes + " (type " + (typeof js.attributes) + ")");
}
// Tag
if (typeof js.tag === "string") {
if (contentStr !== "") {
return `<${js.tag} ${attribStr}>${contentStr}</${js.tag}>`;
}
switch (js.tag) {
case "area":
case "base":
case "br":
case "col":
case "embed":
case "hr":
case "img":
case "input":
case "keygen":
case "link":
case "meta":
case "param":
case "source":
case "track":
case "wbr":
return `<${js.tag} ${attribStr}>`;
default:
return `<${js.tag} ${attribStr}>${contentStr}</${js.tag}>`;
}
} else {
throw Error("Invalid tag " + js.tag + " (type " + (typeof js.tag) + ")");
}
}
@deanveloper
Copy link
Author

Updated to fix a bug with self-closing tags

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment