Skip to content

Instantly share code, notes, and snippets.

@shawnthompson
Last active February 25, 2025 19:57
Show Gist options
  • Save shawnthompson/d31d89b092fb1efbb4c59958a17b6d57 to your computer and use it in GitHub Desktop.
Save shawnthompson/d31d89b092fb1efbb4c59958a17b6d57 to your computer and use it in GitHub Desktop.
TOC Bookmarklet
javascript:(function() {
let headings = document.querySelectorAll("h1[id], h2[id], h3[id], h4[id], h5[id], h6[id]");
if (!headings.length) {
alert("No headings with IDs found.");
return;
}
let toc = "";
let lastLevel = 1; // Tracks the last heading level
let indent = ""; // Used for indentation
headings.forEach(h => {
let level = parseInt(h.tagName.charAt(1)); // Extracts heading level (1-6)
let text = h.innerText.trim();
let id = h.id;
// Adjust indentation based on the heading level
if (level > lastLevel) {
indent += " "; // Increase indentation for sub-levels
} else if (level < lastLevel) {
indent = indent.substring(0, indent.length - (2 * (lastLevel - level))); // Reduce indentation
}
toc += `${indent}- [${text}](#${id})\n`;
lastLevel = level; // Update last processed level
});
// Create a modal to display TOC
let modal = document.createElement("div");
modal.style = `
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 50%;
max-height: 60%;
overflow-y: auto;
background: #fff;
padding: 20px;
box-shadow: 0px 4px 10px rgba(0,0,0,0.2);
border-radius: 10px;
z-index: 9999;
font-family: Arial, sans-serif;
text-align: left;
`;
let closeButton = document.createElement("button");
closeButton.innerText = "Close";
closeButton.style = "margin-bottom: 10px; padding: 5px 10px; cursor: pointer;";
closeButton.onclick = () => document.body.removeChild(modal);
let copyButton = document.createElement("button");
copyButton.innerText = "Copy";
copyButton.style = "margin-left: 10px; padding: 5px 10px; cursor: pointer;";
copyButton.onclick = () => {
navigator.clipboard.writeText(toc);
copyButton.innerText = "Copied!";
setTimeout(() => copyButton.innerText = "Copy", 2000);
};
let textArea = document.createElement("textarea");
textArea.style = "width: 100%; height: 200px; font-family: monospace; padding: 10px; border: 1px solid #ccc;";
textArea.readOnly = true;
textArea.value = toc;
modal.append(closeButton, copyButton, document.createElement("br"), document.createElement("br"), textArea);
document.body.appendChild(modal);
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment