Skip to content

Instantly share code, notes, and snippets.

@lot224
Last active January 11, 2022 17:41
Show Gist options
  • Save lot224/5dc6527aa31c9bf16c18453679a7ed17 to your computer and use it in GitHub Desktop.
Save lot224/5dc6527aa31c9bf16c18453679a7ed17 to your computer and use it in GitHub Desktop.
Flat Array of filenames to html tree structure.
const files = [
"path/1/pages/home.html",
"path/1/pages/about.html",
"path/1/pages/settings.html",
"path/1/pages/contact.html",
"path/1/assets/images/background.jpeg",
"path/1/assets/images/logo.png",
"path/1/assets/images/arrow-left.png",
"path/1/assets/images/arrow-right.png",
"path/1/assets/images/backgrounds/space.png",
"path/1/assets/images/backgrounds/mountains.jpeg",
"path/1/assets/images/backgrounds/ocean.png",
"path/1/styles/light/main.css",
"path/1/styles/light/branding.css",
"path/1/styles/dark/main.css",
"path/1/styles/dark/branding.css",
"path/1/styles/helper.css",
"path/1/scripts/main.js",
"path/1/scripts/components/header.js",
"path/1/scripts/components/footer.js",
"path/1/scripts/components/login.js",
"path/1/scripts/components/signup.js",
"path/2/admin/login.html",
"path/2/admin/employee.html",
"path/assets/images/background.png",
"path/styles/main.css",
"favicon.ico"
]
function toTree(flatArray: string[], parent: string = "ul", child: string = "li") {
const r = /\s.*$/gm; // Removes anything after and including the first space. (allows us to close html tags correctly)
const grow = (branches: any) => {
// Lets keep the branches on top, leaves after
const branch = [];
const leaves = [];
// Get the property names and sort a-z.
const names = Object.getOwnPropertyNames(branches).sort();
names.forEach(name => {
if (branches[name] !== null) { // this is a directory.
branch.push(`<${child}>${name}<${parent}>${grow(branches[name])}</${parent.replace(r, '')}></${child.replace(r, '')}>`);
} else {
leaves.push(`<${child}>${name}</${child.replace(r, '')}>`)
}
});
return branch.join('') + leaves.join('');
}
const tree = {};
// lets unflatten the array into a single object.
flatArray.forEach(limb => {
const logs = limb.split('/');
const len = logs.length;
let trunk = tree;
for (var i = 0; i < len; i++) {
const log = logs[i];
if (!trunk[log])
trunk[log] = i + 1 === len ? null : {};
trunk = trunk[log];
}
})
// Pass the unflattened tree into the grow function. and we'll wrap it around parent tags.
return `<${parent}>${grow(tree)}</${parent.replace(r, '')}>`;
}
const tree = toTree(files); // default <ul>'s and <li>'s
//const tree = toTree(files, 'ol'); // Just <ol>'s and <li>'s
//const tree = toTree(files, 'div', 'span'); // use divs with nested spans.
//const tree = toTree(files, 'div class="parent"', 'span class="child"'); // use divs with nested spans and include some class names.
console.log(tree);
<ul><li>path<ul><li>1<ul><li>assets<ul><li>images<ul><li>backgrounds<ul><li>mountains.jpeg</li><li>ocean.png</li><li>space.png</li></ul></li><li>arrow-left.png</li><li>arrow-right.png</li><li>background.jpeg</li><li>logo.png</li></ul></li></ul></li><li>pages<ul><li>about.html</li><li>contact.html</li><li>home.html</li><li>settings.html</li></ul></li><li>scripts<ul><li>components<ul><li>footer.js</li><li>header.js</li><li>login.js</li><li>signup.js</li></ul></li><li>main.js</li></ul></li><li>styles<ul><li>dark<ul><li>branding.css</li><li>main.css</li></ul></li><li>light<ul><li>branding.css</li><li>main.css</li></ul></li><li>helper.css</li></ul></li></ul></li><li>2<ul><li>admin<ul><li>employee.html</li><li>login.html</li></ul></li></ul></li><li>assets<ul><li>images<ul><li>background.png</li></ul></li></ul></li><li>styles<ul><li>main.css</li></ul></li></ul></li><li>favicon.ico</li></ul>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment