1<?php 2/** 3 * Renderer output base class 4 * 5 * @author Harry Fuecks <hfuecks@gmail.com> 6 * @author Andreas Gohr <andi@splitbrain.org> 7 */ 8if(!defined('DOKU_INC')) die('meh.'); 9 10/** 11 * An empty renderer, produces no output 12 * 13 * Inherits from DokuWiki_Plugin for giving additional functions to render plugins 14 */ 15class Doku_Renderer extends DokuWiki_Plugin { 16 var $info = array( 17 'cache' => true, // may the rendered result cached? 18 'toc' => true, // render the TOC? 19 ); 20 21 var $doc = ''; 22 23 // keep some config options 24 var $acronyms = array(); 25 var $smileys = array(); 26 var $badwords = array(); 27 var $entities = array(); 28 var $interwiki = array(); 29 30 // allows renderer to be used again, clean out any per-use values 31 function reset() { 32 } 33 34 function nocache() { 35 $this->info['cache'] = false; 36 } 37 38 function notoc() { 39 $this->info['toc'] = false; 40 } 41 42 /** 43 * Returns the format produced by this renderer. 44 * 45 * Has to be overidden by decendend classes 46 */ 47 function getFormat() { 48 trigger_error('getFormat() not implemented in '.get_class($this), E_USER_WARNING); 49 } 50 51 /** 52 * Allow the plugin to prevent DokuWiki from reusing an instance 53 * 54 * @return bool false if the plugin has to be instantiated 55 */ 56 function isSingleton() { 57 return false; 58 } 59 60 /** 61 * handle plugin rendering 62 * 63 * @param string $name Plugin name 64 * @param mixed $data custom data set by handler 65 * @param string $state matched state if any 66 * @param string $match raw matched syntax 67 */ 68 function plugin($name, $data, $state = '', $match = '') { 69 $plugin = plugin_load('syntax', $name); 70 if($plugin != null) { 71 $plugin->render($this->getFormat(), $this, $data); 72 } 73 } 74 75 /** 76 * handle nested render instructions 77 * this method (and nest_close method) should not be overloaded in actual renderer output classes 78 */ 79 function nest($instructions) { 80 81 foreach($instructions as $instruction) { 82 // execute the callback against ourself 83 if(method_exists($this, $instruction[0])) { 84 call_user_func_array(array($this, $instruction[0]), $instruction[1] ? $instruction[1] : array()); 85 } 86 } 87 } 88 89 // dummy closing instruction issued by Doku_Handler_Nest, normally the syntax mode should 90 // override this instruction when instantiating Doku_Handler_Nest - however plugins will not 91 // be able to - as their instructions require data. 92 function nest_close() { 93 } 94 95 function document_start() { 96 } 97 98 function document_end() { 99 } 100 101 function render_TOC() { 102 return ''; 103 } 104 105 function toc_additem($id, $text, $level) { 106 } 107 108 function header($text, $level, $pos) { 109 } 110 111 function section_open($level) { 112 } 113 114 function section_close() { 115 } 116 117 function cdata($text) { 118 } 119 120 function p_open() { 121 } 122 123 function p_close() { 124 } 125 126 function linebreak() { 127 } 128 129 function hr() { 130 } 131 132 function strong_open() { 133 } 134 135 function strong_close() { 136 } 137 138 function emphasis_open() { 139 } 140 141 function emphasis_close() { 142 } 143 144 function underline_open() { 145 } 146 147 function underline_close() { 148 } 149 150 function monospace_open() { 151 } 152 153 function monospace_close() { 154 } 155 156 function subscript_open() { 157 } 158 159 function subscript_close() { 160 } 161 162 function superscript_open() { 163 } 164 165 function superscript_close() { 166 } 167 168 function deleted_open() { 169 } 170 171 function deleted_close() { 172 } 173 174 function footnote_open() { 175 } 176 177 function footnote_close() { 178 } 179 180 function listu_open() { 181 } 182 183 function listu_close() { 184 } 185 186 function listo_open() { 187 } 188 189 function listo_close() { 190 } 191 192 function listitem_open($level) { 193 } 194 195 function listitem_close() { 196 } 197 198 function listcontent_open() { 199 } 200 201 function listcontent_close() { 202 } 203 204 function unformatted($text) { 205 } 206 207 function php($text) { 208 } 209 210 function phpblock($text) { 211 } 212 213 function html($text) { 214 } 215 216 function htmlblock($text) { 217 } 218 219 function preformatted($text) { 220 } 221 222 function quote_open() { 223 } 224 225 function quote_close() { 226 } 227 228 function file($text, $lang = null, $file = null) { 229 } 230 231 function code($text, $lang = null, $file = null) { 232 } 233 234 function acronym($acronym) { 235 } 236 237 function smiley($smiley) { 238 } 239 240 function wordblock($word) { 241 } 242 243 function entity($entity) { 244 } 245 246 // 640x480 ($x=640, $y=480) 247 function multiplyentity($x, $y) { 248 } 249 250 function singlequoteopening() { 251 } 252 253 function singlequoteclosing() { 254 } 255 256 function apostrophe() { 257 } 258 259 function doublequoteopening() { 260 } 261 262 function doublequoteclosing() { 263 } 264 265 // $link like 'SomePage' 266 function camelcaselink($link) { 267 } 268 269 function locallink($hash, $name = null) { 270 } 271 272 // $link like 'wiki:syntax', $title could be an array (media) 273 function internallink($link, $title = null) { 274 } 275 276 // $link is full URL with scheme, $title could be an array (media) 277 function externallink($link, $title = null) { 278 } 279 280 function rss($url, $params) { 281 } 282 283 // $link is the original link - probably not much use 284 // $wikiName is an indentifier for the wiki 285 // $wikiUri is the URL fragment to append to some known URL 286 function interwikilink($link, $title = null, $wikiName, $wikiUri) { 287 } 288 289 // Link to file on users OS, $title could be an array (media) 290 function filelink($link, $title = null) { 291 } 292 293 // Link to a Windows share, , $title could be an array (media) 294 function windowssharelink($link, $title = null) { 295 } 296 297// function email($address, $title = null) {} 298 function emaillink($address, $name = null) { 299 } 300 301 function internalmedia($src, $title = null, $align = null, $width = null, 302 $height = null, $cache = null, $linking = null) { 303 } 304 305 function externalmedia($src, $title = null, $align = null, $width = null, 306 $height = null, $cache = null, $linking = null) { 307 } 308 309 function internalmedialink( 310 $src, $title = null, $align = null, $width = null, $height = null, $cache = null 311 ) { 312 } 313 314 function externalmedialink( 315 $src, $title = null, $align = null, $width = null, $height = null, $cache = null 316 ) { 317 } 318 319 function table_open($maxcols = null, $numrows = null, $pos = null) { 320 } 321 322 function table_close($pos = null) { 323 } 324 325 function tablethead_open() { 326 } 327 328 function tablethead_close() { 329 } 330 331 function tablerow_open() { 332 } 333 334 function tablerow_close() { 335 } 336 337 function tableheader_open($colspan = 1, $align = null, $rowspan = 1) { 338 } 339 340 function tableheader_close() { 341 } 342 343 function tablecell_open($colspan = 1, $align = null, $rowspan = 1) { 344 } 345 346 function tablecell_close() { 347 } 348 349 // util functions follow, you probably won't need to reimplement them 350 351 /** 352 * Removes any Namespace from the given name but keeps 353 * casing and special chars 354 * 355 * @author Andreas Gohr <andi@splitbrain.org> 356 */ 357 function _simpleTitle($name) { 358 global $conf; 359 360 //if there is a hash we use the ancor name only 361 @list($name, $hash) = explode('#', $name, 2); 362 if($hash) return $hash; 363 364 if($conf['useslash']) { 365 $name = strtr($name, ';/', ';:'); 366 } else { 367 $name = strtr($name, ';', ':'); 368 } 369 370 return noNSorNS($name); 371 } 372 373 /** 374 * Resolve an interwikilink 375 */ 376 function _resolveInterWiki(&$shortcut, $reference, &$exists = null) { 377 //get interwiki URL 378 if(isset($this->interwiki[$shortcut])) { 379 $url = $this->interwiki[$shortcut]; 380 } else { 381 // Default to Google I'm feeling lucky 382 $url = 'http://www.google.com/search?q={URL}&btnI=lucky'; 383 $shortcut = 'go'; 384 } 385 386 //split into hash and url part 387 @list($reference, $hash) = explode('#', $reference, 2); 388 389 //replace placeholder 390 if(preg_match('#\{(URL|NAME|SCHEME|HOST|PORT|PATH|QUERY)\}#', $url)) { 391 //use placeholders 392 $url = str_replace('{URL}', rawurlencode($reference), $url); 393 $url = str_replace('{NAME}', $reference, $url); 394 $parsed = parse_url($reference); 395 if(!$parsed['port']) $parsed['port'] = 80; 396 $url = str_replace('{SCHEME}', $parsed['scheme'], $url); 397 $url = str_replace('{HOST}', $parsed['host'], $url); 398 $url = str_replace('{PORT}', $parsed['port'], $url); 399 $url = str_replace('{PATH}', $parsed['path'], $url); 400 $url = str_replace('{QUERY}', $parsed['query'], $url); 401 } else { 402 //default 403 $url = $url.rawurlencode($reference); 404 } 405 //handle as wiki links 406 if($url{0} === ':') { 407 list($id, $urlparam) = explode('?', $url, 2); 408 $url = wl(cleanID($id), $urlparam); 409 $exists = page_exists($id); 410 } 411 if($hash) $url .= '#'.rawurlencode($hash); 412 413 return $url; 414 } 415} 416 417 418//Setup VIM: ex: et ts=4 : 419