soo_toc source code
if(class_exists('\Textpattern\Tag\Registry')) {
Txp::get('\Textpattern\Tag\Registry')
->register('soo_toc');
}
function soo_toc( $atts ) {
global $thisarticle;
assert_article();
extract(lAtts(array(
'label' => '',
'labeltag' => '',
'break' => 'li',
'wraptag' => 'ul',
'class' => 'toc',
'level' => 6,
'full_url' => '',
), $atts));
$full_url = $full_url ? permlinkurl($thisarticle) : '';
$pattern = '/<h(\d)[^>]+?id\s*=\s*"([\w-]+)"[^>]*>(.+?)<\\/h\\1/';
preg_match_all($pattern, $thisarticle['body'], $headings, PREG_SET_ORDER);
$items = array();
foreach ( $headings as $h )
if ( $h[1] <= $level ) {
$filtered[] = $h;
$items[] = '<a href="' . $full_url . '#' . $h[2] . '">' . $h[3] . '</a>';
}
if ( !$items )
return;
if ( $wraptag != 'ul' && $wraptag != 'ol' )
return doLabel($label, $labeltag) . doWrap($items, $wraptag, $break, $class);
$nest_level = 1;
$lines[] = soo_toc_prepend('<li>' . $items[0], t, $nest_level);
for ($i = 1; $i < count($items); $i++) {
$level_change = $filtered[$i][1] - $filtered[$i-1][1];
if ($level_change > 0)
for ($j = 1; $j <= $level_change; $j++) {
$lines[] = soo_toc_prepend("<$wraptag>", t, $nest_level).
($level_change > $j ? '<li>' : '');
$nest_level ++;
}
elseif ($level_change < 0)
for ($j = 1; $j <= -$level_change; $j++) {
$nest_level --;
$lines[] = soo_toc_prepend("</$wraptag></li>", t, $nest_level);
}
$lines[] = soo_toc_prepend('<li>' . $items[$i], t, $nest_level);
}
while ($nest_level > 1) {
$nest_level --;
$lines[] = soo_toc_prepend("</$wraptag></li>", t, $nest_level);
}
for ($i = 0; $i < count($lines)-1; $i++)
if ( preg_match('/<li>/', $lines[$i])
&& !preg_match("/<$wraptag>/", $lines[$i+1]) )
$lines[$i] .= '</li>';
if ( !preg_match("/<\/$wraptag>/", $lines[count($lines)-1]) )
$lines[count($lines)-1] .= '</li>';
$out = '<' . $wraptag . ( $class ? ' class="' . $class . '">' : '>' )
. n . join(n, $lines) . n . "</$wraptag>" . n;
return doLabel($label, $labeltag) . n . $out;
}
function soo_toc_prepend($base, $add, $times) {
for ( $i = 1; $i <= $times; $i++ )
$base = $add . $base;
return $base;
}