Skip to content

Instantly share code, notes, and snippets.

@steve-kasica
Created April 25, 2017 19:01
Show Gist options
  • Save steve-kasica/0710b72d995aac51fcb05e90bc2b7d9f to your computer and use it in GitHub Desktop.
Save steve-kasica/0710b72d995aac51fcb05e90bc2b7d9f to your computer and use it in GitHub Desktop.
Nested TOC POC

Nested TOC POC

A proof of concept for nesting a list items in table of contents generated by HTML headings. The following JavaScript/jQuery code coerces DOM nodeName properties into UTF-16 code units to compare heading, a stack to keep track of parent headings, and a post-test loop to nest headings according to W3 specification.

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Nested TOC POC</title>
<style media="screen">
div {
display: inline-block;
}
.content {
width: 66.6666%;
}
.toc {
width: 33.3333%;
float: right;
}
</style>
</head>
<body>
<div class="content">
<h1>1</h1>
<h2>1.1</h2>
<h3>1.1.1</h3>
<h4>1.1.1.1</h4>
<h5>1.1.1.1.1</h5>
<h6>1.1.1.1.1.1</h6>
<h5>1.1.1.1.2</h5>
<h4>1.1.1.2</h4>
<h3>1.1.2</h3>
<h2>1.2</h2>
<h1>2</h1>
<h2>2.1</h2>
<h3>2.1.1</h3>
<h4>2.1.1.1</h4>
<h5>2.1.1.1.1</h5>
<h6>2.1.1.1.1.1</h6>
<h5>2.1.1.1.2</h5>
<h4>2.1.1.2</h4>
<h5>2.1.1.2.1</h5>
<h3>2.1.2</h3>
<h4>2.1.2.1</h4>
<h2>2.2</h2>
</div>
<div class="toc">
<p>Table of Contents</p>
<hr>
</div>
<script
src="https://code.jquery.com/jquery-2.2.4.min.js"
integrity="sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44="
crossorigin="anonymous"></script>
<script type="text/javascript">
Array.prototype.last = function() {
return this[this.length-1];
}
var parents = [];
$(document).ready(function() {
var headings = $('h1,h2,h3,h4,h5,h6');
var ul = $('<ul/>');
headings.each(function(i, heading) {
var a = $('<a/>').text(heading.innerText).attr({
href: '#' + heading.innerText,
'heading-node': heading.nodeName,
});
var li = $('<li/>').append(a);
var isAppended, parent;
do {
isAppended = true;
if (!parents.length) {
parents.push({ nodeName: heading.nodeName, li: li });
ul.append(li);
} else {
parent = parents[parents.length - 1];
if (parent.nodeName < heading.nodeName) {
ul.find(parent.li).append( $('<ul/>').append(li) );
parents.push({ nodeName: heading.nodeName, li: li });
} else {
parents.pop();
isAppended = false;
}
}
} while (!isAppended);
});
$('.toc').append(ul);
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment