Skip to content

Instantly share code, notes, and snippets.

@schuyberg
Created October 20, 2016 21:38
Show Gist options
  • Save schuyberg/f672c82b4fd6a64d267e5e4ecf3cd698 to your computer and use it in GitHub Desktop.
Save schuyberg/f672c82b4fd6a64d267e5e4ecf3cd698 to your computer and use it in GitHub Desktop.
// generates a table of contents
// blame @schuyberg 2016
//
//
// use on jquery object you want it appended before (usually first header)
// hStart = number: html heading level to start on (ie. 2 would be h2)
// depth = number: depth to traverse heading heirarchy (h2 + 1 = h2, h3)
// example: jQuery('h2').first().toc(2,1); --> adds contents before first h2 tag, includes h2, h3 tags.
$.fn.toc = function(hStart, depth){
return makeToC(this, hStart, depth);
function makeToC(before, hStart, depth) {
var el, title, link, newLine;
var levels = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'];
var depth = depth || 0;
var startLevel = hStart-1;
var ToC = "<nav role='navigation' class='table-of-contents'>"
+ "<h4>Contents</h4>"
+ "<ul>";
tocLine($(levels[startLevel]), startLevel, depth);
ToC += "</ul>"
+ "</nav>";
$(before).before(ToC);
function tocLine(selector, thisLevel, depth){
$.each(selector,function(i, v){
el = $(this), title = el.text();
if (title !== '') { // skip blank headings .. maybe other things if you want here
if (el.attr('id')) {
link = el.attr('id');
} else {
var newLink = title.replace(/\s/g, '-').toLowerCase();
el.attr('id', newLink);
link = '#' + newLink;
}
newLine = "<li>"
+ "<a href='" + link + "'>" + title + "</a>"
+ "</li>";
ToC += newLine;
}
if (depth > 0) {
var sel = $(el).nextUntil(levels[thisLevel],levels[thisLevel + 1]);
ToC += "<ul>";
tocLine(sel, thisLevel + 1, depth - 1);
ToC += "</ul>";
}
});
}
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment