setupLocale(); } function getInfo() { return array('author' => 'Martin Tschofen', 'email' => 'mtbrains@comcast.net', 'date' => '2007-02-04', 'name' => 'fullindex', 'desc' => 'Collapsable Index with alternate page names and numbers', 'url' => 'https://www.dokuwiki.org/plugin:fullindex'); } function register(&$controller) { $controller->register_hook('TPL_ACT_RENDER', 'BEFORE', $this, 'html_index_clickable'); } function html_index_clickable(&$event){ global $conf; global $ID; if ($event->data != 'index') return; require_once(DOKU_INC.'inc/search.php'); $dir = $conf['datadir']; $ns = cleanID($ns); #fixme use appropriate function if(empty($ns)){ $ns = dirname(str_replace(':','/',$ID)); if($ns == '.') $ns =''; } $ns = utf8_encodeFN(str_replace(':','/',$ns)); print $this->plugin_locale_xhtml('intro'); $data = array(); search($data,$conf['datadir'],array(&$this,'search_fullindex'),array('ns' => $ns)); usort($data, "_strnatSort"); print ''.$this->getLang('collapse_header').''; //if conf is not set to titles if($conf['plugin']['fullindex']['link_names'] == 0){ print $this->html_build_full_list($data,'idx','html_list_index','html_li_index'); } else { //alternative titles print $this->html_build_full_list($data,'idx',array(&$this,'_html_title_index'),'html_li_index'); } // prevent Dokuwiki normal processing of $ACT (it would clean the variable and destroy our 'index' value. $event->preventDefault(); // index command belongs to us, there is no need to hold up Dokuwiki letting other plugins see if its for them $event->stopPropagation(); } /** * Build an unordered list * Based on inc/search.php - @author Andreas Gohr */ function html_build_full_list($data,$class,$func,$lifunc='html_li_default'){ $level = 0; $opens = 0; $ret = ''; foreach ($data as $item){ if( $item['level'] > $level ){ //open new list for($i=0; $i<($item['level'] - $level); $i++){ if ($i) $ret .= "
  • \n"; if ($level > 0) $ret .= "\n\n"; } return $ret; } /** * find all items and collect necessary information */ function search_fullindex(&$data,$base,$file,$type,$lvl,$opts){ global $conf; $return = true; $item = array(); if($type == 'd' && !preg_match('#^'.$file.'(/|$)#','/'.$opts['ns'])){ //always true - only difference to the inc/search.php function $return = true; }elseif($type == 'f' && !preg_match('#\.txt$#',$file)){ //don't add return false; } $id = pathID($file); //check hidden if(isHiddenPage($id)){ return false; } //check ACL if($type=='f' && auth_quickaclcheck($id) < AUTH_READ){ return false; } //don't display any namespace's index file -- displayed as the namespace instead if($type == 'f' && preg_match('#\:'.$conf['start'].'$#', $id)) { return false;} //setup the sort string if($type=='d'){ $num = $this->_getMetaTag($id.":".$conf['start'], 'identifier'); $title = $this->_getMetaTag($id.":".$conf['start'], 'alternative'); } else { $num = $this->_getMetaTag($id, 'identifier'); $title = $this->_getMetaTag($id, 'alternative'); } $data[]=array('id' => $id, 'type' => $type, 'level' => $lvl, 'num' => $num, 'title' => $title, 'open' => $return, 'sort' => $this->_setSortIndex($id, $lvl, $type, $num, $title)); return $return; } /* * Create sort index for each item */ function _setSortIndex($id, $lvl, $type, $num, $title) { global $conf; //directories if ($type == 'd') { //if same add dir to array if(count($this->sortIndex) + 1 == $lvl) { //add to the sortIndex $this->_addToSortIndex($id, $num, $title); } else if (count($this->sortIndex) + 1 > $lvl) { $this->_removeFromSortIndex($lvl); //and add new index $this->_addToSortIndex($id, $num, $title); } else { //remove from index array_pop($this->sortIndex); } $sortIndex = ""; //files } else { if(count($this->sortIndex) + 1 > $lvl) { $this->_removeFromSortIndex($lvl); } $temp = trim($num.$title); if(empty($temp)) { $sortIdx = $id; } else { $sortIdx = $this->_cleanForSort($num)." ".$title; //space required for natsearch fix to work! } } /*debug print_r($type); print_r(": count="); print_r(count($this->sortIndex) + 1); print_r('---lvl='.$lvl.'
    '); print_r("id="); print_r($id); print_r(" "); print_r($this->sortIndex); print_r("
    "); */ return implode("",$this->sortIndex).$sortIdx; } /** * add an namespace to the sortIndex array */ function _addToSortIndex($id, $num, $title){ $newIndex = trim($num.$title); if ($newIndex == "") { $newIndex = strrchr($id, ":"); //what if it was a root ns? if ($newIndex == "") { $newIndex = $id; } } $this->sortIndex[] = $newIndex; } /** * remove any number of namespaces from the sortIndex array */ function _removeFromSortIndex($lvl) { $diff = count($this->sortIndex) + 1 - $lvl; while($diff > 0){ //backed out of namespace array_pop($this->sortIndex); $diff = $diff - 1; } } /** * build the individual items */ function _html_title_index($item){ $ret = ''; $base = ':'.$item['id']; $base = substr($base,strrpos($base,':')+1); if($item['type']=='d'){ $name = $item['num']." ".$item['title']; $name = trim($name); if($name == ''){ $name = $item['id'];} $ret .= html_wikilink(':'.$item['id'].":", $name); //remove link if namespace/globalstart page doesn't exist if(preg_match('#wikilink2#', $ret)) { //should return somekind of meta info for the namespace instead -- only if NS sorting? $ret = ''.noNS($item['id']).''; } } else { $name = $item['num']." ".$item['title']; $name = trim($name); if($name == ''){ $ret .= html_wikilink(':'.$item['id']); } else { $ret .= html_wikilink(':'.$item['id'], $name); } } return $ret; } function _getMetaTag($page, $term) { /*if(!$page){ return ""; }*/ //return the found meta tag $data = p_get_metadata($page); if (array_key_exists($term, $data)){ return $data[$term]; } else { return ""; } } /** * fix the natural sort, if a number has characters imbedded */ function _cleanForSort($num) { return preg_replace('/([a-zA-Z])/', '*$1', $num); } } //end of action class //utilities: natural sort function _strnatSort($a, $b) { return strnatcasecmp($a['sort'], $b['sort']); }