Forum How do I...?

TOC Generation

talyrobin
How can I use my existing header tags to create Table of Contents?
mikeday
You can write JavaScript to scan for the headings and create links to them.
talyrobin
I added this which prints the TOC in my html, but not when I convert to PDF using Prince. Do I need to do anything special for Prince?

<script>
window.onload = function () {
var toc = "";
var level = 0;

document.getElementById("contents").innerHTML =
document.getElementById("contents").innerHTML.replace(
/<h([\d])>([^<]+)<\/h([\d])>/gi,
function (str, openLevel, titleText, closeLevel) {
if (openLevel != closeLevel) {
return str;
}

if (openLevel > level) {
toc += (new Array(openLevel - level + 1)).join("<ul>");
} else if (openLevel < level) {
toc += (new Array(level - openLevel + 1)).join("</ul>");
}

level = parseInt(openLevel);

var anchor = titleText.replace(/ /g, "_");
toc += "<li><a href=\"#" + anchor + "\">" + titleText
+ "</a></li>";

return "<h" + openLevel + "><a name=\"" + anchor + "\">"
+ titleText + "</a></h" + closeLevel + ">";
}
);

if (level) {
toc += (new Array(level + 1)).join("</ul>");
}

document.getElementById("toc").innerHTML += toc;
};
</script>
mikeday
Are you getting any error messages in the output log? And are the "contents" and "toc" IDs referring to two separate elements, or should they be the same element?
talyrobin
No errors in the log. This is what I have...

<body>

<div id="toc">
<h3>Table of Contents</h3>
</div>

<div id="contents">
.
...my html contents are here
.
</div>

<script>
window.onload = function () {
var toc = "";
var level = 0;

document.getElementById("contents").innerHTML =
document.getElementById("contents").innerHTML.replace(
/<h([\d])>([^<]+)<\/h([\d])>/gi,
function (str, openLevel, titleText, closeLevel) {
if (openLevel != closeLevel) {
return str;
}

if (openLevel > level) {
toc += (new Array(openLevel - level + 1)).join("<ul>");
} else if (openLevel < level) {
toc += (new Array(level - openLevel + 1)).join("</ul>");
}

level = parseInt(openLevel);

var anchor = titleText.replace(/ /g, "_");
toc += "<li><a href=\"#" + anchor + "\">" + titleText + "</a></li>";

return "<h" + openLevel + "><a name=\"" + anchor + "\">"
+ titleText + "</a></h" + closeLevel + ">";
}
);

if (level) {
toc += (new Array(level + 1)).join("</ul>");
}

document.getElementById("toc").innerHTML += toc;
};
</script>
</body>
mikeday
It works fine for me if I add some headings like this:
<div id="contents">
<h1>Main Heading</h1>
<h2>Uh oh</h2>
<h2>Another heading</h2>
<h3>Sub heading</h3>
<h2>Yet again</h2>
</div>