[ 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 inline PHP code
 394       *
 395       * If $conf['phpok'] is true this should evaluate the given code and append the result
 396       * to $doc
 397       *
 398       * @param string $text The PHP code
 399       */
 400      public function php($text) {
 401      }
 402  
 403      /**
 404       * Output block level PHP code
 405       *
 406       * If $conf['phpok'] is true this should evaluate the given code and append the result
 407       * to $doc
 408       *
 409       * @param string $text The PHP code
 410       */
 411      public function phpblock($text) {
 412      }
 413  
 414      /**
 415       * Output raw inline HTML
 416       *
 417       * If $conf['htmlok'] is true this should add the code as is to $doc
 418       *
 419       * @param string $text The HTML
 420       */
 421      public function html($text) {
 422      }
 423  
 424      /**
 425       * Output raw block-level HTML
 426       *
 427       * If $conf['htmlok'] is true this should add the code as is to $doc
 428       *
 429       * @param string $text The HTML
 430       */
 431      public function htmlblock($text) {
 432      }
 433  
 434      /**
 435       * Output preformatted text
 436       *
 437       * @param string $text
 438       */
 439      public function preformatted($text) {
 440      }
 441  
 442      /**
 443       * Start a block quote
 444       */
 445      public function quote_open() {
 446      }
 447  
 448      /**
 449       * Stop a block quote
 450       */
 451      public function quote_close() {
 452      }
 453  
 454      /**
 455       * Display text as file content, optionally syntax highlighted
 456       *
 457       * @param string $text text to show
 458       * @param string $lang programming language to use for syntax highlighting
 459       * @param string $file file path label
 460       */
 461      public function file($text, $lang = null, $file = null) {
 462      }
 463  
 464      /**
 465       * Display text as code content, optionally syntax highlighted
 466       *
 467       * @param string $text text to show
 468       * @param string $lang programming language to use for syntax highlighting
 469       * @param string $file file path label
 470       */
 471      public function code($text, $lang = null, $file = null) {
 472      }
 473  
 474      /**
 475       * Format an acronym
 476       *
 477       * Uses $this->acronyms
 478       *
 479       * @param string $acronym
 480       */
 481      public function acronym($acronym) {
 482      }
 483  
 484      /**
 485       * Format a smiley
 486       *
 487       * Uses $this->smiley
 488       *
 489       * @param string $smiley
 490       */
 491      public function smiley($smiley) {
 492      }
 493  
 494      /**
 495       * Format an entity
 496       *
 497       * Entities are basically small text replacements
 498       *
 499       * Uses $this->entities
 500       *
 501       * @param string $entity
 502       */
 503      public function entity($entity) {
 504      }
 505  
 506      /**
 507       * Typographically format a multiply sign
 508       *
 509       * Example: ($x=640, $y=480) should result in "640×480"
 510       *
 511       * @param string|int $x first value
 512       * @param string|int $y second value
 513       */
 514      public function multiplyentity($x, $y) {
 515      }
 516  
 517      /**
 518       * Render an opening single quote char (language specific)
 519       */
 520      public function singlequoteopening() {
 521      }
 522  
 523      /**
 524       * Render a closing single quote char (language specific)
 525       */
 526      public function singlequoteclosing() {
 527      }
 528  
 529      /**
 530       * Render an apostrophe char (language specific)
 531       */
 532      public function apostrophe() {
 533      }
 534  
 535      /**
 536       * Render an opening double quote char (language specific)
 537       */
 538      public function doublequoteopening() {
 539      }
 540  
 541      /**
 542       * Render an closinging double quote char (language specific)
 543       */
 544      public function doublequoteclosing() {
 545      }
 546  
 547      /**
 548       * Render a CamelCase link
 549       *
 550       * @param string $link The link name
 551       * @see http://en.wikipedia.org/wiki/CamelCase
 552       */
 553      public function camelcaselink($link) {
 554      }
 555  
 556      /**
 557       * Render a page local link
 558       *
 559       * @param string $hash hash link identifier
 560       * @param string $name name for the link
 561       */
 562      public function locallink($hash, $name = null) {
 563      }
 564  
 565      /**
 566       * Render a wiki internal link
 567       *
 568       * @param string       $link  page ID to link to. eg. 'wiki:syntax'
 569       * @param string|array $title name for the link, array for media file
 570       */
 571      public function internallink($link, $title = null) {
 572      }
 573  
 574      /**
 575       * Render an external link
 576       *
 577       * @param string       $link  full URL with scheme
 578       * @param string|array $title name for the link, array for media file
 579       */
 580      public function externallink($link, $title = null) {
 581      }
 582  
 583      /**
 584       * Render the output of an RSS feed
 585       *
 586       * @param string $url    URL of the feed
 587       * @param array  $params Finetuning of the output
 588       */
 589      public function rss($url, $params) {
 590      }
 591  
 592      /**
 593       * Render an interwiki link
 594       *
 595       * You may want to use $this->_resolveInterWiki() here
 596       *
 597       * @param string       $link     original link - probably not much use
 598       * @param string|array $title    name for the link, array for media file
 599       * @param string       $wikiName indentifier (shortcut) for the remote wiki
 600       * @param string       $wikiUri  the fragment parsed from the original link
 601       */
 602      public function interwikilink($link, $title, $wikiName, $wikiUri) {
 603      }
 604  
 605      /**
 606       * Link to file on users OS
 607       *
 608       * @param string       $link  the link
 609       * @param string|array $title name for the link, array for media file
 610       */
 611      public function filelink($link, $title = null) {
 612      }
 613  
 614      /**
 615       * Link to windows share
 616       *
 617       * @param string       $link  the link
 618       * @param string|array $title name for the link, array for media file
 619       */
 620      public function windowssharelink($link, $title = null) {
 621      }
 622  
 623      /**
 624       * Render a linked E-Mail Address
 625       *
 626       * Should honor $conf['mailguard'] setting
 627       *
 628       * @param string $address Email-Address
 629       * @param string|array $name name for the link, array for media file
 630       */
 631      public function emaillink($address, $name = null) {
 632      }
 633  
 634      /**
 635       * Render an internal media file
 636       *
 637       * @param string $src     media ID
 638       * @param string $title   descriptive text
 639       * @param string $align   left|center|right
 640       * @param int    $width   width of media in pixel
 641       * @param int    $height  height of media in pixel
 642       * @param string $cache   cache|recache|nocache
 643       * @param string $linking linkonly|detail|nolink
 644       */
 645      public function internalmedia($src, $title = null, $align = null, $width = null,
 646                             $height = null, $cache = null, $linking = null) {
 647      }
 648  
 649      /**
 650       * Render an external media file
 651       *
 652       * @param string $src     full media URL
 653       * @param string $title   descriptive text
 654       * @param string $align   left|center|right
 655       * @param int    $width   width of media in pixel
 656       * @param int    $height  height of media in pixel
 657       * @param string $cache   cache|recache|nocache
 658       * @param string $linking linkonly|detail|nolink
 659       */
 660      public function externalmedia($src, $title = null, $align = null, $width = null,
 661                             $height = null, $cache = null, $linking = null) {
 662      }
 663  
 664      /**
 665       * Render a link to an internal media file
 666       *
 667       * @param string $src     media ID
 668       * @param string $title   descriptive text
 669       * @param string $align   left|center|right
 670       * @param int    $width   width of media in pixel
 671       * @param int    $height  height of media in pixel
 672       * @param string $cache   cache|recache|nocache
 673       */
 674      public function internalmedialink($src, $title = null, $align = null,
 675                                 $width = null, $height = null, $cache = null) {
 676      }
 677  
 678      /**
 679       * Render a link to an external media file
 680       *
 681       * @param string $src     media ID
 682       * @param string $title   descriptive text
 683       * @param string $align   left|center|right
 684       * @param int    $width   width of media in pixel
 685       * @param int    $height  height of media in pixel
 686       * @param string $cache   cache|recache|nocache
 687       */
 688      public function externalmedialink($src, $title = null, $align = null,
 689                                 $width = null, $height = null, $cache = null) {
 690      }
 691  
 692      /**
 693       * Start a table
 694       *
 695       * @param int $maxcols maximum number of columns
 696       * @param int $numrows NOT IMPLEMENTED
 697       * @param int $pos     byte position in the original source
 698       */
 699      public function table_open($maxcols = null, $numrows = null, $pos = null) {
 700      }
 701  
 702      /**
 703       * Close a table
 704       *
 705       * @param int $pos byte position in the original source
 706       */
 707      public function table_close($pos = null) {
 708      }
 709  
 710      /**
 711       * Open a table header
 712       */
 713      public function tablethead_open() {
 714      }
 715  
 716      /**
 717       * Close a table header
 718       */
 719      public function tablethead_close() {
 720      }
 721  
 722      /**
 723       * Open a table body
 724       */
 725      public function tabletbody_open() {
 726      }
 727  
 728      /**
 729       * Close a table body
 730       */
 731      public function tabletbody_close() {
 732      }
 733  
 734      /**
 735       * Open a table footer
 736       */
 737      public function tabletfoot_open() {
 738      }
 739  
 740      /**
 741       * Close a table footer
 742       */
 743      public function tabletfoot_close() {
 744      }
 745  
 746      /**
 747       * Open a table row
 748       */
 749      public function tablerow_open() {
 750      }
 751  
 752      /**
 753       * Close a table row
 754       */
 755      public function tablerow_close() {
 756      }
 757  
 758      /**
 759       * Open a table header cell
 760       *
 761       * @param int    $colspan
 762       * @param string $align left|center|right
 763       * @param int    $rowspan
 764       */
 765      public function tableheader_open($colspan = 1, $align = null, $rowspan = 1) {
 766      }
 767  
 768      /**
 769       * Close a table header cell
 770       */
 771      public function tableheader_close() {
 772      }
 773  
 774      /**
 775       * Open a table cell
 776       *
 777       * @param int    $colspan
 778       * @param string $align left|center|right
 779       * @param int    $rowspan
 780       */
 781      public function tablecell_open($colspan = 1, $align = null, $rowspan = 1) {
 782      }
 783  
 784      /**
 785       * Close a table cell
 786       */
 787      public function tablecell_close() {
 788      }
 789  
 790      #endregion
 791  
 792      #region util functions, you probably won't need to reimplement them
 793  
 794      /**
 795       * Creates a linkid from a headline
 796       *
 797       * @author Andreas Gohr <andi@splitbrain.org>
 798       * @param string  $title   The headline title
 799       * @param boolean $create  Create a new unique ID?
 800       * @return string
 801       */
 802      public function _headerToLink($title, $create = false) {
 803          if($create) {
 804              return sectionID($title, $this->headers);
 805          } else {
 806              $check = false;
 807              return sectionID($title, $check);
 808          }
 809      }
 810  
 811      /**
 812       * Removes any Namespace from the given name but keeps
 813       * casing and special chars
 814       *
 815       * @author Andreas Gohr <andi@splitbrain.org>
 816       *
 817       * @param string $name
 818       * @return string
 819       */
 820      protected function _simpleTitle($name) {
 821          global $conf;
 822  
 823          //if there is a hash we use the ancor name only
 824          @list($name, $hash) = explode('#', $name, 2);
 825          if($hash) return $hash;
 826  
 827          if($conf['useslash']) {
 828              $name = strtr($name, ';/', ';:');
 829          } else {
 830              $name = strtr($name, ';', ':');
 831          }
 832  
 833          return noNSorNS($name);
 834      }
 835  
 836      /**
 837       * Resolve an interwikilink
 838       *
 839       * @param string    $shortcut  identifier for the interwiki link
 840       * @param string    $reference fragment that refers the content
 841       * @param null|bool $exists    reference which returns if an internal page exists
 842       * @return string interwikilink
 843       */
 844      public function _resolveInterWiki(&$shortcut, $reference, &$exists = null) {
 845          //get interwiki URL
 846          if(isset($this->interwiki[$shortcut])) {
 847              $url = $this->interwiki[$shortcut];
 848          }elseif(isset($this->interwiki['default'])) {
 849              $shortcut = 'default';
 850              $url = $this->interwiki[$shortcut];
 851          }else{
 852              // not parsable interwiki outputs '' to make sure string manipluation works
 853              $shortcut = '';
 854              $url      = '';
 855          }
 856  
 857          //split into hash and url part
 858          $hash = strrchr($reference, '#');
 859          if($hash) {
 860              $reference = substr($reference, 0, -strlen($hash));
 861              $hash = substr($hash, 1);
 862          }
 863  
 864          //replace placeholder
 865          if(preg_match('#\{(URL|NAME|SCHEME|HOST|PORT|PATH|QUERY)\}#', $url)) {
 866              //use placeholders
 867              $url    = str_replace('{URL}', rawurlencode($reference), $url);
 868              //wiki names will be cleaned next, otherwise urlencode unsafe chars
 869              $url    = str_replace('{NAME}', ($url[0] === ':') ? $reference :
 870                                    preg_replace_callback('/[[\\\\\]^`{|}#%]/', function($match) {
 871                                      return rawurlencode($match[0]);
 872                                    }, $reference), $url);
 873              $parsed = parse_url($reference);
 874              if (empty($parsed['scheme'])) $parsed['scheme'] = '';
 875              if (empty($parsed['host'])) $parsed['host'] = '';
 876              if (empty($parsed['port'])) $parsed['port'] = 80;
 877              if (empty($parsed['path'])) $parsed['path'] = '';
 878              if (empty($parsed['query'])) $parsed['query'] = '';
 879              $url = strtr($url,[
 880                  '{SCHEME}' => $parsed['scheme'],
 881                  '{HOST}' => $parsed['host'],
 882                  '{PORT}' => $parsed['port'],
 883                  '{PATH}' => $parsed['path'],
 884                  '{QUERY}' => $parsed['query'] ,
 885              ]);
 886          } else if($url != '') {
 887              // make sure when no url is defined, we keep it null
 888              // default
 889              $url = $url.rawurlencode($reference);
 890          }
 891          //handle as wiki links
 892          if($url[0] === ':') {
 893              $urlparam = null;
 894              $id = $url;
 895              if (strpos($url, '?') !== false) {
 896                  list($id, $urlparam) = explode('?', $url, 2);
 897              }
 898              $url    = wl(cleanID($id), $urlparam);
 899              $exists = page_exists($id);
 900          }
 901          if($hash) $url .= '#'.rawurlencode($hash);
 902  
 903          return $url;
 904      }
 905  
 906      #endregion
 907  }
 908  
 909  
 910  //Setup VIM: ex: et ts=4 :