I uploaded another game design article which originally had Table of Contents (ToC from here on) and I wanted to recreate that section in my dev.to post.
Fortunately, every header tag on dev.to is nicely anchored. Good job, Dev team!
So, Markdown data of headers like this...
## Section
## Another Section
### Sub-Section
...produces...
<h2>
<a name="section" href="#section" class="anchor"></a>
Section
</h2>
<h2>
<a name="another-section" href="#another-section" class="anchor"></a>
Another Section
</h2>
<h3>
<a name="subsection" href="#subsection" class="anchor"></a>
Sub-Section
</h3>
And so, to produce ToC in Markdown, you can write something like...
## Table of Contents
1. [Section](#section)
2. [Another Section](#another-section)
1. [Sub-Section](#subsection)
It's important to note how the reference gets converted. As you can see from the second and third headers, spaces become hyphens and hyphens are removed. Oh and it's all lowercase.
Of course, if you have many big articles, writing each ToC by hand might be tedious and prone to error. I quickly hacked up this script which seems to work "okay" when I run it in my browser's console with the Dev.to Preview tab up.
var anchors = document.getElementsByClassName("anchor");
var outputMarkDown = "## Table of Contents\n";
var orderedNumbers = { };
for (var item in anchors)
{
var anch = anchors[item];
var pelm = anch.parentElement;
var sibl = anch.nextSibling;
// parent is necessary as this is the header tag used
// next sibling is necessary as this is the header text
if (!parent || !sibl) continue;
// indent n times 4 spaces (considers h2 to be first, hence -2)
var indent = pelm.nodeName.slice(-1) - 2;
outputMarkDown += " ".repeat(indent);
// add number
if (!orderedNumbers[indent]) orderedNumbers[indent] = 1;
outputMarkDown += orderedNumbers[indent]++ + ". ";
// add links
outputMarkDown += "[" + sibl.textContent.trim() + "](" + anch.hash + ")\n";
}
console.log(outputMarkDown);
This is what it produced when I ran it on the article linked at the top of this post.