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