Greasy Fork 还支持 简体中文。

Markdown Table Of Contents

Creates a table of contents for some markdown-based websites

目前為 2024-03-30 提交的版本,檢視 最新版本

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name         Markdown Table Of Contents
// @version      1.0
// @author       Rust1667
// @description  Creates a table of contents for some markdown-based websites
// @match        https://rentry.co/*
// @match        https://rentry.org/*
// @match        https://*.reddit.com/r/*/wiki/*
// @match        https://*.github.io/*
// @match        https://saidit.net/s/*/wiki/*
// @match        https://wiki.dbzer0.com/*
// @grant        none
// @namespace https://greasyfork.org/users/980489
// ==/UserScript==

(function() {
    'use strict';

    let currentPageUrl = window.location.href;
    let indexContainer = null;

    function createIndex() {
        let subheaderSelector = 'h2[id], h3[id], h4[id], h5[id], h6[id]';

        // Check if there is more than one h1 subheader
        if (document.querySelectorAll('h1[id]').length > 1) {
            subheaderSelector = 'h1[id], ' + subheaderSelector;
        }

        const subheaders = document.querySelectorAll(subheaderSelector);
        if (subheaders.length === 0) {
            removeIndex();
            return;
        }

        // Determine the highest subheader tier
        let highestTier = 7; // Set to 7 to ensure padding is always greater
        subheaders.forEach(subheader => {
            const level = parseInt(subheader.tagName[1]);
            if (level < highestTier) {
                highestTier = level;
            }
        });

        // Remove existing index container if it exists
        if (indexContainer) {
            indexContainer.remove();
        }

        indexContainer = document.createElement('div');
        indexContainer.style.position = 'fixed';
        indexContainer.style.top = '50%';
        indexContainer.style.right = '0';
        indexContainer.style.transform = 'translateY(-50%)'; // Adjust to center vertically
        indexContainer.style.backgroundColor = getComputedStyle(document.body).getPropertyValue('background-color');
        indexContainer.style.border = '1px solid #ced4da';
        indexContainer.style.padding = '0'; // Remove padding
        indexContainer.style.zIndex = '9999';
        indexContainer.style.maxHeight = '80vh';
        indexContainer.style.overflowY = 'auto';
        indexContainer.style.maxWidth = '200px'; // Limit maximum width

        const indexList = document.createElement('ul');
        indexList.style.margin = '0'; // Remove margin
        indexList.style.padding = '0'; // Remove padding
        indexList.style.listStyleType = 'none'; // Remove bullet points

        subheaders.forEach(subheader => {
            const listItem = document.createElement('li');
            const link = document.createElement('a');
            let textContent = subheader.textContent.trim();
            // Trim long titles
            if (textContent.length > 20) {
                textContent = textContent.substring(0, 20) + '...';
            }
            link.textContent = textContent;
            link.href = '#' + subheader.id;
            link.style.whiteSpace = 'nowrap'; // Prevent line breaks
            link.style.overflow = 'hidden'; // Hide overflowing text
            link.style.textOverflow = 'ellipsis'; // Add ellipsis for overflow
            const level = parseInt(subheader.tagName[1]);
            listItem.style.paddingLeft = (level - highestTier) * 2 + 'em'; // Adjust padding based on the difference from the highest tier
            indexList.appendChild(listItem);
            listItem.appendChild(link);
        });

        indexContainer.appendChild(indexList);
        document.body.appendChild(indexContainer);
    }

    function removeIndex() {
        if (indexContainer) {
            indexContainer.remove();
            indexContainer = null;
        }
    }

    function checkUrlChange() {
        const newUrl = window.location.href;
        if (newUrl !== currentPageUrl) {
            currentPageUrl = newUrl;
            createIndex();
        } else if (!document.querySelector('h1[id], h2[id], h3[id], h4[id], h5[id], h6[id]')) {
            // Page URL hasn't changed, but no subheaders found
            removeIndex();
        }
    }

    // Check if the page has subheaders that can be linked to with a URL
    const hasSubheaders = document.querySelector('h1[id], h2[id], h3[id], h4[id], h5[id], h6[id]');
    if (hasSubheaders) {
        createIndex();
        // Uncommenting the interval check
        setInterval(checkUrlChange, 1000); // Check for URL change every second
    }
})();