Skip to content

Instantly share code, notes, and snippets.

@piroor
Last active November 3, 2022 17:59
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save piroor/14e42c7eeb876ab71e3202dabcd0ee9e to your computer and use it in GitHub Desktop.
Save piroor/14e42c7eeb876ab71e3202dabcd0ee9e to your computer and use it in GitHub Desktop.
Generate Table of Contents for GitHub Wiki Pages
// How to use:
// 1. Go to a page of GitHub Wiki with Firefox.
// 2. Copy this script to the clipboard.
// 3. Hit Ctrl-Shift-K to open Web Console.
// 4. Hit Ctrl-Shift-V to paste this script.
// 5. Hit Enter to run script.
// 6. If you are not in edit mode, click the "Copy ToC" button shown in the page.
// Then ToC is copied to the clipboard, so paste the TOC from the clipboard.
var container = document.querySelector('.markdown-body');
var isEditPage = /\/_edit$/.test(location.href.split('#')[0].split('?')[0]);
if (isEditPage) {
let tab = document.querySelector('.preview-tab');
tab.click();
setTimeout(function waitPreview(retryCount) {
container = document.querySelector('.preview-content .markdown-body');
if (!container || (retryCount < 10 && !generateToC()))
setTimeout(waitPreview, 250, retryCount + 1);
}, 250, 0);
}
else {
generateToC();
}
function generateToC() {
var headings = container.querySelectorAll('h1, h2, h3, h4, h5, h6');
if (headings.length == 0)
return false;
var minLevel = 6;
for (let heading of headings) {
let headingLevel = parseInt(heading.localName.charAt(1));
if (headingLevel < minLevel)
minLevel = headingLevel;
}
var toc = [];
for (let heading of headings) {
let anchor = heading.querySelector('a[href]');
let href = anchor.getAttribute('href');
let indent = '';
let headingLevel = parseInt(heading.localName.charAt(1));
for (let level = headingLevel - minLevel; level > 0; level--) {
indent += ' ';
}
toc.push(`${indent}* [${heading.textContent.trim().replace(/\s\s+/g, ' ')}](${href})`);
}
var source = `<!--ToC-->
${toc.join('\n')}
(This ToC is generated by [ToC Generator Script](https://gist.github.com/piroor/14e42c7eeb876ab71e3202dabcd0ee9e#file-toc-js))
<!--/ToC-->`;
if (isEditPage) {
let tab = document.querySelector('.write-tab');
tab.click();
setTimeout(function updateToC(retryCount) {
var field = document.querySelector('#gollum-editor-body');
if (retryCount < 10 && !field.value)
return setTimeout(updateToC, 250, retryCount);
var matcher = /<!--ToC-->\n(.*\n)*<!--\/ToC-->/;
if (matcher.test(field.value))
field.value = field.value.replace(matcher, source);
else
field.value = `${source}
${field.value}`;
}, 250, 0);
}
else {
let button = document.createElement('button');
button.textContent = 'Copy ToC';
button.setAttribute('style', 'position: fixed; left: 45%; right: 45%; top: 45%;');
button.onclick = function() {
var textarea = document.createElement('textarea');
document.body.appendChild(textarea);
textarea.setAttribute('style', 'position: fixed; top: 0; left: 0;');
textarea.value = source;
textarea.focus();
textarea.select();
document.execCommand('copy');
document.body.removeChild(textarea);
document.body.removeChild(button);
location.href += '/_edit';
};
document.body.appendChild(button);
}
return true;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment