xref: /plugin/dw2pdf/renderer.php (revision 9c76f78dd7c341811a5c79230258ffb80d528b6b)
1a876b55bSAndreas Gohr<?php
2a876b55bSAndreas Gohr/**
3a876b55bSAndreas Gohr * DokuWiki Plugin dw2pdf (Renderer Component)
4a876b55bSAndreas Gohr *
5a876b55bSAndreas Gohr * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
6a876b55bSAndreas Gohr * @author  Andreas Gohr <gohr@cosmocode.de>
7a876b55bSAndreas Gohr */
8a876b55bSAndreas Gohr
9a876b55bSAndreas Gohr// must be run within Dokuwiki
10a876b55bSAndreas Gohrif(!defined('DOKU_INC')) die();
11a876b55bSAndreas Gohr
1260e59de7SGerrit Uitslag/**
1360e59de7SGerrit Uitslag * Render xhtml suitable as input for mpdf library
1460e59de7SGerrit Uitslag */
15a876b55bSAndreas Gohrclass renderer_plugin_dw2pdf extends Doku_Renderer_xhtml {
16a876b55bSAndreas Gohr
17bb7717bcSGerrit Uitslag    private $lastHeaderLevel = -1;
18bb7717bcSGerrit Uitslag    private $originalHeaderLevel = 0;
19bb7717bcSGerrit Uitslag    private $difference = 0;
20*9c76f78dSVincent GIRARD    private $current_bookmark_level = 0;
21*9c76f78dSVincent GIRARD    private static $header_count = [];
22*9c76f78dSVincent GIRARD    private static $previous_level = 0;
23bb7717bcSGerrit Uitslag
2460e59de7SGerrit Uitslag    /**
2560e59de7SGerrit Uitslag     * Stores action instance
2660e59de7SGerrit Uitslag     *
2760e59de7SGerrit Uitslag     * @var action_plugin_dw2pdf
2860e59de7SGerrit Uitslag     */
2960e59de7SGerrit Uitslag    private $actioninstance = null;
3060e59de7SGerrit Uitslag
3160e59de7SGerrit Uitslag    /**
3260e59de7SGerrit Uitslag     * load action plugin instance
3360e59de7SGerrit Uitslag     */
3460e59de7SGerrit Uitslag    public function __construct() {
3560e59de7SGerrit Uitslag        $this->actioninstance = plugin_load('action', 'dw2pdf');
3660e59de7SGerrit Uitslag    }
3760e59de7SGerrit Uitslag
3860e59de7SGerrit Uitslag    public function document_start() {
3960e59de7SGerrit Uitslag        global $ID;
4060e59de7SGerrit Uitslag
4160e59de7SGerrit Uitslag        parent::document_start();
4260e59de7SGerrit Uitslag
4360e59de7SGerrit Uitslag        //ancher for rewritten links to included pages
4460e59de7SGerrit Uitslag        $check = false;
4560e59de7SGerrit Uitslag        $pid = sectionID($ID, $check);
4660e59de7SGerrit Uitslag
4760e59de7SGerrit Uitslag        $this->doc .= "<a name=\"{$pid}__\">";
4860e59de7SGerrit Uitslag        $this->doc .= "</a>";
49*9c76f78dSVincent GIRARD
50*9c76f78dSVincent GIRARD        $this->header_count[1] = $this->actioninstance->getCurrentBookChapter();
5160e59de7SGerrit Uitslag    }
5283bac986SAndreas Gohr
53a876b55bSAndreas Gohr    /**
54a876b55bSAndreas Gohr     * Make available as XHTML replacement renderer
55236e9da2SGerrit Uitslag     *
56236e9da2SGerrit Uitslag     * @param $format
57236e9da2SGerrit Uitslag     * @return bool
58a876b55bSAndreas Gohr     */
59a876b55bSAndreas Gohr    public function canRender($format) {
60a876b55bSAndreas Gohr        if($format == 'xhtml') return true;
61a876b55bSAndreas Gohr        return false;
62a876b55bSAndreas Gohr    }
63a876b55bSAndreas Gohr
64a876b55bSAndreas Gohr    /**
65a876b55bSAndreas Gohr     * Simplified header printing with PDF bookmarks
66236e9da2SGerrit Uitslag     *
67236e9da2SGerrit Uitslag     * @param string $text
68bb7717bcSGerrit Uitslag     * @param int $level from 1 (highest) to 6 (lowest)
69236e9da2SGerrit Uitslag     * @param int $pos
70a876b55bSAndreas Gohr     */
71130c62eeSGerrit Uitslag    public function header($text, $level, $pos) {
72a876b55bSAndreas Gohr        if(!$text) return; //skip empty headlines
7360e59de7SGerrit Uitslag        global $ID;
74a876b55bSAndreas Gohr
75244aaa51SMichael Hamann        $hid = $this->_headerToLink($text, true);
7657a1b6f9SGerrit Uitslag
7757a1b6f9SGerrit Uitslag        //only add items within global configured levels (doesn't check the pdf toc settings)
7857a1b6f9SGerrit Uitslag        $this->toc_additem($hid, $text, $level);
7957a1b6f9SGerrit Uitslag
8060e59de7SGerrit Uitslag        $check = false;
8160e59de7SGerrit Uitslag        $pid = sectionID($ID, $check);
8260e59de7SGerrit Uitslag        $hid = $pid . '__' . $hid;
83244aaa51SMichael Hamann
84*9c76f78dSVincent GIRARD
85*9c76f78dSVincent GIRARD	// retrieve numbered headings option
86*9c76f78dSVincent GIRARD        $isnumberedheadings = $this->actioninstance->getExportConfig('headernumber');
87*9c76f78dSVincent GIRARD
88*9c76f78dSVincent GIRARD        $header_prefix = "";
89*9c76f78dSVincent GIRARD	if ($isnumberedheadings) {
90*9c76f78dSVincent GIRARD		if ($level > 0) {
91*9c76f78dSVincent GIRARD        	    if ($this->previous_level > $level ) {
92*9c76f78dSVincent GIRARD	                for ($i=$level+1; $i<=$this->previous_level; $i++) {
93*9c76f78dSVincent GIRARD				$this->header_count[$i]=0;
94*9c76f78dSVincent GIRARD	                }
95*9c76f78dSVincent GIRARD	            }
96*9c76f78dSVincent GIRARD	        }
97*9c76f78dSVincent GIRARD		$this->header_count[$level]++;
98*9c76f78dSVincent GIRARD
99*9c76f78dSVincent GIRARD        	// $header_prefix = "";
100*9c76f78dSVincent GIRARD	        for ($i=1; $i<=$level; $i++) {
101*9c76f78dSVincent GIRARD	            $header_prefix .= $this->header_count[$i].".";
102*9c76f78dSVincent GIRARD	 	}
103*9c76f78dSVincent GIRARD	}
104*9c76f78dSVincent GIRARD
105a876b55bSAndreas Gohr        // add PDF bookmark
1067fa15500SAndreas Gohr        $bookmark = '';
107bb7717bcSGerrit Uitslag        $maxbookmarklevel = $this->actioninstance->getExportConfig('maxbookmarks');
108bb7717bcSGerrit Uitslag        // 0: off, 1-6: show down to this level
109bb7717bcSGerrit Uitslag        if($maxbookmarklevel && $maxbookmarklevel >= $level) {
110bb7717bcSGerrit Uitslag            $bookmarklevel = $this->calculateBookmarklevel($level);
111*9c76f78dSVincent GIRARD            $bookmark = '<bookmark content="' . $header_prefix." ". $this->_xmlEntities($text) . '" level="' . ($bookmarklevel) . '" />';
112a876b55bSAndreas Gohr        }
113a876b55bSAndreas Gohr
114a876b55bSAndreas Gohr        // print header
1157fa15500SAndreas Gohr        $this->doc .= DOKU_LF . "<h$level>$bookmark";
116*9c76f78dSVincent GIRARD        $this->doc .= $header_prefix."<a name=\"$hid\">";
117a876b55bSAndreas Gohr        $this->doc .= $this->_xmlEntities($text);
118244aaa51SMichael Hamann        $this->doc .= "</a>";
119a876b55bSAndreas Gohr        $this->doc .= "</h$level>" . DOKU_LF;
120*9c76f78dSVincent GIRARD	$this->previous_level = $level;
121a876b55bSAndreas Gohr    }
122a876b55bSAndreas Gohr
123aab792a5SAndreas Gohr    /**
124bb7717bcSGerrit Uitslag     * Bookmark levels might increase maximal +1 per level.
125bb7717bcSGerrit Uitslag     * (note: levels start at 1, bookmarklevels at 0)
126bb7717bcSGerrit Uitslag     *
127bb7717bcSGerrit Uitslag     * @param int $level 1 (highest) to 6 (lowest)
128bb7717bcSGerrit Uitslag     * @return int
129bb7717bcSGerrit Uitslag     */
130bb7717bcSGerrit Uitslag    protected function calculateBookmarklevel($level) {
131bb7717bcSGerrit Uitslag        if($this->lastHeaderLevel == -1) {
132bb7717bcSGerrit Uitslag            $this->lastHeaderLevel = $level;
133bb7717bcSGerrit Uitslag        }
134bb7717bcSGerrit Uitslag        $step = $level - $this->lastHeaderLevel;
135bb7717bcSGerrit Uitslag        if($step > 1) {
136bb7717bcSGerrit Uitslag            $this->difference = $this->difference + ($step - 1);
137bb7717bcSGerrit Uitslag        }
138bb7717bcSGerrit Uitslag        if($step < 0) {
139bb7717bcSGerrit Uitslag            $this->difference = min($this->difference, $level - $this->originalHeaderLevel);
140bb7717bcSGerrit Uitslag            $this->difference = max($this->difference, 0);
141bb7717bcSGerrit Uitslag        }
142bb7717bcSGerrit Uitslag
143bb7717bcSGerrit Uitslag        $bookmarklevel = $level - $this->difference;
144bb7717bcSGerrit Uitslag
145bb7717bcSGerrit Uitslag        if($step > 1) {
146bb7717bcSGerrit Uitslag            $this->originalHeaderLevel = $bookmarklevel;
147bb7717bcSGerrit Uitslag        }
148bb7717bcSGerrit Uitslag
149bb7717bcSGerrit Uitslag        $this->lastHeaderLevel = $level;
150bb7717bcSGerrit Uitslag        return $bookmarklevel - 1; //zero indexed
151bb7717bcSGerrit Uitslag    }
152bb7717bcSGerrit Uitslag
153bb7717bcSGerrit Uitslag    /**
15460e59de7SGerrit Uitslag     * Render a page local link
15560e59de7SGerrit Uitslag     *
156236e9da2SGerrit Uitslag     * // modified copy of parent function
157236e9da2SGerrit Uitslag     *
15860e59de7SGerrit Uitslag     * @param string $hash hash link identifier
15960e59de7SGerrit Uitslag     * @param string $name name for the link
160236e9da2SGerrit Uitslag     * @param bool $returnonly
161236e9da2SGerrit Uitslag     * @return string|void
16260e59de7SGerrit Uitslag     *
16360e59de7SGerrit Uitslag     * @see Doku_Renderer_xhtml::locallink
16460e59de7SGerrit Uitslag     */
165528811ffSAnael Mobilia    function locallink($hash, $name = null, $returnonly = false) {
16660e59de7SGerrit Uitslag        global $ID;
16760e59de7SGerrit Uitslag        $name = $this->_getLinkTitle($name, $hash, $isImage);
16860e59de7SGerrit Uitslag        $hash = $this->_headerToLink($hash);
16960e59de7SGerrit Uitslag        $title = $ID . ' ↵';
17060e59de7SGerrit Uitslag
17160e59de7SGerrit Uitslag        $check = false;
17260e59de7SGerrit Uitslag        $pid = sectionID($ID, $check);
17360e59de7SGerrit Uitslag
17460e59de7SGerrit Uitslag        $this->doc .= '<a href="#' . $pid . '__' . $hash . '" title="' . $title . '" class="wikilink1">';
17560e59de7SGerrit Uitslag        $this->doc .= $name;
17660e59de7SGerrit Uitslag        $this->doc .= '</a>';
17760e59de7SGerrit Uitslag    }
17860e59de7SGerrit Uitslag
17960e59de7SGerrit Uitslag    /**
180aab792a5SAndreas Gohr     * Wrap centered media in a div to center it
181236e9da2SGerrit Uitslag     *
182236e9da2SGerrit Uitslag     * @param string $src       media ID
183236e9da2SGerrit Uitslag     * @param string $title     descriptive text
184236e9da2SGerrit Uitslag     * @param string $align     left|center|right
185236e9da2SGerrit Uitslag     * @param int    $width     width of media in pixel
186236e9da2SGerrit Uitslag     * @param int    $height    height of media in pixel
187236e9da2SGerrit Uitslag     * @param string $cache     cache|recache|nocache
188236e9da2SGerrit Uitslag     * @param bool   $render    should the media be embedded inline or just linked
189236e9da2SGerrit Uitslag     * @return string
190aab792a5SAndreas Gohr     */
191aab792a5SAndreas Gohr    function _media($src, $title = NULL, $align = NULL, $width = NULL,
192aab792a5SAndreas Gohr                    $height = NULL, $cache = NULL, $render = true) {
193aab792a5SAndreas Gohr
194aab792a5SAndreas Gohr        $out = '';
195aab792a5SAndreas Gohr        if($align == 'center') {
196aab792a5SAndreas Gohr            $out .= '<div align="center" style="text-align: center">';
197aab792a5SAndreas Gohr        }
198aab792a5SAndreas Gohr
199aab792a5SAndreas Gohr        $out .= parent::_media($src, $title, $align, $width, $height, $cache, $render);
200aab792a5SAndreas Gohr
201aab792a5SAndreas Gohr        if($align == 'center') {
202aab792a5SAndreas Gohr            $out .= '</div>';
203aab792a5SAndreas Gohr        }
204aab792a5SAndreas Gohr
205aab792a5SAndreas Gohr        return $out;
206aab792a5SAndreas Gohr    }
207aab792a5SAndreas Gohr
208551dd41eSAndreas Gohr    /**
209551dd41eSAndreas Gohr     * hover info makes no sense in PDFs, so drop acronyms
210236e9da2SGerrit Uitslag     *
211236e9da2SGerrit Uitslag     * @param string $acronym
212551dd41eSAndreas Gohr     */
213551dd41eSAndreas Gohr    function acronym($acronym) {
214551dd41eSAndreas Gohr        $this->doc .= $this->_xmlEntities($acronym);
215551dd41eSAndreas Gohr    }
216551dd41eSAndreas Gohr
2179eb4c81fSAndreas Gohr    /**
2189eb4c81fSAndreas Gohr     * reformat links if needed
219236e9da2SGerrit Uitslag     *
220236e9da2SGerrit Uitslag     * @param array $link
221236e9da2SGerrit Uitslag     * @return string
2229eb4c81fSAndreas Gohr     */
2239eb4c81fSAndreas Gohr    function _formatLink($link) {
22460e59de7SGerrit Uitslag
22560e59de7SGerrit Uitslag        // for internal links contains the title the pageid
22660e59de7SGerrit Uitslag        if(in_array($link['title'], $this->actioninstance->getExportedPages())) {
22760e59de7SGerrit Uitslag            list(/* $url */, $hash) = explode('#', $link['url'], 2);
22860e59de7SGerrit Uitslag
22960e59de7SGerrit Uitslag            $check = false;
23060e59de7SGerrit Uitslag            $pid = sectionID($link['title'], $check);
23160e59de7SGerrit Uitslag            $link['url'] = "#" . $pid . '__' . $hash;
23260e59de7SGerrit Uitslag        }
23360e59de7SGerrit Uitslag
2349eb4c81fSAndreas Gohr        // prefix interwiki links with interwiki icon
2359eb4c81fSAndreas Gohr        if($link['name'][0] != '<' && preg_match('/\binterwiki iw_(.\w+)\b/', $link['class'], $m)) {
2369eb4c81fSAndreas Gohr            if(file_exists(DOKU_INC . 'lib/images/interwiki/' . $m[1] . '.png')) {
2379eb4c81fSAndreas Gohr                $img = DOKU_BASE . 'lib/images/interwiki/' . $m[1] . '.png';
2389eb4c81fSAndreas Gohr            } elseif(file_exists(DOKU_INC . 'lib/images/interwiki/' . $m[1] . '.gif')) {
2399eb4c81fSAndreas Gohr                $img = DOKU_BASE . 'lib/images/interwiki/' . $m[1] . '.gif';
2409eb4c81fSAndreas Gohr            } else {
2419eb4c81fSAndreas Gohr                $img = DOKU_BASE . 'lib/images/interwiki.png';
2429eb4c81fSAndreas Gohr            }
2439eb4c81fSAndreas Gohr
24447b0d67bSAndreas Gohr            $link['name'] = '<img src="' . $img . '" width="16" height="16" style="vertical-align: center" class="' . $link['class'] . '" />' . $link['name'];
2459eb4c81fSAndreas Gohr        }
2469eb4c81fSAndreas Gohr        return parent::_formatLink($link);
2479eb4c81fSAndreas Gohr    }
248ccdd3126SAndreas Gohr
249ccdd3126SAndreas Gohr    /**
250ccdd3126SAndreas Gohr     * no obfuscation for email addresses
251236e9da2SGerrit Uitslag     *
252236e9da2SGerrit Uitslag     * @param string $address
253236e9da2SGerrit Uitslag     * @param null $name
254236e9da2SGerrit Uitslag     * @param bool $returnonly
255236e9da2SGerrit Uitslag     * @return string|void
256ccdd3126SAndreas Gohr     */
2570a23c2bcSAnael Mobilia    function emaillink($address, $name = NULL, $returnonly = false) {
258ccdd3126SAndreas Gohr        global $conf;
259ccdd3126SAndreas Gohr        $old = $conf['mailguard'];
260ccdd3126SAndreas Gohr        $conf['mailguard'] = 'none';
2619e1a2ac6SAnael Mobilia        parent::emaillink($address, $name, $returnonly);
262ccdd3126SAndreas Gohr        $conf['mailguard'] = $old;
263ccdd3126SAndreas Gohr    }
264ccdd3126SAndreas Gohr
265a876b55bSAndreas Gohr}
266a876b55bSAndreas Gohr
267