1<?php 2/** 3 * Renderer for metadata 4 * 5 * @author Esther Brunner <wikidesign@gmail.com> 6 */ 7if(!defined('DOKU_INC')) die('meh.'); 8 9if ( !defined('DOKU_LF') ) { 10 // Some whitespace to help View > Source 11 define ('DOKU_LF',"\n"); 12} 13 14if ( !defined('DOKU_TAB') ) { 15 // Some whitespace to help View > Source 16 define ('DOKU_TAB',"\t"); 17} 18 19require_once DOKU_INC . 'inc/parser/renderer.php'; 20 21/** 22 * The Renderer 23 */ 24class Doku_Renderer_metadata extends Doku_Renderer { 25 26 var $doc = ''; 27 var $meta = array(); 28 var $persistent = array(); 29 30 var $headers = array(); 31 var $capture = true; 32 var $store = ''; 33 34 function getFormat(){ 35 return 'metadata'; 36 } 37 38 function document_start(){ 39 // reset metadata to persistent values 40 $this->meta = $this->persistent; 41 } 42 43 function document_end(){ 44 // store internal info in metadata (notoc,nocache) 45 $this->meta['internal'] = $this->info; 46 47 if (!$this->meta['description']['abstract']){ 48 // cut off too long abstracts 49 $this->doc = trim($this->doc); 50 if (strlen($this->doc) > 500) 51 $this->doc = utf8_substr($this->doc, 0, 500).'…'; 52 $this->meta['description']['abstract'] = $this->doc; 53 } 54 } 55 56 function toc_additem($id, $text, $level) { 57 global $conf; 58 59 //only add items within configured levels 60 if($level >= $conf['toptoclevel'] && $level <= $conf['maxtoclevel']){ 61 // the TOC is one of our standard ul list arrays ;-) 62 $this->meta['description']['tableofcontents'][] = array( 63 'hid' => $id, 64 'title' => $text, 65 'type' => 'ul', 66 'level' => $level-$conf['toptoclevel']+1 67 ); 68 } 69 70 } 71 72 function header($text, $level, $pos) { 73 74 if (!$this->meta['title']) $this->meta['title'] = $text; 75 76 // add the header to the TOC 77 $hid = $this->_headerToLink($text,'true'); 78 $this->toc_additem($hid, $text, $level); 79 80 // add to summary 81 if ($this->capture && ($level > 1)) $this->doc .= DOKU_LF.$text.DOKU_LF; 82 } 83 84 function section_open($level){} 85 function section_close(){} 86 87 function cdata($text){ 88 if ($this->capture) $this->doc .= $text; 89 } 90 91 function p_open(){ 92 if ($this->capture) $this->doc .= DOKU_LF; 93 } 94 95 function p_close(){ 96 if ($this->capture){ 97 if (strlen($this->doc) > 250) $this->capture = false; 98 else $this->doc .= DOKU_LF; 99 } 100 } 101 102 function linebreak(){ 103 if ($this->capture) $this->doc .= DOKU_LF; 104 } 105 106 function hr(){ 107 if ($this->capture){ 108 if (strlen($this->doc) > 250) $this->capture = false; 109 else $this->doc .= DOKU_LF.'----------'.DOKU_LF; 110 } 111 } 112 113 function strong_open(){} 114 function strong_close(){} 115 116 function emphasis_open(){} 117 function emphasis_close(){} 118 119 function underline_open(){} 120 function underline_close(){} 121 122 function monospace_open(){} 123 function monospace_close(){} 124 125 function subscript_open(){} 126 function subscript_close(){} 127 128 function superscript_open(){} 129 function superscript_close(){} 130 131 function deleted_open(){} 132 function deleted_close(){} 133 134 /** 135 * Callback for footnote start syntax 136 * 137 * All following content will go to the footnote instead of 138 * the document. To achieve this the previous rendered content 139 * is moved to $store and $doc is cleared 140 * 141 * @author Andreas Gohr <andi@splitbrain.org> 142 */ 143 function footnote_open() { 144 if ($this->capture){ 145 // move current content to store and record footnote 146 $this->store = $this->doc; 147 $this->doc = ''; 148 } 149 } 150 151 /** 152 * Callback for footnote end syntax 153 * 154 * All rendered content is moved to the $footnotes array and the old 155 * content is restored from $store again 156 * 157 * @author Andreas Gohr 158 */ 159 function footnote_close() { 160 if ($this->capture){ 161 // restore old content 162 $this->doc = $this->store; 163 $this->store = ''; 164 } 165 } 166 167 function listu_open(){ 168 if ($this->capture) $this->doc .= DOKU_LF; 169 } 170 171 function listu_close(){ 172 if ($this->capture && (strlen($this->doc) > 250)) $this->capture = false; 173 } 174 175 function listo_open(){ 176 if ($this->capture) $this->doc .= DOKU_LF; 177 } 178 179 function listo_close(){ 180 if ($this->capture && (strlen($this->doc) > 250)) $this->capture = false; 181 } 182 183 function listitem_open($level){ 184 if ($this->capture) $this->doc .= str_repeat(DOKU_TAB, $level).'* '; 185 } 186 187 function listitem_close(){ 188 if ($this->capture) $this->doc .= DOKU_LF; 189 } 190 191 function listcontent_open(){} 192 function listcontent_close(){} 193 194 function unformatted($text){ 195 if ($this->capture) $this->doc .= $text; 196 } 197 198 function php($text){} 199 200 function phpblock($text){} 201 202 function html($text){} 203 204 function htmlblock($text){} 205 206 function preformatted($text){ 207 if ($this->capture) $this->doc .= $text; 208 } 209 210 function file($text){ 211 if ($this->capture){ 212 $this->doc .= DOKU_LF.$text; 213 if (strlen($this->doc) > 250) $this->capture = false; 214 else $this->doc .= DOKU_LF; 215 } 216 } 217 218 function quote_open(){ 219 if ($this->capture) $this->doc .= DOKU_LF.DOKU_TAB.'"'; 220 } 221 222 function quote_close(){ 223 if ($this->capture){ 224 $this->doc .= '"'; 225 if (strlen($this->doc) > 250) $this->capture = false; 226 else $this->doc .= DOKU_LF; 227 } 228 } 229 230 function code($text, $language = NULL){ 231 if ($this->capture){ 232 $this->doc .= DOKU_LF.$text; 233 if (strlen($this->doc) > 250) $this->capture = false; 234 else $this->doc .= DOKU_LF; 235 } 236 } 237 238 function acronym($acronym){ 239 if ($this->capture) $this->doc .= $acronym; 240 } 241 242 function smiley($smiley){ 243 if ($this->capture) $this->doc .= $smiley; 244 } 245 246 function entity($entity){ 247 if ($this->capture) $this->doc .= $entity; 248 } 249 250 function multiplyentity($x, $y){ 251 if ($this->capture) $this->doc .= $x.'×'.$y; 252 } 253 254 function singlequoteopening(){ 255 global $lang; 256 if ($this->capture) $this->doc .= $lang['singlequoteopening']; 257 } 258 259 function singlequoteclosing(){ 260 global $lang; 261 if ($this->capture) $this->doc .= $lang['singlequoteclosing']; 262 } 263 264 function apostrophe() { 265 global $lang; 266 if ($this->capture) $this->doc .= $lang['apostrophe']; 267 } 268 269 function doublequoteopening(){ 270 global $lang; 271 if ($this->capture) $this->doc .= $lang['doublequoteopening']; 272 } 273 274 function doublequoteclosing(){ 275 global $lang; 276 if ($this->capture) $this->doc .= $lang['doublequoteclosing']; 277 } 278 279 function camelcaselink($link) { 280 $this->internallink($link, $link); 281 } 282 283 function locallink($hash, $name = NULL){} 284 285 /** 286 * keep track of internal links in $this->meta['relation']['references'] 287 */ 288 function internallink($id, $name = NULL){ 289 global $ID; 290 291 $default = $this->_simpleTitle($id); 292 293 // first resolve and clean up the $id 294 resolve_pageid(getNS($ID), $id, $exists); 295 list($page, $hash) = split('#', $id, 2); 296 297 // set metadata 298 $this->meta['relation']['references'][$page] = $exists; 299 // $data = array('relation' => array('isreferencedby' => array($ID => true))); 300 // p_set_metadata($id, $data); 301 302 // add link title to summary 303 if ($this->capture){ 304 $name = $this->_getLinkTitle($name, $default, $id); 305 $this->doc .= $name; 306 } 307 } 308 309 function externallink($url, $name = NULL){ 310 if ($this->capture){ 311 if ($name) $this->doc .= $name; 312 else $this->doc .= '<'.$url.'>'; 313 } 314 } 315 316 function interwikilink($match, $name = NULL, $wikiName, $wikiUri){ 317 if ($this->capture){ 318 list($wikiUri, $hash) = explode('#', $wikiUri, 2); 319 $name = $this->_getLinkTitle($name, $wikiName.'>'.$wikiUri); 320 $this->doc .= $name; 321 } 322 } 323 324 function windowssharelink($url, $name = NULL){ 325 if ($this->capture){ 326 if ($name) $this->doc .= $name; 327 else $this->doc .= '<'.$url.'>'; 328 } 329 } 330 331 function emaillink($address, $name = NULL){ 332 if ($this->capture){ 333 if ($name) $this->doc .= $name; 334 else $this->doc .= '<'.$address.'>'; 335 } 336 } 337 338 function internalmedia($src, $title=NULL, $align=NULL, $width=NULL, 339 $height=NULL, $cache=NULL, $linking=NULL){ 340 if ($this->capture && $title) $this->doc .= '['.$title.']'; 341 } 342 343 function externalmedia($src, $title=NULL, $align=NULL, $width=NULL, 344 $height=NULL, $cache=NULL, $linking=NULL){ 345 if ($this->capture && $title) $this->doc .= '['.$title.']'; 346 } 347 348 function rss($url,$params) { 349 $this->meta['relation']['haspart'][$url] = true; 350 351 $this->meta['date']['valid']['age'] = 352 isset($this->meta['date']['valid']['age']) ? 353 min($this->meta['date']['valid']['age'],$params['refresh']) : 354 $params['refresh']; 355 } 356 357 function table_open($maxcols = NULL, $numrows = NULL){} 358 function table_close(){} 359 360 function tablerow_open(){} 361 function tablerow_close(){} 362 363 function tableheader_open($colspan = 1, $align = NULL){} 364 function tableheader_close(){} 365 366 function tablecell_open($colspan = 1, $align = NULL){} 367 function tablecell_close(){} 368 369 //---------------------------------------------------------- 370 // Utils 371 372 /** 373 * Removes any Namespace from the given name but keeps 374 * casing and special chars 375 * 376 * @author Andreas Gohr <andi@splitbrain.org> 377 */ 378 function _simpleTitle($name){ 379 global $conf; 380 381 if(is_array($name)) return ''; 382 383 if($conf['useslash']){ 384 $nssep = '[:;/]'; 385 }else{ 386 $nssep = '[:;]'; 387 } 388 $name = preg_replace('!.*'.$nssep.'!','',$name); 389 //if there is a hash we use the anchor name only 390 $name = preg_replace('!.*#!','',$name); 391 return $name; 392 } 393 394 /** 395 * Creates a linkid from a headline 396 * 397 * @param string $title The headline title 398 * @param boolean $create Create a new unique ID? 399 * @author Andreas Gohr <andi@splitbrain.org> 400 */ 401 function _headerToLink($title, $create=false) { 402 $title = str_replace(':','',cleanID($title)); 403 $title = ltrim($title,'0123456789._-'); 404 if(empty($title)) $title='section'; 405 406 if($create){ 407 // make sure tiles are unique 408 $num = ''; 409 while(in_array($title.$num,$this->headers)){ 410 ($num) ? $num++ : $num = 1; 411 } 412 $title = $title.$num; 413 $this->headers[] = $title; 414 } 415 416 return $title; 417 } 418 419 /** 420 * Construct a title and handle images in titles 421 * 422 * @author Harry Fuecks <hfuecks@gmail.com> 423 */ 424 function _getLinkTitle($title, $default, $id=NULL) { 425 global $conf; 426 427 $isImage = false; 428 if (is_null($title)){ 429 if (useHeading('content') && $id){ 430 $heading = p_get_first_heading($id,false); 431 if ($heading) return $heading; 432 } 433 return $default; 434 } else if (is_string($title)){ 435 return $title; 436 } else if (is_array($title)){ 437 return '['.$title.']'; 438 } 439 } 440 441} 442 443//Setup VIM: ex: et ts=4 enc=utf-8 : 444