Skip to content

Instantly share code, notes, and snippets.

@HichamBenjelloun
Created September 28, 2024 07:27
Show Gist options
  • Save HichamBenjelloun/1048e1d9792341933ef6e0beabc0849b to your computer and use it in GitHub Desktop.
Save HichamBenjelloun/1048e1d9792341933ef6e0beabc0849b to your computer and use it in GitHub Desktop.
Generates a hierarchical Table of Contents (TOC) from DOM headings and returns it as a string.
type HeadingNode = {
element: HTMLHeadingElement;
children: HeadingNode[];
};
function createHeadingTree(): HeadingNode[] {
const root: HeadingNode[] = [];
const stack: HeadingNode[] = [];
for (const heading of document.querySelectorAll<HTMLHeadingElement>(
'h1, h2, h3, h4, h5, h6',
)) {
const level = +heading.tagName[1];
const node: HeadingNode = { element: heading, children: [] };
if (stack.length === 0) {
root.push(node);
} else {
while (
stack.length > 0 &&
+stack[stack.length - 1].element.tagName[1] >= level
) {
stack.pop();
}
if (stack.length === 0) {
root.push(node);
} else {
stack[stack.length - 1].children.push(node);
}
}
stack.push(node);
}
return root;
}
function tableOfContents(headingsTree: HeadingNode[] = createHeadingTree()) {
if (headingsTree.length === 0) {
return '';
}
return `<ul>${headingsTree.map((heading): string => `<li>${heading.element.textContent}${tableOfContents(heading.children)}`)}</li></ul>`;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment