Skip to content

Instantly share code, notes, and snippets.

@apavlinovic
Last active August 1, 2019 10:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save apavlinovic/cef1986296676e3c05afb6f1df9ee74a to your computer and use it in GitHub Desktop.
Save apavlinovic/cef1986296676e3c05afb6f1df9ee74a to your computer and use it in GitHub Desktop.
Table of Contents in JavaScript
function buildTableOfContents (targetContainerId, list_type) {
var toc = "";
var list_type = list_type || 'ol';
var current_nesting_level = 0;
var headings = document
.getElementById(targetContainerId)
.querySelectorAll("h1, h2, h3, h4, h5, h6");
headings.forEach(heading => {
heading.setAttribute('id', generate_safe_anchor_id(heading.innerText));
var heading_level = parseInt(heading.tagName.replace(/H/gi, ''), 0);
if(heading_level == current_nesting_level) {
toc += generate_heading_link(heading);
} else if(heading_level > current_nesting_level) {
current_nesting_level = heading_level;
toc += generate_nest_opening();
toc += generate_heading_link(heading);
} else {
var nested_depth = current_nesting_level - heading_level;
while(nested_depth > 0) {
toc += generate_nest_closing();
nested_depth--;
}
current_nesting_level = heading_level;
toc += generate_heading_link(heading);
}
});
while(current_nesting_level > 0) {
toc += generate_nest_closing();
current_nesting_level--;
}
headings[0].insertAdjacentHTML('beforebegin', toc);
function generate_nest_opening() {
return '<' + list_type + '>\n';
}
function generate_nest_closing() {
return '</' + list_type + '>\n';
}
function generate_safe_anchor_id(text) {
return text.replace(/\s+/gi, '_');
}
function generate_heading_link(heading) {
return '<li><a href="#' + generate_safe_anchor_id(heading.innerText) + '">'
+ heading.innerText
+ '</a></li>';
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment