Skip to main content
All CollectionsPDF Code Examples
Code Example: Dynamic Table of Contents
Code Example: Dynamic Table of Contents
Jonathon Fruchte avatar
Written by Jonathon Fruchte
Updated over 7 years ago

Here's an example document that uses JavaScript to dynamically make a table of contents for your PDF based on HTML heading tags:

<html>
   <body>
      <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>
      <div id="toc">
         <h3>Table of Contents</h3>
      </div>
      <div id="contents">
         <h1>Main Heading (h1)</h1>
         <h2>Second level heading (h2)</h2>
         <h2>Another heading (h2)</h2>
         <h3>Sub heading (h3)</h3>
         <h2>One more second level heading (h2)</h2>
      </div>
   </body>
</html>

Adding Page Numbers

If you'd like the dynamic TOC to include page numbers, you can add it with CSS using generated content and the target-counter  function:

<style>
  #toc li a::after {content: " | Page " target-counter(attr(href), page);}
</style>
Did this answer your question?