* @author: Reini Urban */ class WikiPlugin_CreateToc extends WikiPlugin { function getName() { return _("CreateToc"); } function getDescription() { return _("Automatically link headers at the top"); } function getVersion() { return preg_replace("/[Revision: $]/", '', "\$Revision: 1.4 $"); } function getDefaultArguments() { return array( 'pagename' => '[pagename]', // not sure yet. TOC of another page here? // or headers=1,2,3 is also possible. 'headers' => "!!!,!!,!", // "!!!" => h1, "!!" => h2, "!" => h3 'noheader' => 0, // omit

Table of Contents

'align' => 'left', 'with_toclink' => 0, // link back to TOC // not yet 'jshide' => 0, // collapsed TOC as DHTML button ); } function preg_quote ($heading) { return str_replace(array("/",".","?","*"), array('\/','\.','\?','\*'), $heading); } function searchHeader ($content, $start_index, $heading, $level) { $count = substr_count($level,'!'); switch ($count) { case 1: $h = "h4"; break; case 2: $h = "h3"; break; case 3: $h = "h2"; break; } for ($j=$start_index; $j$heading<\/$h>/",$content[$j])) return $j; } } trigger_error("Heading <$h> $heading not found\n", E_USER_NOTICE); return 0; } // Feature request: proper nesting function extractHeaders (&$content, &$markup, $backlink=0, $level=2, $basepage='') { $headers = array(); if ($level < 1 or $level > 6) $level = 1; $j = 0; for ($i=0; $i$s line in markup $j = $this->searchHeader($markup->_content, $j, $s, $match[1]); if ( $j and isset($markup->_content[$j]) and is_string($markup->_content[$j]) ) { $x = $markup->_content[$j]; $heading = preg_quote($s); if ($x = preg_replace('/()('.$heading.')(<\/h\d>)/', "\$1\$2\$3",$x)) { if ($backlink) $x = preg_replace('/()('.$heading.')(<\/h\d>)/', "\$1\$2\$3", $markup->_content[$j]); $markup->_content[$j] = $x; } } } } } return $headers; } function run($dbi, $argstr, $request, $basepage) { extract($this->getArgs($argstr, $request)); if ($pagename) { // Expand relative page names. $page = new WikiPageName($pagename, $basepage); $pagename = $page->name; } if (!$pagename) { return $this->error(_("no page specified")); } $page = $dbi->getPage($pagename); $current = $page->getCurrentRevision(); $content = $current->getContent(); $html = HTML::div(array('class' => 'toc','align' => $align)); if (!$noheader) $html->pushContent(HTML::h1(HTML::a(array('name'=>'TOC'),_("Table Of Contents")))); $list = HTML::ul(array('class' => 'toc')); //Todo: replace !!! with level 1, ... //Todo: proper indent of heading if ($headers = $this->extractHeaders(&$content, &$dbi->_markup, $with_toclink, 1, $basepage)) { foreach ($headers as $h) { $link = new WikiPageName($pagename,$page,$h); $list->pushContent(HTML::li(WikiLink($link,'known',$h))); } } //Fixme: Put new contents back to pagecache. // Will require yet another & arg to $plugin->run() $html->pushContent($list); return $html; } }; // $Log: not supported by cvs2svn $ // Revision 1.1 2004/03/01 18:10:28 rurban // first version, without links, anchors and jscript folding // // // For emacs users // Local Variables: // mode: php // tab-width: 8 // c-basic-offset: 4 // c-hanging-comment-ender-p: nil // indent-tabs-mode: nil // End: ?>