Skip to content

Instantly share code, notes, and snippets.

@6david9
Last active April 28, 2024 05:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save 6david9/d2fd7beb525c9c60803eff74adbc8a47 to your computer and use it in GitHub Desktop.
Save 6david9/d2fd7beb525c9c60803eff74adbc8a47 to your computer and use it in GitHub Desktop.
add table of contents to python library reference page.
// ==UserScript==
// @name Python doc toc
// @namespace http://tampermonkey.net/
// @version 2024-04-27
// @description Add table of contents to python doc.
// @author You
// @match https://docs.python.org/3/library/*.html
// @icon https://www.google.com/s2/favicons?sz=64&domain=python.org
// @grant none
// @run-at document-idle
// ==/UserScript==
(function() {
'use strict';
function generateRandomHexString(length) {
let result = '';
for (let i = 0; i < length; i++) {
result += Math.floor(Math.random() * 16).toString(16);
}
return result;
}
function createLink(text, target) {
let divElem = document.createElement("div");
let linkElem = document.createElement("a");
linkElem.textContent = text;
linkElem.style = "text-decoration: none; line-height: 1.4; font-size: 1.2em;";
divElem.appendChild(linkElem);
let hrElem = document.createElement("hr");
divElem.appendChild(hrElem);
if (target) {
linkElem.href = target;
}
return divElem;
}
function insertOrAppend(rootElement, targeElement) {
let child = rootElement.firstChild;
if (child) {
rootElement.insertBefore(targeElement, child);
}
else {
rootElement.appendChild(targeElement);
}
}
function buildSection(rootElement, secElem) {
let dlElems = secElem.querySelectorAll(":scope > dl");
for (let dlElem of dlElems) {
let dtElem = dlElem.querySelector("dt");
let text = dtElem.textContent.trim().replace("¶", "");
let idValue = dtElem.getAttribute("id");
if (!idValue) {
idValue = generateRandomHexString(10);
dtElem.id = idValue;
}
let elem = createLink(text, `#${idValue}`);
rootElement.appendChild(elem);
}
let sectionElems = secElem.querySelectorAll(":scope > section");
for (let elem of sectionElems) {
recursiveBuildSection(rootElement, elem);
}
}
function recursiveBuildSection(rootElement, elem) {
let h2Elem = elem.querySelector(":scope > h2");
let sectionElems = elem.querySelectorAll(":scope > section");
let sectionRootElement = document.createElement("div");
rootElement.appendChild(sectionRootElement);
if (h2Elem) {
let text = h2Elem.textContent.trim().replace("¶", "");
let textElem = document.createElement("h2");
textElem.textContent = text;
textElem.style = "border-bottom: thick double lightgray; margin-bottom: 20px; margin-top: 10px; display: inline-block;";
sectionRootElement.appendChild(textElem);
}
if (elem.tagName.toLowerCase() === "section") {
buildSection(sectionRootElement, elem);
}
for (let elem of sectionElems) {
buildSection(sectionRootElement, elem);
}
return rootElement;
}
function addTableOfContent() {
let bodyElem = document.querySelector("div.body")
let sectionElem = bodyElem.querySelector(":scope > section");
let rootElement = document.createElement("div");
rootElement.style = "border: 1px solid white; padding: 10px;";
let tocElement = document.createElement("h1");
tocElement.textContent = "Table of Contents";
tocElement.style = "width: 100%; border-bottom: thick double lightgray; margin-bottom: 10px;";
rootElement.appendChild(tocElement);
buildSection(rootElement, sectionElem);
insertOrAppend(bodyElem, rootElement);
}
addTableOfContent();
window.scrollTo(0, 0);
})();
@6david9
Copy link
Author

6david9 commented Apr 28, 2024

Screenshot 2024-04-28 at 13 24 08 Screenshot 2024-04-28 at 13 24 25

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment