blob: ffdaf0bfb180c06ac29999a54b641fa53ef4f1f4 [file] [log] [blame]
/**
* Inspired by https://github.com/matthewkastor/html-table-of-contents
* by Matthew Christopher Kastor-Inare III
*/
function createTOC() {
var toc = document.getElementById('toc');
var content = document.getElementById('content');
var baseLevel = 0;
var currentLevel = 0;
var currentTarget = document.createElement('ul');
toc.appendChild(currentTarget);
var headings = [].slice.call(content.querySelectorAll('h1, h2, h3'));
headings.forEach(function (heading, index) {
// The type of the heading will determine the nesting level in the TOC
var level = parseInt(heading.tagName.substring(1))
// The first heading doesn't show nested in the TOC. It will determine
// the root level. There shouldn't be bigger headings int he page. If
// that is the case, they will reamin in the same level than this
// base heading.
if (baseLevel == 0) {
baseLevel = level;
} else {
// Check if we have to nest or "un-nest" the element
var nestDiff = level - currentLevel;
if (nestDiff > 0) {
// Create the nested lists to reflect the heading hierarchy
for (var i = 0; i < nestDiff; i++) {
var ul = document.createElement('ul');
currentTarget.appendChild(ul);
currentTarget = ul;
}
} else if (nestDiff < 0) {
// Go to the right parent according to the heading nesting level, but
// stop "un-nesting" when reaching the baseLevel
var toBaseLevelDiff = currentLevel - baseLevel;
var unNestDiff = Math.min(toBaseLevelDiff, -nestDiff);
for (var i = 0; i < unNestDiff; i++) {
currentTarget = currentTarget.parentNode;
}
}
}
// Update the current level
currentLevel = level;
// After nesting/un-nesting, if we are below the base level, update it so
// upcoming nestings/un-nestings are properly handled
if (level < baseLevel) {
baseLevel = level;
}
// Add an anchor to the heading to we can link to it
var anchor = document.createElement('a');
anchor.setAttribute('name', 'toc' + index);
anchor.setAttribute('id', 'toc' + index);
// Build the link to pointing to the anchor
var link = document.createElement('a');
link.setAttribute('href', '#toc' + index);
link.textContent = heading.textContent;
// Append the element to the TOC, with the right nesting level
var li = document.createElement('li');
li.appendChild(link);
currentTarget.appendChild(li);
heading.parentNode.insertBefore(anchor, heading);
});
}