1<?php 2/** 3 * Add smart navigation capability to dokuwiki 4 * 5 * Roland Hellebart's tree plugin ( his http://wiki.splitbrain.org/plugin:tree ) 6 * was used as a base for this. 7 * 8 * Documentation is located at http://wiki.splitbrain.org/plugin:navilevel 9 * 10 * @license GNU_GPL_v2 11 * @author Thanos Massias 12 */ 13 14if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/'); 15if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/'); 16require_once(DOKU_PLUGIN.'syntax.php'); 17 18/** 19 * All DokuWiki plugins to extend the parser/rendering mechanism 20 * need to inherit from this class 21 */ 22 class syntax_plugin_navilevel extends DokuWiki_Syntax_Plugin { 23 24 25 function getInfo(){ 26 return array( 27 'author' => 'Thanos Massias', 28 'email' => 'thanos.massias@gmail.com', 29 'date' => '2007-06-14', 30 'name' => 'navilevel Plugin', 31 'desc' => 'Add smart Navigation Capability', 32 'url' => 'http://www.acsys.gr/plugins/navilevel/', 33 ); 34 } 35 36 /** 37 * What kind of syntax are we? 38 */ 39 function getType(){ 40 return 'protected'; 41 } 42 43 /** 44 * What kind of syntax do we allow (optional) 45 */ 46 function getAllowedTypes() { 47 return array('protected'); 48 } 49 50 /** 51 * What about paragraphs? (optional) 52 */ 53 function getPType(){ 54 return 'block'; 55 } 56 57 /** 58 * Where to sort in? 59 */ 60 function getSort(){ 61 return 203; 62 } 63 64 /** 65 * Connect pattern to lexer 66 */ 67 function connectTo($mode) { 68 $this->Lexer->addEntryPattern('<navilevel.*?>(?=.*?</navilevel>)',$mode,'plugin_navilevel'); 69 } 70 71 function postConnect() { 72 $this->Lexer->addExitPattern('</navilevel>','plugin_navilevel'); 73 } 74 75 /** 76 * Handle the match 77 */ 78 function handle($match, $state, $pos, &$handler){ 79 switch ($state) { 80 case DOKU_LEXER_ENTER : 81 break; 82 case DOKU_LEXER_MATCHED : 83 break; 84 case DOKU_LEXER_UNMATCHED : 85 break; 86 case DOKU_LEXER_EXIT : 87 break; 88 case DOKU_LEXER_SPECIAL : 89 break; 90 } 91 return array($match, $state); 92 } 93 94 /** 95 * Create output 96 */ 97 function render($mode, &$renderer, $data) { 98 // You may have to configure $rellevel to suite your site 99 // 100 // $lowlevel = 1; --> sites not based on per-namespace start pages (default) 101 // $lowlevel = 2; --> sites based on per-namespace start pages 102 // 103 $lowlevel = 1; 104 105 global $ID; 106 global $ullevellast; 107 $linklineID = ':'.$ID; 108 // In case you want the plugin to work correctly within a sidebar add the 109 // following two lines in '/dokuwiki_home/lib/tpl/template_name/main.php': 110 // --------------------- 111 // global $PPID; 112 // $PPID = $ID; 113 // --------------------- 114 global $PPID; 115 if ('X'.$PPID != 'X'){ 116 if ($ID != $PPID){ 117 $linklineID = ':'.$PPID; 118 } 119 } 120 $partsID = explode(':', $linklineID); 121 $countpartsID = count($partsID); 122 123 $showall = 0; 124 if (($countpartsID == 2) && ($partsID[1] == 'sitemap')){ 125 $showall = 1; 126 } 127 128 if($mode == 'xhtml'){ 129 switch ($data[1]) { 130 case DOKU_LEXER_ENTER : 131 $renderer->doc .= "\n"; 132 break; 133 134 case DOKU_LEXER_MATCHED : 135 break; 136 137 case DOKU_LEXER_UNMATCHED : 138 $content = $data[0]; 139 140 // clean up the input data 141 // clear any trailing or leading empty lines from the data set 142 $content = preg_replace("/[\r\n]*$/","",$content); 143 $content = preg_replace("/^\s*[\r\n]*/","",$content); 144 145 // Not sure if PHP handles the DOS \r\n or Mac \r, so being paranoid 146 // and converting them if they exist to \n 147 $content = preg_replace("/\r\n/","\n",$content); 148 $content = preg_replace("/\r/","\n",$content); 149 $result = $this->tree_explode_node($content); 150 151 $ullevellast = 0; 152 153 foreach ($result as $input){ 154 $arrinput = explode('|', $input); 155 $linkline = $arrinput[0]; 156 $linkline = trim($linkline); 157 $linktext_before = $arrinput[1]; 158 $linktext_before = trim($linktext_before); 159 $linkname = $arrinput[2]; 160 $linkname = trim($linkname); 161 $linktext_after = $arrinput[3]; 162 $linktext_after = trim($linktext_after); 163 if (strlen($linkline) > 0) { 164 $linkline = cleanID($linkline); 165 if (substr($linkline,0,1) != ':'){ 166 $linkline = ':'.$linkline; 167 } 168 169 $parts = explode(':', $linkline); 170 $countparts = count($parts); 171 172 $listlink = 0; 173 // low level links 174 if ($countparts < (2 + $lowlevel)){ 175 $listlink = 1; 176 }else{ 177 // children, yes - grandchildren and beyond, no 178 if ($countparts <= $countpartsID + 1){ 179 $listlink = 1; 180 $tmppathID = ''; 181 $tmppath = ''; 182 $i = 0; 183 foreach ($parts as $part){ 184 if (($i > 0) && ($i < $countparts - 2)){ 185 if ('X'.$partsID[$i] != 'X') { 186 $tmppathID .= ':'.$partsID[$i]; 187 $tmppath .= ':'.$parts[$i]; 188 if ($tmppathID !== $tmppath){ 189 $listlink = 0; 190 } 191 } 192 } 193 $i++; 194 } 195 } 196 } 197 198 if ($listlink || $showall){ 199 $ullevel = $countparts - 1; 200 if ($ullevel == $ullevellast){ 201 $renderer->doc .= "\n</li>"; 202 } 203 if ($ullevel > $ullevellast){ 204 $renderer->doc .= "\n<ul>"; 205 } 206 if ($ullevel < $ullevellast){ 207 for ($j = 0; $j < ($ullevellast - $ullevel); $j++){ 208 $renderer->doc .= "\n</li>\n</ul>"; 209 } 210 $renderer->doc .= "\n</li>"; 211 } 212 $ullevellast = $ullevel; 213 $renderer->doc .= "\n".'<li class="level'.$ullevel.'"><div class="li"> '; 214 if (strlen($linktext_before) > 0) { 215 $renderer->doc .= $linktext_before.' '; 216 } 217 if (strlen($linkname) > 0) { 218 $renderer->doc .= $renderer->internallink($linkline,$linkname); 219 }else{ 220 $renderer->doc .= $renderer->internallink($linkline); 221 } 222 if (strlen($linktext_after) > 0) { 223 $renderer->doc .= ' '.$linktext_after; 224 } 225 $renderer->doc .= "</div>"; 226 }else{ 227 $renderer->doc .= ""; 228 } 229 } 230 } 231 break; 232 233 case DOKU_LEXER_EXIT : 234 $ullevel = 1; 235 if ($ullevel == $ullevellast){ 236 $renderer->doc .= "\n</li>"; 237 } 238 if ($ullevel > $ullevellast){ 239 $renderer->doc .= "\n<ul>"; 240 } 241 if ($ullevel < $ullevellast){ 242 for ($j = 0; $j < ($ullevellast - $ullevel); $j++) { 243 $renderer->doc .= "\n</li>\n</ul>"; 244 } 245 $renderer->doc .= "\n</li>"; 246 } 247 $renderer->doc .= "\n</ul>"; 248 break; 249 250 case DOKU_LEXER_SPECIAL : 251 break; 252 } 253 return false; 254 } 255 256 // unsupported $mode 257 return false; 258 } 259 260 function tree_explode_node(&$str) { 261 $len = strlen($str) + 1; 262 $inside = false; 263 $word = ''; 264 for ($i = 0; $i < $len; ++$i) { 265 $next = $i+1; 266 if ($str[$i] == "\n") { 267 $out[] = $word; 268 $word = ''; 269 } elseif ($next == $len) { 270 $out[] = $word; 271 $word = ''; 272 } else { 273 $word .= $str[$i]; 274 } 275 } 276 $str = substr($str, $next); 277 $out[] = $word; 278 return $out; 279 } 280} 281 282//Setup VIM: ex: et ts=4 enc=utf-8 : 283?> 284