phpdynamically-generated

Automatically generate nested table of contents based on heading tags


Which one of you crafty programmers can show me an elegant php coded solution for automatically generating a nested table of contents based on heading tags on the page?

So I have a html document thus:

<h1> Animals </h1>

Some content goes here.
Some content goes here.

<h2> Mammals </h2>

Some content goes here.
Some content goes here.

<h3> Terrestrial Mammals </h3>
Some content goes here.
Some content goes here.

<h3> Marine Mammals </h3>
Some content goes here.
Some content goes here.

<h4> Whales </h4>
Some content goes here.
Some content goes here.

More specifically, I want a linked table of contents in the form of a nested list of links to headings on the same page:

Table of Contents (automatically generated by PHP code)

  1. Animals
    1. Mammals
      1. Terrestrial_Mammals
      2. Marine_Mammals
        1. Whales

Solution

  • I found this method, by Alex Freeman (http://www.10stripe.com/articles/automatically-generate-table-of-contents-php.php):

        preg_match_all('#<h[4-6]*[^>]*>.*?<\/h[4-6]>#',$html_string,$resultats);
    
        //reformat the results to be more usable
        $toc = implode("\n",$resultats[0]);
        $toc = str_replace('<a name="','<a href="#',$toc);
        $toc = str_replace('</a>','',$toc);
        $toc = preg_replace('#<h([4-6])>#','<li class="toc$1">',$toc);
        $toc = preg_replace('#<\/h[4-6]>#','</a></li>',$toc);
    
        //plug the results into appropriate HTML tags
        $toc = '<div id="toc"> 
        <p id="toc-header">Table des matières</p>
        <hr />
        <ul>
        '.$toc.'
        </ul>
        </div><br /><br />';
    
        return $toc;
    

    In the HTML, the headers have to be written as:

    <h2><a name="target"></a>Text</h2>