for (const el of document.querySelectorAll("[id]")) { el.classList.add("haspara"); const pilcrow = document.createElement("a"); pilcrow.className = "pilcrow"; pilcrow.href = "#" + el.id; pilcrow.innerHTML = "¶"; el.prepend(pilcrow); } const foldable = (root, children) => { let state = true; root.addEventListener("click", (e) => { if (e.target.classList.contains("pilcrow")) state = true; else state = !state; children.style.height = state ? "auto" : "0"; children.style.overflow = state ? "visible" : "hidden"; if (state) root.classList.remove("closed"); else root.classList.add("closed"); }); root.classList.add("toggle-root"); }; const make_foldable = (root) => { const child_stacks = new Array(10).fill(null).map(() => ({ children: [], root: null })); const flush_header = (this_level, sibling) => { for (let level = 9; level >= this_level; level--) { const stack = child_stacks[level]; if (!stack.root) continue; const new_e = document.createElement("div"); for (const old_e of stack.children) { old_e.remove(); new_e.appendChild(old_e); } if (stack.root.tagName !== "H1") foldable(stack.root, new_e); let parent_level; for (parent_level = level - 1; parent_level > 0; parent_level--) if (child_stacks[parent_level].root) break; if (parent_level === -1) { if (sibling) root.insertBefore(new_e, sibling); else root.appendChild(new_e); } else { stack.root.remove(); child_stacks[parent_level].children.push(stack.root); child_stacks[parent_level].children.push(new_e); } stack.root = null; stack.children.length = 0; } }; for (const child of [...root.children]) { if (/^H\d$/.test(child.tagName)) { const this_level = parseInt(child.tagName[1]) - 1; flush_header(this_level, child); child_stacks[this_level].root = child; continue; } for (let level = 9; level >= 0; level--) { if (child_stacks[level].root) { child_stacks[level].children.push(child); break; } } } for (let level = 9; level >= 0; level--) { flush_header(level, null); } }; make_foldable(document.body);