From c5a8fd9606f6ad8de87e3f7563aa190872e302c0 Mon Sep 17 00:00:00 2001 From: Andreas Gohr <andi@splitbrain.org> Date: Sun, 19 Feb 2006 00:07:44 +0100 Subject: [PATCH] create unique IDs for sections This patch finally completes the support for unique section IDs. To achive this the mechanism how the TOC is build was changed. The TOC now is build in the renderer only. Currently the TOC will be rendered in the end_document function and is then prepended to the doc. This should ensure compatibility with the rest of the code. Adding support for separating the TOC from the page should now be a simpler task in the future. TODO: - Update base class - remove commented old TOC code - make sure no other parts of the code use any of the old TOC code darcs-hash:20060218230744-7ad00-40c5463d93f8ae1c543fb4fed747b2047b4c1302.gz --- inc/html.php | 13 +++++++- inc/parser/handler.php | 7 +++- inc/parser/xhtml.php | 76 +++++++++++++++++++++++++++++++++++++++--- 3 files changed, 90 insertions(+), 6 deletions(-) diff --git a/inc/html.php b/inc/html.php index f9acd7325..46336b68d 100644 --- a/inc/html.php +++ b/inc/html.php @@ -647,6 +647,9 @@ function html_li_default($item){ * print the <li> tag. Both user function need to accept * a single item. * + * Both user functions can be given as array to point to + * a member of an object. + * * @author Andreas Gohr <andi@splitbrain.org> */ function html_buildlist($data,$class,$func,$lifunc='html_li_default'){ @@ -678,9 +681,17 @@ function html_buildlist($data,$class,$func,$lifunc='html_li_default'){ $level = $item['level']; //print item - $ret .= $lifunc($item); //user function + if(is_array($lifunc)){ + $ret .= $lifunc[0]->$lifunc[1]($item); //user object method + }else{ + $ret .= $lifunc($item); //user function + } $ret .= '<div class="li">'; + if(is_array($func)){ + $ret .= $func[0]->$func[1]($item); //user object method + }else{ $ret .= $func($item); //user function + } $ret .= '</div>'; } diff --git a/inc/parser/handler.php b/inc/parser/handler.php index 3609e23a8..4653cf603 100644 --- a/inc/parser/handler.php +++ b/inc/parser/handler.php @@ -37,10 +37,12 @@ class Doku_Handler { $this->calls = $B->process($this->calls); } +/** FIXME deprecated if ( $this->meta['toc'] ) { $T = & new Doku_Handler_Toc(); $this->calls = $T->process($this->calls); } +*/ array_unshift($this->calls,array('document_start',array(),0)); $last_call = end($this->calls); @@ -1495,6 +1497,9 @@ class Doku_Handler_Block { } //------------------------------------------------------------------------ + +/** FIXME deprecated + define('DOKU_TOC_OPEN',1); define('DOKU_TOCBRANCH_OPEN',2); define('DOKU_TOCITEM_OPEN',3); @@ -1671,6 +1676,6 @@ class Doku_Handler_Toc { } } - +*/ //Setup VIM: ex: et ts=4 enc=utf-8 : diff --git a/inc/parser/xhtml.php b/inc/parser/xhtml.php index 1c7343cda..a54e5bcab 100644 --- a/inc/parser/xhtml.php +++ b/inc/parser/xhtml.php @@ -25,7 +25,10 @@ require_once DOKU_INC . 'inc/parser/renderer.php'; */ class Doku_Renderer_xhtml extends Doku_Renderer { - var $doc = ''; + // @access public + var $doc = ''; // will contain the whole document + var $toc = array(); // will contain the Table of Contents + var $headers = array(); @@ -42,6 +45,9 @@ class Doku_Renderer_xhtml extends Doku_Renderer { var $store = ''; function document_start() { + //reset some internals + $this->toc = array(); + $this->headers = array(); } function document_end() { @@ -81,8 +87,39 @@ class Doku_Renderer_xhtml extends Doku_Renderer { } $this->doc .= '</div>'.DOKU_LF; } + + // prepend the TOC + $this->doc = $this->render_TOC().$this->doc; + } + + /** + * Return the TOC rendered to XHTML + * + * @author Andreas Gohr <andi@splitbrain.org> + */ + function render_TOC(){ + if(!count($this->toc)) return ''; + global $lang; + $out = '<div class="toc">'.DOKU_LF; + $out .= '<div class="tocheader toctoggle" id="toc__header">'; + $out .= $lang['toc']; + $out .= '</div>'.DOKU_LF; + $out .= '<div id="toc__inside">'.DOKU_LF; + $out .= html_buildlist($this->toc,'toc',array($this,'_tocitem')); + $out .= '</div>'.DOKU_LF.'</div>'.DOKU_LF; + return $out; } + /** + * Callback for html_buildlist + */ + function _tocitem($item){ + return '<span class="li"><a href="#'.$item['hid'].'" class="toc">'. + $this->_xmlEntities($item['title']).'</a></span>'; + } + +/** FIXME deprecated + function toc_open() { global $lang; $this->doc .= '<div class="toc">'.DOKU_LF; @@ -122,6 +159,8 @@ class Doku_Renderer_xhtml extends Doku_Renderer { $this->doc .= '</div>'.DOKU_LF.'</div>'.DOKU_LF; } +*/ + function header($text, $level, $pos) { global $conf; //handle section editing @@ -132,7 +171,21 @@ class Doku_Renderer_xhtml extends Doku_Renderer { $this->lastsec = $pos; } - $this->doc .= DOKU_LF.'<h'.$level.'><a name="'.$this->_headerToLink($text).'" id="'.$this->_headerToLink($text).'">'; + // create a unique header id + $hid = $this->_headerToLink($text,'true'); + + //handle TOC +//FIXME if($this->meta['toc'] && + if($level >= $conf['toptoclevel'] && $level <= $conf['maxtoclevel']){ + // the TOC is one of our standard ul list arrays ;-) + $this->toc[] = array( 'hid' => $hid, + 'title' => $text, + 'type' => 'ul', + 'level' => $level); + } + + // write the header + $this->doc .= DOKU_LF.'<h'.$level.'><a name="'.$hid.'" id="'.$hid.'">'; $this->doc .= $this->_xmlEntities($text); $this->doc .= "</a></h$level>".DOKU_LF; } @@ -969,11 +1022,26 @@ class Doku_Renderer_xhtml extends Doku_Renderer { /** * Creates a linkid from a headline + * + * @param string $title The headline title + * @param boolean $create Create a new unique ID? + * @author Andreas Gohr <andi@splitbrain.org> */ - function _headerToLink($title) { - $title = str_replace(':','',cleanID($title,true)); + function _headerToLink($title,$create=false) { + $title = str_replace(':','',cleanID($title,true)); //force ASCII $title = ltrim($title,'0123456789'); if(empty($title)) $title='section'; + + if($create){ + // make sure tiles are unique + $num = ''; + while(in_array($title.$num,$this->headers)){ + ($num) ? $num = 1 : $num++; + } + $title = $title.$num; + $this->headers[] = $title; + } + return $title; } -- GitLab