Source: document.js

/**
 * @file Build table of contents and index.
 * @version April 20, 2017
 *
 * @author Olivier Pirson --- http://www.opimedia.be/
 * @license GPLv3 --- Copyright (C) 2017 Olivier Pirson
 */

(function () {
    "use strict";

    /**
     * Build index
     * in a HTML list in #Index
     * with all .index with a id.
     */
    function buildIndex() {
        const elements = document.getElementsByClassName("index");
        const indices = [];

        for (let element of elements) {
            const id = element.id;

            if (id) {
                indices.push([element.innerHTML, id]);
            }
        }

        indices.sort(function(a, b) {
            a = a[0].toUpperCase();
            b = b[0].toUpperCase();

            return (a < b
                    ? -1
                    : (a > b
                       ? 1
                       : 0));
        });

        const lists = document.getElementById("Index").children[1].children;

        for (let i = 0; i < indices.length; ++i) {
            const index = indices[i];
            const li = document.createElement("li");

            li.innerHTML = '<a href="#' + index[1] + '">' + index[0] + '</a>';

            lists[(i > indices.length/3
                   ? (i > 2*indices.length/3
                      ? 2
                      : 1)
                   : 0)].appendChild(li);
        }
    }


    /**
     * Build the table of contents
     * in a HTML list listHtmlElement
     * with all id and > header > h* of sectionHtmlElements
     * and recursively for subsections.
     *
     * @param {HTMLElement} listHtmlElement
     * @param {HTMLCollection} sectionHtmlElements
     */
    function buildTableOfContents(listHtmlElement, sectionHtmlElements) {
        assert(listHtmlElement instanceof HTMLElement, listHtmlElement);
        assert(sectionHtmlElements instanceof HTMLCollection, sectionHtmlElements);

        for (let section of sectionHtmlElements) {
            const id = section.id;

            if (id !== "Contents") {
                const hContent = section.children[0].children[0].innerHTML;
                const matches = /^((.|\n)+)<a.+?<\/a>$/im.exec(hContent);
                const title = matches[1];

                const li = document.createElement("li");

                li.innerHTML = '<a href="#' + id + '">' + title + '</a>';

                const subSections = section.getElementsByTagName("section");

                if (subSections) {
                    const subList = document.createElement("ul");

                    buildTableOfContents(subList, subSections);
                    li.appendChild(subList);
                }

                listHtmlElement.appendChild(li);
            }
        }
    }



    window.addEventListener("load", function () {
        buildIndex();
        buildTableOfContents(document.getElementById("Contents").children[1].children[0],
                             document.getElementsByTagName("main")[0].children);


        // Show/hide subsections in the table contents panel
        document.getElementById("button-Contents-expand-collapse")
            .addEventListener("click",
                              function () {
                                  const contents = document.getElementById("Contents");

                                  cssInvertClass(contents, "collapse");
                              },
                              false);

        // Show/hide the table contents panel
        document.getElementById("button-Contents-on-off")
            .addEventListener("click",
                              function () {
                                  const contents = document.getElementById("Contents");

                                  cssInvertClass(contents, "off");
                              },
                              false);
    });
}());