So, I slapped together a quick TOC generator this morning. Yay coffee.
If you have a document that makes a few small requirements, then this script will pull a table of contents out of your document automatically, using the text of headers as the table of contents text. All table of contents items will be generated as links to their position in the document, then will provide a dot leader and a generated page number. The example below styles them to look pretty okay.
This code will be part of my utility library, http://scutil.com/ (also available at github,) probably by the end of the day or so.
The way this works is to scan the DOM and build a list of every <h1>, <h2> .. <h6> that is not marked notoc (that is, <h1 notoc="notoc"> will be ignored.) Then, it goes to the location you pass it as a target, and builds a nested <ol> containing <li><a href="header id"></li> to represent the ToC. It is assumed that CSS will be used to fill the TOC out; that way you don't have to screw with the code to set what your ToC looks like. An example of how to do that is given below.
This script assumes two requirements of any header that isn't marked notoc. Headers marked notoc will be ignored.
The first is that every header must have a unique id. That ID is how this script hooks the links, page numbers and text content in the ToC to the element. If you forget to set a header's id, there will be a broken row in your table of contents, with an empty text spot and a zero page number.
The other is that this script will fail, and halt generation of your document, if headers jump by more than one step upwards. So, using <h1> then <h3> and then invoking this script will Cause Much Fail (tm). You could get around that with notoc if you're using headers for styling purposes, but then, if you're using headers for styling purposes, bad!
That's enough to build a table of contents magically. An example of using it is given below, assuming that you've cut and pasted that code into a file called toc.js.
If you have a document that makes a few small requirements, then this script will pull a table of contents out of your document automatically, using the text of headers as the table of contents text. All table of contents items will be generated as links to their position in the document, then will provide a dot leader and a generated page number. The example below styles them to look pretty okay.
This code will be part of my utility library, http://scutil.com/ (also available at github,) probably by the end of the day or so.
The way this works is to scan the DOM and build a list of every <h1>, <h2> .. <h6> that is not marked notoc (that is, <h1 notoc="notoc"> will be ignored.) Then, it goes to the location you pass it as a target, and builds a nested <ol> containing <li><a href="header id"></li> to represent the ToC. It is assumed that CSS will be used to fill the TOC out; that way you don't have to screw with the code to set what your ToC looks like. An example of how to do that is given below.
This script assumes two requirements of any header that isn't marked notoc. Headers marked notoc will be ignored.
The first is that every header must have a unique id. That ID is how this script hooks the links, page numbers and text content in the ToC to the element. If you forget to set a header's id, there will be a broken row in your table of contents, with an empty text spot and a zero page number.
The other is that this script will fail, and halt generation of your document, if headers jump by more than one step upwards. So, using <h1> then <h3> and then invoking this script will Cause Much Fail (tm). You could get around that with notoc if you're using headers for styling purposes, but then, if you're using headers for styling purposes, bad!
function LinkTo(Tgt) {
var InA = document.createElement('a');
InA.setAttribute('href', '#' + Tgt); // prince bug: foo.href = bar; doesn't work!
return InA;
}
function TocItem(Tgt) {
var InLI = document.createElement('li');
InLI.appendChild(LinkTo(Tgt));
return InLI;
}
function ToCwalk(Source) {
var InOL = document.createElement('ol');
var DStack = [];
var Walker = function(lSource) {
switch (lSource.nodeName.toString().toUpperCase()) {
case 'H1': if (lSource.getAttribute('notoc') !== 'notoc') { DStack.push({d:1, t:lSource.id}); } break;
case 'H2': if (lSource.getAttribute('notoc') !== 'notoc') { DStack.push({d:2, t:lSource.id}); } break;
case 'H3': if (lSource.getAttribute('notoc') !== 'notoc') { DStack.push({d:3, t:lSource.id}); } break;
case 'H4': if (lSource.getAttribute('notoc') !== 'notoc') { DStack.push({d:4, t:lSource.id}); } break;
case 'H5': if (lSource.getAttribute('notoc') !== 'notoc') { DStack.push({d:5, t:lSource.id}); } break;
case 'H6': if (lSource.getAttribute('notoc') !== 'notoc') { DStack.push({d:6, t:lSource.id}); } break;
default : break;
}
if (lSource.hasChildNodes()) {
var tNode = lSource.firstChild;
do {
Walker(tNode);
} while (tNode = tNode.nextSibling);
}
}
Walker(Source);
var curDepth = 1;
var curStack = [InOL];
var childStack = [];
var lastChild = null;
for (var i=0, iC=DStack.length; i<iC; ++i) {
var gap = DStack[i].d - curDepth;
switch (gap) {
case 0:
lastChild = TocItem(DStack[i].t)
curStack[curStack.length-1].appendChild(lastChild);
break;
case 1:
++curDepth;
childStack.push(lastChild);
var newList = document.createElement('ol');
curStack.push(newList);
lastChild.appendChild(newList);
lastChild = TocItem(DStack[i].t)
curStack[curStack.length-1].appendChild(lastChild);
break;
default:
if (gap > 0) {
Log.error("Header depth increased by more than one!");
} else {
for (z=0; z>gap; --z) {
--curDepth;
childStack.pop();
curStack.pop();
}
lastChild = TocItem(DStack[i].t)
curStack[curStack.length-1].appendChild(lastChild);
}
break;
}
}
return InOL;
}
That's enough to build a table of contents magically. An example of using it is given below, assuming that you've cut and pasted that code into a file called toc.js.
<?xml version="1.0" standalone="no" ?>
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="toc.js"></script>
<style type="text/css">
breaker { display: block; page-break-after: always; }
#ToCol { margin: 1.5em 0 0 1.5em; }
#ToCol a { color: black; text-decoration: none; content: target-content(attr(href)); }
#ToCol a::after { content: " " leader(".") " " target-counter(attr(href), page); }
#ToCol ol { margin-left: 2em; }
#ToCol li { margin-top: 0.3em; }
.lorem { color: #bbb; }
</style>
<script type="text/javascript">
function init() {
var Body = document.getElementById('bodyid'); // this is what we're scanning
var ToC = ToCwalk(Body); // make the ToC
ToC.id = 'ToCol'; // give it an id, for CSS
document.getElementById('ToCbox').appendChild(ToC); // put the ToC in place.
}
</script>
</head>
<body id="bodyid" onload="init();">
<div id="ToCbox"></div>
<breaker/>
<h1 id="firstId">First</h1>
<p>Hi, hello</p>
<p>How are you</p>
<p class="lorem">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<p class="lorem">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<h2 id="firstDetailId">Details</h2>
<p>Just fine, thanks</p>
<p class="lorem">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<p class="lorem">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<h2 id="firstSiblingDetailId">More Details</h2>
<p>Nice weather we're having</p>
<p class="lorem">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<p class="lorem">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<h1 id="secondId">Second</h1>
<p>Hi, hello</p>
<p>How are you</p>
<p class="lorem">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<p class="lorem">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<h2 id="secondDetailId">Details</h2>
<p>Just fine, thanks</p>
<p class="lorem">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<p class="lorem">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<h3 id="inceptionGoDeeperBwomp">Deeper this time</h3>
<p>Would like a coffee though</p>
<p class="lorem">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<p class="lorem">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<h3 id="theJokeIsGettingOld">More TOC please</h3>
<p>And maybe a bagel?</p>
<p class="lorem">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<p class="lorem">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<h2 id="Eisenhower">More Details</h2>
<p>Bagel bagel bagel.</p>
<p class="lorem">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<p class="lorem">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<h1 id="ThatsAWrap">Postscript</h1>
<p>was a nice language</p>
</body>
</html>
John Haugeland is http://fullof.bs/