1<?php
2/**
3 * Renderer for XHTML output
4 *
5 * @author Andreas Gohr <andi@splitbrain.org>
6 */
7// must be run within Dokuwiki
8if(!defined('DOKU_INC')) die();
9
10// we inherit from the XHTML renderer instead directly of the base renderer
11require_once DOKU_INC.'inc/parser/xhtml.php';
12
13/**
14 * The Renderer
15 */
16class renderer_plugin_nsexport_xhtml extends Doku_Renderer_xhtml {
17
18    public $_media = array();
19
20    public function _relTop(){
21        // relative URLs we need
22        global $ID;
23        $deep = substr_count($ID,':');
24        $ref  = '';
25        for($i=0; $i<$deep; $i++) $ref .= '../';
26        return $ref;
27    }
28
29    public function _localMedia($src){
30        // rewrite local media and move to zip
31        if(!preg_match('/^\w+:\/\//',$src)){
32            $this->_media[] = $src;
33
34            $ref = $this->_relTop();
35            $src = $ref.'_media/'.str_replace(':','/',$src);
36        }
37        return $src;
38    }
39
40    /**
41     * Store all referenced media in metadata
42     */
43    public function document_end(){
44        global $ID;
45        parent::document_end();
46
47        $this->_media = array_unique($this->_media);
48        p_set_metadata($ID,array('plugin_nsexport'=>$this->_media));
49    }
50
51
52    /**
53     * Rewrite all internal links to local html files
54     */
55    public function internallink($id, $name = null, $search=null, $returnonly=false, $linktype='content') {
56        global $conf;
57        global $ID;
58        // default name is based on $id as given
59        $default = $this->_simpleTitle($id);
60
61        $ref = $this->_relTop();
62
63        // now first resolve and clean up the $id
64        resolve_pageid(getNS($ID),$id,$exists);
65        $name = $this->_getLinkTitle($name, $default, $isImage, $id, $linktype);
66        if ( !$isImage ) {
67            if ( $exists ) {
68                $class='wikilink1';
69                // fixme check if this a exported page, if not skip it
70
71            } else {
72                // doesn't exist? skip it
73                $this->cdata($name);
74                return;
75            }
76        } else {
77            $class='media';
78        }
79
80        //keep hash anchor
81        list($id,$hash) = explode('#',$id,2);
82        if(!empty($hash)) $hash = $this->_headerToLink($hash);
83
84        //prepare for formating
85        $link['target'] = $conf['target']['wiki'];
86        $link['style']  = '';
87        $link['pre']    = '';
88        $link['suf']    = '';
89        // highlight link to current page
90        if ($id === $ID) {
91            $link['pre']    = '<span class="curid">';
92            $link['suf']    = '</span>';
93        }
94        $link['more']   = '';
95        $link['class']  = $class;
96        $link['url']    = $ref.str_replace(':','/',$id).'.html';
97        $link['name']   = $name;
98        $link['title']  = $id;
99
100        //keep hash
101        if($hash) $link['url'].='#'.$hash;
102
103        //output formatted
104        $this->doc .= $this->_formatLink($link);
105    }
106
107    /**
108     * Renders internal and external media
109     *
110     * @author Andreas Gohr <andi@splitbrain.org>
111     */
112    public function _media ($src, $title=null, $align=null, $width=null,
113                            $height=null, $cache=null, $render = true) {
114        $ret = '';
115        $src = $this->_localMedia($src);
116
117        list($ext,$mime,$dl) = mimetype($src);
118        if(substr($mime,0,5) === 'image'){
119            // first get the $title
120            if (!is_null($title)) {
121                $title  = $this->_xmlEntities($title);
122            }elseif($ext === 'jpg' || $ext === 'jpeg'){
123                //try to use the caption from IPTC/EXIF
124                require_once(DOKU_INC.'inc/JpegMeta.php');
125                $jpeg = new JpegMeta(mediaFN($src));
126                if($jpeg !== false) $cap = $jpeg->getTitle();
127                if($cap){
128                    $title = $this->_xmlEntities($cap);
129                }
130            }
131            if (!$render) {
132                // if the picture is not supposed to be rendered
133                // return the title of the picture
134                if (!$title) {
135                    // just show the sourcename
136                    $title = $this->_xmlEntities(basename(noNS($src)));
137                }
138                return $title;
139            }
140            //add image tag
141            $ret .= '<img src="'.$src.'"';
142            $ret .= ' class="media'.$align.'"';
143
144            // make left/right alignment for no-CSS view work (feeds)
145            if($align === 'right') $ret .= ' align="right"';
146            if($align === 'left')  $ret .= ' align="left"';
147
148            if ($title) {
149                $ret .= ' title="' . $title . '"';
150                $ret .= ' alt="'   . $title .'"';
151            }else{
152                $ret .= ' alt=""';
153            }
154
155            if ( !is_null($width) )
156                $ret .= ' width="'.$this->_xmlEntities($width).'"';
157
158            if ( !is_null($height) )
159                $ret .= ' height="'.$this->_xmlEntities($height).'"';
160
161            $ret .= ' />';
162
163        }elseif($mime === 'application/x-shockwave-flash'){
164            if (!$render) {
165                // if the flash is not supposed to be rendered
166                // return the title of the flash
167                if (!$title) {
168                    // just show the sourcename
169                    $title = basename(noNS($src));
170                }
171                return $this->_xmlEntities($title);
172            }
173
174            $att = array();
175            $att['class'] = "media$align";
176            if($align === 'right') $att['align'] = 'right';
177            if($align === 'left')  $att['align'] = 'left';
178            $ret .= html_flashobject($src,$width,$height,
179                                     array('quality' => 'high'),
180                                     null,
181                                     $att,
182                                     $this->_xmlEntities($title));
183        }elseif($title){
184            // well at least we have a title to display
185            $ret .= $this->_xmlEntities($title);
186        }else{
187            // just show the sourcename
188            $ret .= $this->_xmlEntities(basename(noNS($src)));
189        }
190
191        return $ret;
192    }
193
194    public function internalmedia ($src, $title = null, $align = null, $width = null,
195                                   $height = null, $cache = null, $linking = null, $return = false) {
196        global $ID;
197        list($src,$hash) = explode('#',$src,2);
198        resolve_mediaid(getNS($ID),$src, $exists);
199
200        $lsrc = $this->_localMedia($src);
201        $noLink = false;
202        $render = ($linking === 'linkonly') ? false : true;
203        $link = $this->_getMediaLinkConf($src, $title, $align, $width, $height, $cache, $render);
204        $link['url'] = $lsrc;
205
206        list($ext,$mime,$dl) = mimetype($src);
207        if(substr($mime,0,5) === 'image' && $render){
208        }elseif($mime === 'application/x-shockwave-flash' && $render){
209            // don't link flash movies
210            $noLink = true;
211        }else{
212            // add file icons
213            $class = preg_replace('/[^_\-a-z0-9]+/i','_',$ext);
214            $link['class'] .= ' mediafile mf_'.$class;
215        }
216
217        if($hash) $link['url'] .= '#'.$hash;
218
219        //markup non existing files
220        if (!$exists)
221          $link['class'] .= ' wikilink2';
222
223        //output formatted
224        if ($linking === 'nolink' || $noLink) $this->doc .= $link['name'];
225        else $this->doc .= $this->_formatLink($link);
226
227    }
228
229
230}
231
232