Skip to content

Instantly share code, notes, and snippets.

@musen
Last active May 23, 2016 15:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save musen/23278ed72334fb44dd92ff90635cbcae to your computer and use it in GitHub Desktop.
Save musen/23278ed72334fb44dd92ff90635cbcae to your computer and use it in GitHub Desktop.
Generate table of contents from html.
function _generate_toc( $content , $headings, $first_heading) {
preg_match_all( '/<h([' . $headings . '])(.*)>([^<]+)<\/h[' . $headings . ']>/i', $content, $matches, PREG_SET_ORDER );
global $anchors;
$anchors = array();
$toc = '<ul class="nav">'."\n";
$i = 0;
//add the fist anchor link
$toc .= '<li><a href="#page-top">'.$first_heading.'</a></li>';
foreach ( $matches as $heading ) {
if ($i == 0)
$startlvl = $heading[1];
$lvl = $heading[1];
$ret = preg_match( '/id=[\'|"](.*)?[\'|"]/i', stripslashes($heading[2]), $anchor );
if ( $ret && $anchor[1] != '' ) {
$anchor = stripslashes( $anchor[1] );
$add_id = false;
} else {
$anchor = preg_replace( '/\s+/', '-', preg_replace('/[^a-z\s]/', '', strtolower( $heading[3] ) ) );
$add_id = true;
}
if ( !in_array( $anchor, $anchors ) ) {
$anchors[] = $anchor;
} else {
$orig_anchor = $anchor;
$i = 2;
while ( in_array( $anchor, $anchors ) ) {
$anchor = $orig_anchor.'-'.$i;
$i++;
}
$anchors[] = $anchor;
}
if ( $add_id ) {
$content = substr_replace( $content, '<h'.$lvl.' id="'.$anchor.'"'.$heading[2].'>'.$heading[3].'</h'.$lvl.'>', strpos( $content, $heading[0] ), strlen( $heading[0] ) );
}
$ret = preg_match( '/title=[\'|"](.*)?[\'|"]/i', stripslashes( $heading[2] ), $title );
if ( $ret && $title[1] != '' )
$title = stripslashes( $title[1] );
else
$title = $heading[3];
$title = trim( strip_tags( $title ) );
if ($i > 0) {
if ($prevlvl < $lvl) {
$toc .= "\n"."<ul>"."\n";
} else if ($prevlvl > $lvl) {
$toc .= '</li>'."\n";
while ($prevlvl > $lvl) {
$toc .= "</ul>"."\n".'</li>'."\n";
$prevlvl--;
}
} else {
$toc .= '</li>'."\n";
}
}
$j = 0;
$title = explode(':', $title);
$toc .= '<li><a href="#'.$anchor.'">'.$title[0].'</a>';
$prevlvl = $lvl;
$i++;
}
unset( $anchors );
while ( $lvl > $startlvl ) {
$toc .= "\n</ul>";
$lvl--;
}
$toc .= '</li>'."\n";
$toc .= '</ul>'."\n";
return array('toc' => $toc, 'content' => $content);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment