function createTOC()

in js/toc.js [5:73]


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);
    });
}