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