[ Index ]

PHP Cross Reference of DokuWiki

title

Body

[close]

/inc/parser/ -> renderer.php (source)

   1  <?php
   2  /**
   3   * Renderer output base class
   4   *
   5   * @author Harry Fuecks <hfuecks@gmail.com>
   6   * @author Andreas Gohr <andi@splitbrain.org>
   7   */
   8  
   9  use dokuwiki\Extension\Plugin;
  10  use dokuwiki\Extension\SyntaxPlugin;
  11  
  12  /**
  13   * Allowed chars in $language for code highlighting
  14   * @see GeSHi::set_language()
  15   */
  16  define('PREG_PATTERN_VALID_LANGUAGE', '#[^a-zA-Z0-9\-_]#');
  17  
  18  /**
  19   * An empty renderer, produces no output
  20   *
  21   * Inherits from dokuwiki\Plugin\DokuWiki_Plugin for giving additional functions to render plugins
  22   *
  23   * The renderer transforms the syntax instructions created by the parser and handler into the
  24   * desired output format. For each instruction a corresponding method defined in this class will
  25   * be called. That method needs to produce the desired output for the instruction and add it to the
  26   * $doc field. When all instructions are processed, the $doc field contents will be cached by
  27   * DokuWiki and sent to the user.
  28   */
  29  abstract class Doku_Renderer extends Plugin {
  30      /** @var array Settings, control the behavior of the renderer */
  31      public $info = array(
  32          'cache' => true, // may the rendered result cached?
  33          'toc'   => true, // render the TOC?
  34      );
  35  
  36      /** @var array contains the smiley configuration, set in p_render() */
  37      public $smileys = array();
  38      /** @var array contains the entity configuration, set in p_render() */
  39      public $entities = array();
  40      /** @var array contains the acronym configuration, set in p_render() */
  41      public $acronyms = array();
  42      /** @var array contains the interwiki configuration, set in p_render() */
  43      public $interwiki = array();
  44  
  45      /** @var array the list of headers used to create unique link ids */
  46      protected $headers = array();
  47  
  48      /**
  49       * @var string the rendered document, this will be cached after the renderer ran through
  50       */
  51      public $doc = '';
  52  
  53      /**
  54       * clean out any per-use values
  55       *
  56       * This is called before each use of the renderer object and should be used to
  57       * completely reset the state of the renderer to be reused for a new document
  58       */
  59      public function reset(){
  60          $this->headers = array();
  61          $this->doc           = '';
  62          $this->info['cache'] = true;
  63          $this->info['toc']   = true;
  64      }
  65  
  66      /**
  67       * Allow the plugin to prevent DokuWiki from reusing an instance
  68       *
  69       * Since most renderer plugins fail to implement Doku_Renderer::reset() we default
  70       * to reinstantiating the renderer here
  71       *
  72       * @return bool   false if the plugin has to be instantiated
  73       */
  74      public function isSingleton() {
  75          return false;
  76      }
  77  
  78      /**
  79       * Returns the format produced by this renderer.
  80       *
  81       * Has to be overidden by sub classes
  82       *
  83       * @return string
  84       */
  85      abstract public function getFormat();
  86  
  87      /**
  88       * Disable caching of this renderer's output
  89       */
  90      public function nocache() {
  91          $this->info['cache'] = false;
  92      }
  93  
  94      /**
  95       * Disable TOC generation for this renderer's output
  96       *
  97       * This might not be used for certain sub renderer
  98       */
  99      public function notoc() {
 100          $this->info['toc'] = false;
 101      }
 102  
 103      /**
 104       * Handle plugin rendering
 105       *
 106       * Most likely this needs NOT to be overwritten by sub classes
 107       *
 108       * @param string $name  Plugin name
 109       * @param mixed  $data  custom data set by handler
 110       * @param string $state matched state if any
 111       * @param string $match raw matched syntax
 112       */
 113      public function plugin($name, $data, $state = '', $match = '') {
 114          /** @var SyntaxPlugin $plugin */
 115          $plugin = plugin_load('syntax', $name);
 116          if($plugin != null) {
 117              $plugin->render($this->getFormat(), $this, $data);
 118          }
 119      }
 120  
 121      /**
 122       * handle nested render instructions
 123       * this method (and nest_close method) should not be overloaded in actual renderer output classes
 124       *
 125       * @param array $instructions
 126       */
 127      public function nest($instructions) {
 128          foreach($instructions as $instruction) {
 129              // execute the callback against ourself
 130              if(method_exists($this, $instruction[0])) {
 131                  call_user_func_array(array($this, $instruction[0]), $instruction[1] ? $instruction[1] : array());
 132              }
 133          }
 134      }
 135  
 136      /**
 137       * dummy closing instruction issued by Doku_Handler_Nest
 138       *
 139       * normally the syntax mode should override this instruction when instantiating Doku_Handler_Nest -
 140       * however plugins will not be able to - as their instructions require data.
 141       */
 142      public function nest_close() {
 143      }
 144  
 145      #region Syntax modes - sub classes will need to implement them to fill $doc
 146  
 147      /**
 148       * Initialize the document
 149       */
 150      public function document_start() {
 151      }
 152  
 153      /**
 154       * Finalize the document
 155       */
 156      public function document_end() {
 157      }
 158  
 159      /**
 160       * Render the Table of Contents
 161       *
 162       * @return string
 163       */
 164      public function render_TOC() {
 165          return '';
 166      }
 167  
 168      /**
 169       * Add an item to the TOC
 170       *
 171       * @param string $id       the hash link
 172       * @param string $text     the text to display
 173       * @param int    $level    the nesting level
 174       */
 175      public function toc_additem($id, $text, $level) {
 176      }
 177  
 178      /**
 179       * Render a heading
 180       *
 181       * @param string $text  the text to display
 182       * @param int    $level header level
 183       * @param int    $pos   byte position in the original source
 184       */
 185      public function header($text, $level, $pos) {
 186      }
 187  
 188      /**
 189       * Open a new section
 190       *
 191       * @param int $level section level (as determined by the previous header)
 192       */
 193      public function section_open($level) {
 194      }
 195  
 196      /**
 197       * Close the current section
 198       */
 199      public function section_close() {
 200      }
 201  
 202      /**
 203       * Render plain text data
 204       *
 205       * @param string $text
 206       */
 207      public function cdata($text) {
 208      }
 209  
 210      /**
 211       * Open a paragraph
 212       */
 213      public function p_open() {
 214      }
 215  
 216      /**
 217       * Close a paragraph
 218       */
 219      public function p_close() {
 220      }
 221  
 222      /**
 223       * Create a line break
 224       */
 225      public function linebreak() {
 226      }
 227  
 228      /**
 229       * Create a horizontal line
 230       */
 231      public function hr() {
 232      }
 233  
 234      /**
 235       * Start strong (bold) formatting
 236       */
 237      public function strong_open() {
 238      }
 239  
 240      /**
 241       * Stop strong (bold) formatting
 242       */
 243      public function strong_close() {
 244      }
 245  
 246      /**
 247       * Start emphasis (italics) formatting
 248       */
 249      public function emphasis_open() {
 250      }
 251  
 252      /**
 253       * Stop emphasis (italics) formatting
 254       */
 255      public function emphasis_close() {
 256      }
 257  
 258      /**
 259       * Start underline formatting
 260       */
 261      public function underline_open() {
 262      }
 263  
 264      /**
 265       * Stop underline formatting
 266       */
 267      public function underline_close() {
 268      }
 269  
 270      /**
 271       * Start monospace formatting
 272       */
 273      public function monospace_open() {
 274      }
 275  
 276      /**
 277       * Stop monospace formatting
 278       */
 279      public function monospace_close() {
 280      }
 281  
 282      /**
 283       * Start a subscript
 284       */
 285      public function subscript_open() {
 286      }
 287  
 288      /**
 289       * Stop a subscript
 290       */
 291      public function subscript_close() {
 292      }
 293  
 294      /**
 295       * Start a superscript
 296       */
 297      public function superscript_open() {
 298      }
 299  
 300      /**
 301       * Stop a superscript
 302       */
 303      public function superscript_close() {
 304      }
 305  
 306      /**
 307       * Start deleted (strike-through) formatting
 308       */
 309      public function deleted_open() {
 310      }
 311  
 312      /**
 313       * Stop deleted (strike-through) formatting
 314       */
 315      public function deleted_close() {
 316      }
 317  
 318      /**
 319       * Start a footnote
 320       */
 321      public function footnote_open() {
 322      }
 323  
 324      /**
 325       * Stop a footnote
 326       */
 327      public function footnote_close() {
 328      }
 329  
 330      /**
 331       * Open an unordered list
 332       */
 333      public function listu_open() {
 334      }
 335  
 336      /**
 337       * Close an unordered list
 338       */
 339      public function listu_close() {
 340      }
 341  
 342      /**
 343       * Open an ordered list
 344       */
 345      public function listo_open() {
 346      }
 347  
 348      /**
 349       * Close an ordered list
 350       */
 351      public function listo_close() {
 352      }
 353  
 354      /**
 355       * Open a list item
 356       *
 357       * @param int $level the nesting level
 358       * @param bool $node true when a node; false when a leaf
 359       */
 360      public function listitem_open($level,$node=false) {
 361      }
 362  
 363      /**
 364       * Close a list item
 365       */
 366      public function listitem_close() {
 367      }
 368  
 369      /**
 370       * Start the content of a list item
 371       */
 372      public function listcontent_open() {
 373      }
 374  
 375      /**
 376       * Stop the content of a list item
 377       */
 378      public function listcontent_close() {
 379      }
 380  
 381      /**
 382       * Output unformatted $text
 383       *
 384       * Defaults to $this->cdata()
 385       *
 386       * @param string $text
 387       */
 388      public function unformatted($text) {
 389          $this->cdata($text);
 390      }
 391  
 392      /**
 393       * Output preformatted text
 394       *
 395       * @param string $text
 396       */
 397      public function preformatted($text) {
 398      }
 399  
 400      /**
 401       * Start a block quote
 402       */
 403      public function quote_open() {
 404      }
 405  
 406      /**
 407       * Stop a block quote
 408       */
 409      public function quote_close() {
 410      }
 411  
 412      /**
 413       * Display text as file content, optionally syntax highlighted
 414       *
 415       * @param string $text text to show
 416       * @param string $lang programming language to use for syntax highlighting
 417       * @param string $file file path label
 418       */
 419      public function file($text, $lang = null, $file = null) {
 420      }
 421  
 422      /**
 423       * Display text as code content, optionally syntax highlighted
 424       *
 425       * @param string $text text to show
 426       * @param string $lang programming language to use for syntax highlighting
 427       * @param string $file file path label
 428       */
 429      public function code($text, $lang = null, $file = null) {
 430      }
 431  
 432      /**
 433       * Format an acronym
 434       *
 435       * Uses $this->acronyms
 436       *
 437       * @param string $acronym
 438       */
 439      public function acronym($acronym) {
 440      }
 441  
 442      /**
 443       * Format a smiley
 444       *
 445       * Uses $this->smiley
 446       *
 447       * @param string $smiley
 448       */
 449      public function smiley($smiley) {
 450      }
 451  
 452      /**
 453       * Format an entity
 454       *
 455       * Entities are basically small text replacements
 456       *
 457       * Uses $this->entities
 458       *
 459       * @param string $entity
 460       */
 461      public function entity($entity) {
 462      }
 463  
 464      /**
 465       * Typographically format a multiply sign
 466       *
 467       * Example: ($x=640, $y=480) should result in "640×480"
 468       *
 469       * @param string|int $x first value
 470       * @param string|int $y second value
 471       */
 472      public function multiplyentity($x, $y) {
 473      }
 474  
 475      /**
 476       * Render an opening single quote char (language specific)
 477       */
 478      public function singlequoteopening() {
 479      }
 480  
 481      /**
 482       * Render a closing single quote char (language specific)
 483       */
 484      public function singlequoteclosing() {
 485      }
 486  
 487      /**
 488       * Render an apostrophe char (language specific)
 489       */
 490      public function apostrophe() {
 491      }
 492  
 493      /**
 494       * Render an opening double quote char (language specific)
 495       */
 496      public function doublequoteopening() {
 497      }
 498  
 499      /**
 500       * Render an closinging double quote char (language specific)
 501       */
 502      public function doublequoteclosing() {
 503      }
 504  
 505      /**
 506       * Render a CamelCase link
 507       *
 508       * @param string $link The link name
 509       * @see http://en.wikipedia.org/wiki/CamelCase
 510       */
 511      public function camelcaselink($link) {
 512      }
 513  
 514      /**
 515       * Render a page local link
 516       *
 517       * @param string $hash hash link identifier
 518       * @param string $name name for the link
 519       */
 520      public function locallink($hash, $name = null) {
 521      }
 522  
 523      /**
 524       * Render a wiki internal link
 525       *
 526       * @param string       $link  page ID to link to. eg. 'wiki:syntax'
 527       * @param string|array $title name for the link, array for media file
 528       */
 529      public function internallink($link, $title = null) {
 530      }
 531  
 532      /**
 533       * Render an external link
 534       *
 535       * @param string       $link  full URL with scheme
 536       * @param string|array $title name for the link, array for media file
 537       */
 538      public function externallink($link, $title = null) {
 539      }
 540  
 541      /**
 542       * Render the output of an RSS feed
 543       *
 544       * @param string $url    URL of the feed
 545       * @param array  $params Finetuning of the output
 546       */
 547      public function rss($url, $params) {
 548      }
 549  
 550      /**
 551       * Render an interwiki link
 552       *
 553       * You may want to use $this->_resolveInterWiki() here
 554       *
 555       * @param string       $link     original link - probably not much use
 556       * @param string|array $title    name for the link, array for media file
 557       * @param string       $wikiName indentifier (shortcut) for the remote wiki
 558       * @param string       $wikiUri  the fragment parsed from the original link
 559       */
 560      public function interwikilink($link, $title, $wikiName, $wikiUri) {
 561      }
 562  
 563      /**
 564       * Link to file on users OS
 565       *
 566       * @param string       $link  the link
 567       * @param string|array $title name for the link, array for media file
 568       */
 569      public function filelink($link, $title = null) {
 570      }
 571  
 572      /**
 573       * Link to windows share
 574       *
 575       * @param string       $link  the link
 576       * @param string|array $title name for the link, array for media file
 577       */
 578      public function windowssharelink($link, $title = null) {
 579      }
 580  
 581      /**
 582       * Render a linked E-Mail Address
 583       *
 584       * Should honor $conf['mailguard'] setting
 585       *
 586       * @param string $address Email-Address
 587       * @param string|array $name name for the link, array for media file
 588       */
 589      public function emaillink($address, $name = null) {
 590      }
 591  
 592      /**
 593       * Render an internal media file
 594       *
 595       * @param string $src     media ID
 596       * @param string $title   descriptive text
 597       * @param string $align   left|center|right
 598       * @param int    $width   width of media in pixel
 599       * @param int    $height  height of media in pixel
 600       * @param string $cache   cache|recache|nocache
 601       * @param string $linking linkonly|detail|nolink
 602       */
 603      public function internalmedia($src, $title = null, $align = null, $width = null,
 604                             $height = null, $cache = null, $linking = null) {
 605      }
 606  
 607      /**
 608       * Render an external media file
 609       *
 610       * @param string $src     full media URL
 611       * @param string $title   descriptive text
 612       * @param string $align   left|center|right
 613       * @param int    $width   width of media in pixel
 614       * @param int    $height  height of media in pixel
 615       * @param string $cache   cache|recache|nocache
 616       * @param string $linking linkonly|detail|nolink
 617       */
 618      public function externalmedia($src, $title = null, $align = null, $width = null,
 619                             $height = null, $cache = null, $linking = null) {
 620      }
 621  
 622      /**
 623       * Render a link to an internal media file
 624       *
 625       * @param string $src     media ID
 626       * @param string $title   descriptive text
 627       * @param string $align   left|center|right
 628       * @param int    $width   width of media in pixel
 629       * @param int    $height  height of media in pixel
 630       * @param string $cache   cache|recache|nocache
 631       */
 632      public function internalmedialink($src, $title = null, $align = null,
 633                                 $width = null, $height = null, $cache = null) {
 634      }
 635  
 636      /**
 637       * Render a link to an external media file
 638       *
 639       * @param string $src     media ID
 640       * @param string $title   descriptive text
 641       * @param string $align   left|center|right
 642       * @param int    $width   width of media in pixel
 643       * @param int    $height  height of media in pixel
 644       * @param string $cache   cache|recache|nocache
 645       */
 646      public function externalmedialink($src, $title = null, $align = null,
 647                                 $width = null, $height = null, $cache = null) {
 648      }
 649  
 650      /**
 651       * Start a table
 652       *
 653       * @param int $maxcols maximum number of columns
 654       * @param int $numrows NOT IMPLEMENTED
 655       * @param int $pos     byte position in the original source
 656       */
 657      public function table_open($maxcols = null, $numrows = null, $pos = null) {
 658      }
 659  
 660      /**
 661       * Close a table
 662       *
 663       * @param int $pos byte position in the original source
 664       */
 665      public function table_close($pos = null) {
 666      }
 667  
 668      /**
 669       * Open a table header
 670       */
 671      public function tablethead_open() {
 672      }
 673  
 674      /**
 675       * Close a table header
 676       */
 677      public function tablethead_close() {
 678      }
 679  
 680      /**
 681       * Open a table body
 682       */
 683      public function tabletbody_open() {
 684      }
 685  
 686      /**
 687       * Close a table body
 688       */
 689      public function tabletbody_close() {
 690      }
 691  
 692      /**
 693       * Open a table footer
 694       */
 695      public function tabletfoot_open() {
 696      }
 697  
 698      /**
 699       * Close a table footer
 700       */
 701      public function tabletfoot_close() {
 702      }
 703  
 704      /**
 705       * Open a table row
 706       */
 707      public function tablerow_open() {
 708      }
 709  
 710      /**
 711       * Close a table row
 712       */
 713      public function tablerow_close() {
 714      }
 715  
 716      /**
 717       * Open a table header cell
 718       *
 719       * @param int    $colspan
 720       * @param string $align left|center|right
 721       * @param int    $rowspan
 722       */
 723      public function tableheader_open($colspan = 1, $align = null, $rowspan = 1) {
 724      }
 725  
 726      /**
 727       * Close a table header cell
 728       */
 729      public function tableheader_close() {
 730      }
 731  
 732      /**
 733       * Open a table cell
 734       *
 735       * @param int    $colspan
 736       * @param string $align left|center|right
 737       * @param int    $rowspan
 738       */
 739      public function tablecell_open($colspan = 1, $align = null, $rowspan = 1) {
 740      }
 741  
 742      /**
 743       * Close a table cell
 744       */
 745      public function tablecell_close() {
 746      }
 747  
 748      #endregion
 749  
 750      #region util functions, you probably won't need to reimplement them
 751  
 752      /**
 753       * Creates a linkid from a headline
 754       *
 755       * @author Andreas Gohr <andi@splitbrain.org>
 756       * @param string  $title   The headline title
 757       * @param boolean $create  Create a new unique ID?
 758       * @return string
 759       */
 760      public function _headerToLink($title, $create = false) {
 761          if($create) {
 762              return sectionID($title, $this->headers);
 763          } else {
 764              $check = false;
 765              return sectionID($title, $check);
 766          }
 767      }
 768  
 769      /**
 770       * Removes any Namespace from the given name but keeps
 771       * casing and special chars
 772       *
 773       * @author Andreas Gohr <andi@splitbrain.org>
 774       *
 775       * @param string $name
 776       * @return string
 777       */
 778      public function _simpleTitle($name) {
 779          global $conf;
 780  
 781          //if there is a hash we use the ancor name only
 782          list($name, $hash) = sexplode('#', $name, 2);
 783          if($hash) return $hash;
 784  
 785          if($conf['useslash']) {
 786              $name = strtr($name, ';/', ';:');
 787          } else {
 788              $name = strtr($name, ';', ':');
 789          }
 790  
 791          return noNSorNS($name);
 792      }
 793  
 794      /**
 795       * Resolve an interwikilink
 796       *
 797       * @param string    $shortcut  identifier for the interwiki link
 798       * @param string    $reference fragment that refers the content
 799       * @param null|bool $exists    reference which returns if an internal page exists
 800       * @return string interwikilink
 801       */
 802      public function _resolveInterWiki(&$shortcut, $reference, &$exists = null) {
 803          //get interwiki URL
 804          if(isset($this->interwiki[$shortcut])) {
 805              $url = $this->interwiki[$shortcut];
 806          }elseif(isset($this->interwiki['default'])) {
 807              $shortcut = 'default';
 808              $url = $this->interwiki[$shortcut];
 809          }else{
 810              // not parsable interwiki outputs '' to make sure string manipluation works
 811              $shortcut = '';
 812              $url      = '';
 813          }
 814  
 815          //split into hash and url part
 816          $hash = strrchr($reference, '#');
 817          if($hash) {
 818              $reference = substr($reference, 0, -strlen($hash));
 819              $hash = substr($hash, 1);
 820          }
 821  
 822          //replace placeholder
 823          if(preg_match('#\{(URL|NAME|SCHEME|HOST|PORT|PATH|QUERY)\}#', $url)) {
 824              //use placeholders
 825              $url    = str_replace('{URL}', rawurlencode($reference), $url);
 826              //wiki names will be cleaned next, otherwise urlencode unsafe chars
 827              $url    = str_replace('{NAME}', ($url[0] === ':') ? $reference :
 828                                    preg_replace_callback('/[[\\\\\]^`{|}#%]/', function($match) {
 829                                      return rawurlencode($match[0]);
 830                                    }, $reference), $url);
 831              $parsed = parse_url($reference);
 832              if (empty($parsed['scheme'])) $parsed['scheme'] = '';
 833              if (empty($parsed['host'])) $parsed['host'] = '';
 834              if (empty($parsed['port'])) $parsed['port'] = 80;
 835              if (empty($parsed['path'])) $parsed['path'] = '';
 836              if (empty($parsed['query'])) $parsed['query'] = '';
 837              $url = strtr($url,[
 838                  '{SCHEME}' => $parsed['scheme'],
 839                  '{HOST}' => $parsed['host'],
 840                  '{PORT}' => $parsed['port'],
 841                  '{PATH}' => $parsed['path'],
 842                  '{QUERY}' => $parsed['query'] ,
 843              ]);
 844          } else if($url != '') {
 845              // make sure when no url is defined, we keep it null
 846              // default
 847              $url = $url.rawurlencode($reference);
 848          }
 849          //handle as wiki links
 850          if($url && $url[0] === ':') {
 851              $urlparam = null;
 852              $id = $url;
 853              if (strpos($url, '?') !== false) {
 854                  list($id, $urlparam) = sexplode('?', $url, 2, '');
 855              }
 856              $url    = wl(cleanID($id), $urlparam);
 857              $exists = page_exists($id);
 858          }
 859          if($hash) $url .= '#'.rawurlencode($hash);
 860  
 861          return $url;
 862      }
 863  
 864      #endregion
 865  }
 866  
 867  
 868  //Setup VIM: ex: et ts=4 :