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 public 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 87 $step = $level - $this->lastheadlevel; 88 89 if($step > 0) { 90 $this->current_bookmark_level += 1; 91 } elseif($step < 0) { 92 $this->current_bookmark_level -= 1; 93 if($this->current_bookmark_level < 0) { 94 $this->current_bookmark_level = 0; 95 } 96 } 97 98 $this->lastheadlevel = $level; 99 100 $bookmark = '<bookmark content="' . $this->_xmlEntities($text) . '" level="' . ($this->current_bookmark_level) . '" />'; 101 } 102 103 // print header 104 $this->doc .= DOKU_LF . "<h$level>$bookmark"; 105 $this->doc .= "<a name=\"$hid\">"; 106 $this->doc .= $this->_xmlEntities($text); 107 $this->doc .= "</a>"; 108 $this->doc .= "</h$level>" . DOKU_LF; 109 } 110 111 /** 112 * Render a page local link 113 * 114 * // modified copy of parent function 115 * 116 * @param string $hash hash link identifier 117 * @param string $name name for the link 118 * @param bool $returnonly 119 * @return string|void 120 * 121 * @see Doku_Renderer_xhtml::locallink 122 */ 123 function locallink($hash, $name = null, $returnonly = false) { 124 global $ID; 125 $name = $this->_getLinkTitle($name, $hash, $isImage); 126 $hash = $this->_headerToLink($hash); 127 $title = $ID.' ↵'; 128 129 $check = false; 130 $pid = sectionID($ID, $check); 131 132 $this->doc .= '<a href="#'. $pid . '__' . $hash.'" title="'.$title.'" class="wikilink1">'; 133 $this->doc .= $name; 134 $this->doc .= '</a>'; 135 } 136 137 /** 138 * Wrap centered media in a div to center it 139 * 140 * @param string $src media ID 141 * @param string $title descriptive text 142 * @param string $align left|center|right 143 * @param int $width width of media in pixel 144 * @param int $height height of media in pixel 145 * @param string $cache cache|recache|nocache 146 * @param bool $render should the media be embedded inline or just linked 147 * @return string 148 */ 149 function _media ($src, $title=NULL, $align=NULL, $width=NULL, 150 $height=NULL, $cache=NULL, $render = true) { 151 152 $out = ''; 153 if($align == 'center'){ 154 $out .= '<div align="center" style="text-align: center">'; 155 } 156 157 $out .= parent::_media ($src, $title, $align, $width, $height, $cache, $render); 158 159 if($align == 'center'){ 160 $out .= '</div>'; 161 } 162 163 return $out; 164 } 165 166 /** 167 * hover info makes no sense in PDFs, so drop acronyms 168 * 169 * @param string $acronym 170 */ 171 function acronym($acronym) { 172 $this->doc .= $this->_xmlEntities($acronym); 173 } 174 175 /** 176 * reformat links if needed 177 * 178 * @param array $link 179 * @return string 180 */ 181 function _formatLink($link){ 182 183 // for internal links contains the title the pageid 184 if(in_array($link['title'], $this->actioninstance->getExportedPages())) { 185 list(/* $url */, $hash) = explode('#', $link['url'], 2); 186 187 $check = false; 188 $pid = sectionID($link['title'], $check); 189 $link['url'] = "#" . $pid . '__' . $hash; 190 } 191 192 193 // prefix interwiki links with interwiki icon 194 if($link['name'][0] != '<' && preg_match('/\binterwiki iw_(.\w+)\b/',$link['class'],$m)){ 195 if(file_exists(DOKU_INC.'lib/images/interwiki/'.$m[1].'.png')){ 196 $img = DOKU_BASE.'lib/images/interwiki/'.$m[1].'.png'; 197 }elseif(file_exists(DOKU_INC.'lib/images/interwiki/'.$m[1].'.gif')){ 198 $img = DOKU_BASE.'lib/images/interwiki/'.$m[1].'.gif'; 199 }else{ 200 $img = DOKU_BASE.'lib/images/interwiki.png'; 201 } 202 203 $link['name'] = '<img src="'.$img.'" width="16" height="16" style="vertical-align: center" class="'.$link['class'].'" />'.$link['name']; 204 } 205 return parent::_formatLink($link); 206 } 207 208 /** 209 * no obfuscation for email addresses 210 * 211 * @param string $address 212 * @param null $name 213 * @param bool $returnonly 214 * @return string|void 215 */ 216 function emaillink($address, $name = NULL, $returnonly = false) { 217 global $conf; 218 $old = $conf['mailguard']; 219 $conf['mailguard'] = 'none'; 220 parent::emaillink($address, $name, $returnonly); 221 $conf['mailguard'] = $old; 222 } 223 224} 225 226