For my posts on dev.to I always want to have a Table of Contents. Until now I did that manually which was a lot of work. So I created a small JS snippet that you can use as bookmarklet.
A bookmarklet looks like a bookmark in your browser. But when you click it, a JS snippet runs on the current page.
Here's the source code. It goes through all h2 and h3 of the article, creates internal links, and concatenates them as markdown. Ready to copy & paste to your dev.to post.
(() => {
let toc = "";
let numH2 = 1;
let numH3 = 1;
document.querySelectorAll("article h2,article h3").forEach(element => {
const a = element.firstElementChild;
if (a?.nodeName === "A") {
const text = (element.lastChild?.nodeValue || "").replaceAll("\n", "").trim();
if (element.nodeName === "H2") {
toc += `${numH2}. [${text}](${a.hash})\n`;
numH2 += 1;
numH3 = 1;
} else if (element.nodeName === "H3") {
toc += ` ${numH3}. [${text}](${a.hash})\n`;
numH3 += 1;
}
}
});
console.log("## Table Of Contents\n\n" + toc);
})()
How to create a bookmarklet? Create a new bookmark in your browser. In place of the URL you type javascript:
followed by your code.
Here the minified JS snippet from above for your bookmark.
javascript:(()=>{let toc="";let numH2=1;let numH3=1;document.querySelectorAll("article h2,article h3").forEach(element=>{const a=element.firstElementChild;if(a?.nodeName==="A"){const text=(element.lastChild?.nodeValue||"").replaceAll("\n","").trim();if(element.nodeName==="H2"){toc+=`${numH2}. [${text}](${a.hash})\n`;numH2+=1;numH3=1}else if(element.nodeName==="H3"){toc+=` ${numH3}. [${text}](${a.hash})\n`;numH3+=1}}});console.log("##%20Table%20Of%20Contents\n\n"+toc)})()