function get_toc_item_id(header_id) {
return "toc_item_" + header_id;
}
// github.com/ghiculescu/jekyll-table-of-contents // This is how a jquery plugin is defined - stackoverflow.com/questions/2937227/what-does-function-jquery-mean . $.fn.toc = function(options) {
console.debug("Setting up TOC for " + document.location); var defaults = { noBackToTopLinks: false, title: '', minimumHeaders: 3, headers: 'h1, h2, h3, h4', listType: 'ol', // values: [ol|ul] }, settings = $.extend(defaults, options); // console.debug($(settings.headers)); var headers = $(settings.headers).filter(function() { // get all headers with an ID var previousSiblingName = $(this).prev().attr( "name" ); if (!this.id && previousSiblingName) { this.id = $(this).attr( "id", previousSiblingName.replace(/\./g, "-") ); } return this.id; }), output = $(this); if (!headers.length || headers.length < settings.minimumHeaders || !output.length) { return; } // console.debug(headers); var get_level = function(ele) { return parseInt(ele.nodeName.replace("H", ""), 10); } var highest_level = headers.map(function(_, ele) { return get_level(ele); }).get().sort()[0]; var level = get_level(headers[0]), this_level, html = settings.title + " <"+settings.listType+" id=\"toc_ul\" class=\"nav\">"; headers.on('click', function() { if (!settings.noBackToTopLinks) { window.location.hash = this.id; } }) .addClass('clickable-header') .each(function(_, header) { this_level = get_level(header); if (!settings.noBackToTopLinks && this_level === highest_level) { $(header).addClass('top-level-header'); } var toc_item_id = get_toc_item_id(header.id); if (this_level === level) // same level as before; same indenting html += "<li id='" + toc_item_id + "'><a href='#" + header.id + "'>" + header.innerText + "</a>"; else if (this_level <= level){ // higher level than before; end parent ol for(i = this_level; i < level; i++) { html += "</li></"+settings.listType+">" } html += "<li id='" + toc_item_id + "'><a href='#" + header.id + "'>" + header.innerText + "</a>"; } else if (this_level > level) { // lower level than before; expand the previous to contain a ol for(i = this_level; i > level; i--) { html += "<"+settings.listType+">"; if(i == level + 1) { html += "<li id='" + toc_item_id + "'>"; } else { html += "<li>"; } } html += "<a href='#" + header.id + "'>" + header.innerText + "</a>"; } level = this_level; // update for the next one }); html += "</"+settings.listType+">"; headers.each(function () { var header = $(this); if (!header.next().hasClass("back-to-top")){ // There is a javascript click listener (defined later in this file) for the below to scroll up. var return_to_top = $('<div id="toc_up_' + header.attr('id') + '" class="icon-arrow-up back-to-top" style="text-align:right;">Up↑</div>'); var toc_item_id = get_toc_item_id(header.attr('id')); return_to_top.click(function () { // First, set up the right selections in the table-of-contents menu. // So, the user can follow the trail of highlights menu items and expand the menu items till he reaches the appropriate level. // On 20181119, I spent close to a working day messing with the menu getting it to expand to the right spot; but on realizing that the above is good enough, gave up. var itemToActivate = undefined; $("#toc_ul").find("li").each(function (liIndex, liElement) { // console.debug(liIndex, liElement); if (liElement.id == toc_item_id) { itemToActivate = $(this); } else { $(this).removeClass("active"); } }); itemToActivate.addClass("active"); itemToActivate.parents("li").addClass("active"); // This call is ineffective for some reason. // Now scroll up. $([document.documentElement, document.body]).animate({ scrollTop: $("[id='" + toc_item_id + "']").offset().top }, 100); }); header.after(return_to_top); } }) output.html(html); resetNavgocoMenu(); // Finally, set up navgoco options.
};
function resetNavgocoMenu() {
$('#toc_ul').navgoco({ accordion: true, openClass: 'active', // open save: false, caretHtml: '...', // Make it easier to expand the drawers by increasing click-capture area. cookie: { name: 'navgoco_toc', expires: false, path: '/' }, slide: { duration: 0, // 400ms was causing screen shakes with scrolling to the top by pressing the Up bottons. easing: 'swing' } }); // console.debug("Set up navgoco."); $("#toc_ul").navgoco('toggle', false);
}
function updateToc() {
$('#toc').toc({minimumHeaders: 0, listType: 'ul', headers: 'h2,h3,h4,h5,h6'});
}
// Update table of contents (To be called whenever page contents are updated). $( document ).ready(updateToc);
// Code to make the “Nav” button, which toggles the table of contents. // Not to be confused with toggling sub-items in that menu. var toggleToc = function() {
$("#toc").toggle(); $("#toggle-toc-icon").toggleClass('fa-toggle-on'); $("#toggle-toc-icon").toggleClass('fa-toggle-off');
};
function toggleTocExpansion() {
$("#toggle-toc-expansion-icon").toggleClass('fa-toggle-on'); $("#toggle-toc-expansion-icon").toggleClass('fa-toggle-off'); if($("#toggle-toc-expansion-icon").hasClass('fa-toggle-on')) { $("#toc_ul").navgoco('toggle', true); } else { $("#toc_ul").navgoco('toggle', false); }
}
$(document).ready(function() {
$("#toggle-toc-icon").click(toggleToc); $("#toggle-toc-expansion-icon").click(toggleTocExpansion);
});