diff -r 1783be241488 -r 616d046e3bd9 Wikulator.php --- a/Wikulator.php Wed Dec 24 09:53:25 2008 -0500 +++ b/Wikulator.php Wed Dec 24 11:04:18 2008 -0500 @@ -16,6 +16,7 @@ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. */ +$plugins->attachHook('render_wikiformat_pre', 'mediafier_draw_toc($text);'); $plugins->attachHook('render_wikiformat_post', 'mediafy($result);'); $plugins->attachHook('compile_template', 'mediafier_add_headers();'); $plugins->attachHook('html_attribute_whitelist', '$whitelist["ref"] = array(); $whitelist["references"] = array("/");'); @@ -27,6 +28,66 @@ mediafy_process_references($text); } +function mediafier_draw_toc(&$text) +{ + if ( strstr($text, '__NOTOC__') ) + return true; + + if ( !preg_match_all('/^\s*([=]{1,6})([^\r\n]+)\\1\s*$/m', $text, $matches) ) + return true; + + $heading_map = array(); + foreach ( $matches[1] as $heading ) + { + $heading_map[] = strlen($heading); + } + + if ( count($heading_map) < 4 && !strstr($text, '__TOC__') ) + return true; + + $prev = 0; + $levels = 0; + $treenum = array(); + $toc = ''; + foreach ( $heading_map as $i => $head ) + { + if ( $head > $prev ) + { + $treenum[] = 0; + $levels++; + $toc .= '
'; + } + else if ( $head < $prev ) + { + if ( $levels > 1 ) + { + $toc .= '
'; + $levels--; + unset($treenum[count($treenum)-1]); + } + } + $treenum[count($treenum)-1]++; + if ( $i > 0 ) + $toc .= ''; + $toc .= '
' . implode('.', $treenum) . ' ' . htmlspecialchars($matches[2][$i]) . ''; + $prev = $head; + } + while ( $levels > 0 ) + { + $toc .= '
'; + $levels--; + } + $toc_body = "
+
Contents [hide]
+
$toc
+
"; + + if ( strstr($text, '__TOC__') ) + $text = str_replace_once('__TOC__', $toc_body, $text); + else if ( ($text = preg_replace('/^=/', "$toc_body\n\n=", $text)) === $text ) + $text = str_replace_once("\n=", "\n$toc_body\n=", $text); +} + function mediafier_add_headers() { global $db, $session, $paths, $template, $plugins; // Common objects @@ -37,6 +98,20 @@ "); $ref_script = << +