xref: /plugin/dw2pdf/renderer.php (revision 236e9da25892c6b94b7717b2c7b49243f433507e)
1<?php
2/**
3 * DokuWiki Plugin dw2pdf (Renderer Component)
4 *
5 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
6 * @author  Andreas Gohr <gohr@cosmocode.de>
7 */
8
9// must be run within Dokuwiki
10if (!defined('DOKU_INC')) die();
11
12/**
13 * Render xhtml suitable as input for mpdf library
14 */
15class renderer_plugin_dw2pdf extends Doku_Renderer_xhtml {
16
17    private $lastheadlevel = -1;
18    private $current_bookmark_level = 0;
19    /**
20     * Stores action instance
21     *
22     * @var action_plugin_dw2pdf
23     */
24    private $actioninstance = null;
25
26    /**
27     * load action plugin instance
28     */
29    public function __construct() {
30        $this->actioninstance = plugin_load('action', 'dw2pdf');
31    }
32
33    public function document_start() {
34        global $ID;
35
36        parent::document_start();
37
38        //ancher for rewritten links to included pages
39        $check = false;
40        $pid = sectionID($ID, $check);
41
42        $this->doc .= "<a name=\"{$pid}__\">";
43        $this->doc .= "</a>";
44    }
45
46    /**
47     * Make available as XHTML replacement renderer
48     *
49     * @param $format
50     * @return bool
51     */
52    public function canRender($format){
53        if($format == 'xhtml') return true;
54        return false;
55    }
56
57    /**
58     * Simplified header printing with PDF bookmarks
59     *
60     * @param string $text
61     * @param int $level
62     * @param int $pos
63     */
64    function header($text, $level, $pos) {
65        if(!$text) return; //skip empty headlines
66        global $ID;
67
68        $hid = $this->_headerToLink($text, true);
69
70        //only add items within global configured levels (doesn't check the pdf toc settings)
71        $this->toc_additem($hid, $text, $level);
72
73        $check = false;
74        $pid = sectionID($ID, $check);
75        $hid = $pid . '__' . $hid;
76
77            // add PDF bookmark
78        $bookmark = '';
79        $bmlevel = $this->actioninstance->getExportConfig('maxbookmarks');
80        if($bmlevel && $bmlevel >= $level){
81            // PDF readers choke on invalid nested levels
82
83            if ($this->lastheadlevel == -1)
84            	$this->lastheadlevel = $level;
85
86            $step = $level - $this->lastheadlevel;
87
88            if ($step > 0)
89            	$this->current_bookmark_level += 1;
90            else if ($step <0)  {
91            	$this->current_bookmark_level -= 1;
92                if ($this->current_bookmark_level < 0)
93                    $this->current_bookmark_level = 0;
94            }
95
96            $this->lastheadlevel = $level;
97
98            $bookmark = '<bookmark content="'.$this->_xmlEntities($text).'" level="'.($this->current_bookmark_level).'" />';
99        }
100
101        // print header
102        $this->doc .= DOKU_LF."<h$level>$bookmark";
103        $this->doc .= "<a name=\"$hid\">";
104        $this->doc .= $this->_xmlEntities($text);
105        $this->doc .= "</a>";
106        $this->doc .= "</h$level>".DOKU_LF;
107    }
108
109    /**
110     * Render a page local link
111     *
112     * // modified copy of parent function
113     *
114     * @param string $hash hash link identifier
115     * @param string $name name for the link
116     * @param bool $returnonly
117     * @return string|void
118     *
119     * @see Doku_Renderer_xhtml::locallink
120     */
121    function locallink($hash, $name = null, $returnonly = false) {
122        global $ID;
123        $name  = $this->_getLinkTitle($name, $hash, $isImage);
124        $hash  = $this->_headerToLink($hash);
125        $title = $ID.' ↵';
126
127        $check = false;
128        $pid = sectionID($ID, $check);
129
130        $this->doc .= '<a href="#'. $pid . '__' . $hash.'" title="'.$title.'" class="wikilink1">';
131        $this->doc .= $name;
132        $this->doc .= '</a>';
133    }
134
135    /**
136     * Wrap centered media in a div to center it
137     *
138     * @param string $src       media ID
139     * @param string $title     descriptive text
140     * @param string $align     left|center|right
141     * @param int    $width     width of media in pixel
142     * @param int    $height    height of media in pixel
143     * @param string $cache     cache|recache|nocache
144     * @param bool   $render    should the media be embedded inline or just linked
145     * @return string
146     */
147    function _media ($src, $title=NULL, $align=NULL, $width=NULL,
148                      $height=NULL, $cache=NULL, $render = true) {
149
150        $out = '';
151        if($align == 'center'){
152            $out .= '<div align="center" style="text-align: center">';
153        }
154
155        $out .= parent::_media ($src, $title, $align, $width, $height, $cache, $render);
156
157        if($align == 'center'){
158            $out .= '</div>';
159        }
160
161        return $out;
162    }
163
164    /**
165     * hover info makes no sense in PDFs, so drop acronyms
166     *
167     * @param string $acronym
168     */
169    function acronym($acronym) {
170        $this->doc .= $this->_xmlEntities($acronym);
171    }
172
173    /**
174     * reformat links if needed
175     *
176     * @param array $link
177     * @return string
178     */
179    function _formatLink($link){
180
181        // for internal links contains the title the pageid
182        if(in_array($link['title'], $this->actioninstance->getExportedPages())) {
183            list(/* $url */, $hash) = explode('#', $link['url'], 2);
184
185            $check = false;
186            $pid = sectionID($link['title'], $check);
187            $link['url'] = "#" . $pid . '__' . $hash;
188        }
189
190
191        // prefix interwiki links with interwiki icon
192        if($link['name'][0] != '<' && preg_match('/\binterwiki iw_(.\w+)\b/',$link['class'],$m)){
193            if(file_exists(DOKU_INC.'lib/images/interwiki/'.$m[1].'.png')){
194                $img = DOKU_BASE.'lib/images/interwiki/'.$m[1].'.png';
195            }elseif(file_exists(DOKU_INC.'lib/images/interwiki/'.$m[1].'.gif')){
196                $img = DOKU_BASE.'lib/images/interwiki/'.$m[1].'.gif';
197            }else{
198                $img = DOKU_BASE.'lib/images/interwiki.png';
199            }
200
201            $link['name'] = '<img src="'.$img.'" width="16" height="16" style="vertical-align: center" class="'.$link['class'].'" />'.$link['name'];
202        }
203        return parent::_formatLink($link);
204    }
205
206    /**
207     * no obfuscation for email addresses
208     *
209     * @param string $address
210     * @param null $name
211     * @param bool $returnonly
212     * @return string|void
213     */
214    function emaillink($address, $name = NULL, $returnonly = false) {
215        global $conf;
216        $old = $conf['mailguard'];
217        $conf['mailguard'] = 'none';
218        parent::emaillink($address, $name, $returnonly);
219        $conf['mailguard'] = $old;
220    }
221
222}
223
224