Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
289 views
in Technique[技术] by (71.8m points)

php - 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
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

I don't find it elegant, but might help in getting general idea how to create one ;)

It uses simple_html_dom to find and manipulate elements in original html

$htmlcode = <<< EOHTML
<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.
EOHTML;
// simpehtmldom or other dom manipulating library
require_once 'simple_html_dom.php';

$html = str_get_html($htmlcode);

$toc = '';
$last_level = 0;

foreach($html->find('h1,h2,h3,h4,h5,h6') as $h){
    $innerTEXT = trim($h->innertext);
    $id =  str_replace(' ','_',$innerTEXT);
    $h->id= $id; // add id attribute so we can jump to this element
    $level = intval($h->tag[1]);

    if($level > $last_level)
        $toc .= "<ol>";
    else{
        $toc .= str_repeat('</li></ol>', $last_level - $level);
        $toc .= '</li>';
    }

    $toc .= "<li><a href='#{$id}'>{$innerTEXT}</a>";

    $last_level = $level;
}

$toc .= str_repeat('</li></ol>', $last_level);
$html_with_toc = $toc . "<hr>" . $html->save();

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

57.0k users

...