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