Skip to content

Instantly share code, notes, and snippets.

@ststeiger
Last active March 7, 2024 14:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ststeiger/44d8bbad7bf008cb3f6a48670647f36d to your computer and use it in GitHub Desktop.
Save ststeiger/44d8bbad7bf008cb3f6a48670647f36d to your computer and use it in GitHub Desktop.
Json ML generatio from Object
function createHTMLFromJSONML(jsonML)
{
if (!Array.isArray(jsonML) || jsonML.length === 0)
{
return '';
}
const [tag, attributes, ...children] = jsonML;
// Create opening tag with attributes
let html = `<${tag}`;
if (attributes && Object.keys(attributes).length > 0)
{
for (const [attr, value] of Object.entries(attributes))
{
html += ` ${attr}="${value}"`;
}
}
html += '>';
// Recursively create HTML for children
for (const child of children)
{
if (Array.isArray(child))
{
html += createHTMLFromJSONML(child);
}
else
{
html += child;
}
}
// Create closing tag
html += `</${tag}>`;
return html;
}
const obj = [{ "noob": "you are" }, { "yoda": "you get" }];
const headersTable = [
"table",
{},
["tr", { "style": "background-color: #5b9bd5; color: #FFF; font-weight: bold;" },
["td", { "style": "padding: 1mm; " }, "Key"],
["td", { "style": "padding: 1mm; " }, "Value"]
],
...obj.map((entry, index) => {
const rowColor = index % 2 === 0 ? "#DCE6F1" : "ivory";
return ["tr", { "style": `background-color: ${rowColor};` },
["td", { "style": "padding: 1mm; padding-right: 5mm; " }, Object.keys(entry)[0]],
["td", { "style": "padding: 1mm; padding-right: 5mm; " }, Object.values(entry)[0]]
];
})
];
// console.log(createHTMLFromJSONML(headersTable));
const mytable = [
{ "column1": "R1 C1", "column2": "R1 C2", "column3": "R1 C3" },
{ "column1": "R2 C1", "column2": "R2 C2", "column3": "R2 C3" },
{ "column1": "R3 C1", "column2": "R3 C2", "column3": "R3 C3" },
{ "column1": "R4 C1", "column2": "R4 C2", "column3": "R4 C3" }
];
const jsonMLTable = [
"table",
{},
["tr", { "style": "background-color: #5b9bd5; color: #FFF; font-weight: bold;" },
["td", { "style": "padding: 1mm; " }, "Column 1"],
["td", { "style": "padding: 1mm; " }, "Column 2"],
["td", { "style": "padding: 1mm; " }, "Column 3"]
],
...mytable.map(row => {
return ["tr", {},
["td", { "style": "padding: 1mm; padding-right: 5mm;" }, row.column1],
["td", { "style": "padding: 1mm; padding-right: 5mm;" }, row.column2],
["td", { "style": "padding: 1mm; padding-right: 5mm;" }, row.column3]
];
})
];
// console.log(JSON.stringify(jsonMLTable, null, 2));
console.log(createHTMLFromJSONML(jsonMLTable ));
var obj = [{ "key": "noob", "value": "you are"}, { "key": "yoda", "value": "you get"}];
var headersTable = [
"table",
{},
["tr", { "style": "background-color: #5b9bd5; color: #FFF; font-weight: bold;" },
["td", { "style": "padding: 1mm; " }, "Key"],
["td", { "style": "padding: 1mm; " }, "Value"]
],
...obj.map(({key, value}, index) =>
{
// Alternate row colors based on index
const rowColor = index % 2 === 0 ? "#DCE6F1" : "ivory";
return ["tr", { "style": `background-color: ${rowColor};` },
["td", { "style": "padding: 1mm; padding-right: 5mm; "}, key],
["td", { "style": "padding: 1mm; padding-right: 5mm; "}, value]
];
})
];
createHTMLFromJSONML(headersTable )
function createFragmentFromJSONML(jsonML) {
if (!Array.isArray(jsonML) || jsonML.length === 0) {
return null;
}
const [tag, attributes, ...children] = jsonML;
// Create the fragment
const fragment = document.createDocumentFragment();
// Create the element based on the tag
const element = document.createElement(tag);
// Set attributes
if (attributes && Object.keys(attributes).length > 0) {
for (const [attr, value] of Object.entries(attributes)) {
element.setAttribute(attr, value);
}
}
// Append children recursively
for (const child of children) {
if (Array.isArray(child)) {
const childFragment = createFragmentFromJSONML(child);
if (childFragment) {
element.appendChild(childFragment);
}
} else {
// Convert text nodes to actual text nodes
element.appendChild(document.createTextNode(child));
}
}
fragment.appendChild(element);
return fragment;
}
const docFragment_jsonML = [
"div",
{ "class": "container" },
"Hello, ",
["strong", {}, "world"],
"!"
];
const fragment = createFragmentFromJSONML(docFragment_jsonML);
// document.body.appendChild(fragment);
function getOuterHTML(fragment) {
const tempDiv = document.createElement('div');
tempDiv.appendChild(fragment.cloneNode(true));
return tempDiv.innerHTML;
}
const outerHTML = getOuterHTML(fragment);
console.log(outerHTML);
function elementToJSONML(element) {
const jsonML = [];
const tagName = element.tagName.toLowerCase();
const attributes = {};
// Get element attributes
for (const attr of element.attributes) {
attributes[attr.name] = attr.value;
}
// Add element tag, attributes, and children to JSONML
jsonML.push(tagName, attributes);
// Recursively convert children to JSONML
for (const childNode of element.childNodes) {
if (childNode.nodeType === Node.TEXT_NODE) {
// Text node, add its value directly to JSONML
jsonML.push(childNode.nodeValue);
} else if (childNode.nodeType === Node.ELEMENT_NODE) {
// Element node, recursively convert it to JSONML
jsonML.push(elementToJSONML(childNode));
}
}
return jsonML;
}
// Example usage:
// const container = document.getElementById('container');
const container = document.body;
const jsonML = elementToJSONML(container);
const json = JSON.stringify(jsonML, null, 2);
console.log(jsonML);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment