docs: add pagetoc

Changed files
+150 -1
docs
+6 -1
docs/book.toml
···
git-repository-url = "https://patchy.soopy.moe/cassie/genso-nix"
git-repository-icon = "fa-code-fork"
edit-url-template = "https://patchy.soopy.moe/cassie/genso-nix/_edit/main/docs/{path}"
-
additional-css = ["mdbook-admonish.css", "./theme/catppuccin.css", "./theme/catppuccin-admonish.css"]
cname = "flake.soopy.moe"
+
+
additional-js = ["theme/pagetoc.js"]
+
additional-css = ["mdbook-admonish.css", "./theme/catppuccin.css", "./theme/catppuccin-admonish.css", "theme/pagetoc.css"]
[preprocessor.admonish]
command = "mdbook-admonish"
assets_version = "3.0.2" # do not edit: managed by `mdbook-admonish install`
+
+
[preprocessor.pagetoc]
+
# [preprocessor.catppuccin]
# assets_version = "2.1.0" # DO NOT EDIT: Managed by `mdbook-catppuccin install`
+71
docs/theme/pagetoc.css
···
+
@media only screen and (max-width:1439px) {
+
.sidetoc {
+
display: none;
+
}
+
}
+
+
@media only screen and (min-width:1440px) {
+
main {
+
position: relative;
+
}
+
+
.sidetoc {
+
margin-left: auto;
+
margin-right: auto;
+
left: calc(100% + (var(--content-max-width))/4 - 140px);
+
position: absolute;
+
}
+
+
.pagetoc {
+
position: fixed;
+
width: 200px;
+
height: calc(100vh - var(--menu-bar-height) - 0.67em * 4);
+
overflow: auto;
+
}
+
+
.pagetoc a {
+
border-left: 1px solid var(--sidebar-bg);
+
color: var(--fg) !important;
+
display: block;
+
padding-bottom: 5px;
+
padding-top: 5px;
+
padding-left: 10px;
+
text-align: left;
+
text-decoration: none;
+
}
+
+
.pagetoc a:hover,
+
.pagetoc a.active {
+
background: var(--sidebar-bg);
+
color: var(--sidebar-fg) !important;
+
}
+
+
.pagetoc .active {
+
background: var(--sidebar-bg);
+
color: var(--sidebar-fg);
+
}
+
+
.pagetoc .pagetoc-H2 {
+
padding-left: 20px;
+
}
+
+
.pagetoc .pagetoc-H3 {
+
padding-left: 40px;
+
}
+
+
.pagetoc .pagetoc-H4 {
+
padding-left: 60px;
+
}
+
+
.pagetoc .pagetoc-H5 {
+
display: none;
+
}
+
+
.pagetoc .pagetoc-H6 {
+
display: none;
+
}
+
}
+
+
a[class^='pagetoc-H']:only-child {
+
display: none;
+
}
+73
docs/theme/pagetoc.js
···
+
let scrollTimeout;
+
+
const listenActive = () => {
+
const elems = document.querySelector(".pagetoc").children;
+
[...elems].forEach((el) => {
+
el.addEventListener("click", (event) => {
+
clearTimeout(scrollTimeout);
+
[...elems].forEach((el) => el.classList.remove("active"));
+
el.classList.add("active");
+
// Prevent scroll updates for a short period
+
scrollTimeout = setTimeout(() => {
+
scrollTimeout = null;
+
}, 100); // Adjust timing as needed
+
});
+
});
+
};
+
+
const getPagetoc = () =>
+
document.querySelector(".pagetoc") || autoCreatePagetoc();
+
+
const autoCreatePagetoc = () => {
+
const main = document.querySelector("#content > main");
+
const content = Object.assign(document.createElement("div"), {
+
className: "content-wrap",
+
});
+
content.append(...main.childNodes);
+
main.prepend(content);
+
main.insertAdjacentHTML(
+
"afterbegin",
+
'<div class="sidetoc"><nav class="pagetoc"></nav></div>',
+
);
+
return document.querySelector(".pagetoc");
+
};
+
const updateFunction = () => {
+
if (scrollTimeout) return; // Skip updates if within the cooldown period from a click
+
const headers = [...document.getElementsByClassName("header")];
+
const scrolledY = window.scrollY;
+
let lastHeader = null;
+
+
// Find the last header that is above the current scroll position
+
for (let i = headers.length - 1; i >= 0; i--) {
+
if (scrolledY >= headers[i].offsetTop) {
+
lastHeader = headers[i];
+
break;
+
}
+
}
+
+
const pagetocLinks = [...document.querySelector(".pagetoc").children];
+
pagetocLinks.forEach((link) => link.classList.remove("active"));
+
+
if (lastHeader) {
+
const activeLink = pagetocLinks.find((link) =>
+
lastHeader.href === link.href
+
);
+
if (activeLink) activeLink.classList.add("active");
+
}
+
};
+
+
window.addEventListener("load", () => {
+
const pagetoc = getPagetoc();
+
const headers = [...document.getElementsByClassName("header")];
+
headers.forEach((header) => {
+
const link = Object.assign(document.createElement("a"), {
+
textContent: header.text,
+
href: header.href,
+
className: `pagetoc-${header.parentElement.tagName}`,
+
});
+
pagetoc.appendChild(link);
+
});
+
updateFunction();
+
listenActive();
+
window.addEventListener("scroll", updateFunction);
+
});