xref: /dokuwiki/inc/parser/xhtml.php (revision 313da78abbcffe408af09b97c101d52be18a262b)
10cecf9d5Sandi<?php
2b625487dSandi/**
3b625487dSandi * Renderer for XHTML output
4b625487dSandi *
5b625487dSandi * @author Harry Fuecks <hfuecks@gmail.com>
6b625487dSandi * @author Andreas Gohr <andi@splitbrain.org>
7b625487dSandi */
8b625487dSandi
90cecf9d5Sandiif(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/');
100cecf9d5Sandi
110cecf9d5Sandiif ( !defined('DOKU_LF') ) {
120cecf9d5Sandi    // Some whitespace to help View > Source
130cecf9d5Sandi    define ('DOKU_LF',"\n");
140cecf9d5Sandi}
150cecf9d5Sandi
160cecf9d5Sandiif ( !defined('DOKU_TAB') ) {
170cecf9d5Sandi    // Some whitespace to help View > Source
180cecf9d5Sandi    define ('DOKU_TAB',"\t");
190cecf9d5Sandi}
200cecf9d5Sandi
210e1c636eSandirequire_once DOKU_INC . 'inc/parser/renderer.php';
220e1c636eSandi
230cecf9d5Sandi/**
24b625487dSandi * The Renderer
250cecf9d5Sandi */
26ac83b9d8Sandiclass Doku_Renderer_xhtml extends Doku_Renderer {
270cecf9d5Sandi
280cecf9d5Sandi    var $doc = '';
290cecf9d5Sandi
300cecf9d5Sandi    var $headers = array();
310cecf9d5Sandi
320cecf9d5Sandi    var $footnotes = array();
330cecf9d5Sandi
340cecf9d5Sandi    var $acronyms = array();
350cecf9d5Sandi    var $smileys = array();
360cecf9d5Sandi    var $badwords = array();
370cecf9d5Sandi    var $entities = array();
380cecf9d5Sandi    var $interwiki = array();
390cecf9d5Sandi
40af587fa8Sandi    var $lastsec = 0;
41af587fa8Sandi
427764a90aSandi    var $store = '';
437764a90aSandi
447764a90aSandi
450cecf9d5Sandi    function document_start() {
460cecf9d5Sandi    }
470cecf9d5Sandi
480cecf9d5Sandi    function document_end() {
491d47afe1Sandi        // add button for last section if any and more than one
50433bef32Sandi        if($this->lastsec > 1) $this->_secedit($this->lastsec,'');
510cecf9d5Sandi
520cecf9d5Sandi        if ( count ($this->footnotes) > 0 ) {
53a2d649c4Sandi            $this->doc .= '<div class="footnotes">'.DOKU_LF;
540cecf9d5Sandi            foreach ( $this->footnotes as $footnote ) {
55a2d649c4Sandi                $this->doc .= $footnote;
560cecf9d5Sandi            }
57a2d649c4Sandi            $this->doc .= '</div>'.DOKU_LF;
580cecf9d5Sandi        }
590cecf9d5Sandi    }
600cecf9d5Sandi
610cecf9d5Sandi    function toc_open() {
62a2d649c4Sandi        $this->doc .= '<div class="toc">'.DOKU_LF;
63a2d649c4Sandi        $this->doc .= '<div class="tocheader">Table of Contents <script type="text/javascript">showTocToggle("+","-")</script></div>'.DOKU_LF;
64a2d649c4Sandi        $this->doc .= '<div id="tocinside">'.DOKU_LF;
650cecf9d5Sandi    }
660cecf9d5Sandi
670cecf9d5Sandi    function tocbranch_open($level) {
68a2d649c4Sandi        $this->doc .= '<ul class="toc">'.DOKU_LF;
690cecf9d5Sandi    }
700cecf9d5Sandi
710cecf9d5Sandi    function tocitem_open($level, $empty = FALSE) {
720cecf9d5Sandi        if ( !$empty ) {
73a2d649c4Sandi            $this->doc .= '<li class="level'.$level.'">';
740cecf9d5Sandi        } else {
75a2d649c4Sandi            $this->doc .= '<li class="clear">';
760cecf9d5Sandi        }
770cecf9d5Sandi    }
780cecf9d5Sandi
790cecf9d5Sandi    function tocelement($level, $title) {
80a2d649c4Sandi        $this->doc .= '<span class="li"><a href="#'.$this->_headerToLink($title).'" class="toc">';
81a2d649c4Sandi        $this->doc .= $this->_xmlEntities($title);
82a2d649c4Sandi        $this->doc .= '</a></span>';
830cecf9d5Sandi    }
840cecf9d5Sandi
850cecf9d5Sandi    function tocitem_close($level) {
86a2d649c4Sandi        $this->doc .= '</li>'.DOKU_LF;
870cecf9d5Sandi    }
880cecf9d5Sandi
890cecf9d5Sandi    function tocbranch_close($level) {
90a2d649c4Sandi        $this->doc .= '</ul>'.DOKU_LF;
910cecf9d5Sandi    }
920cecf9d5Sandi
930cecf9d5Sandi    function toc_close() {
94a2d649c4Sandi        $this->doc .= '</div>'.DOKU_LF.'</div>'.DOKU_LF;
950cecf9d5Sandi    }
960cecf9d5Sandi
97af587fa8Sandi    function header($text, $level, $pos) {
98af587fa8Sandi        global $conf;
99af587fa8Sandi        //handle section editing
100af587fa8Sandi        if($level <= $conf['maxseclevel']){
101af587fa8Sandi            // add button for last section if any
102433bef32Sandi            if($this->lastsec) $this->_secedit($this->lastsec,$pos-1);
103af587fa8Sandi            // remember current position
104af587fa8Sandi            $this->lastsec = $pos;
105af587fa8Sandi        }
106af587fa8Sandi
107a2d649c4Sandi        $this->doc .= DOKU_LF.'<a name="'.$this->_headerToLink($text).'"></a><h'.$level.'>';
108a2d649c4Sandi        $this->doc .= $this->_xmlEntities($text);
109a2d649c4Sandi        $this->doc .= "</h$level>".DOKU_LF;
1100cecf9d5Sandi    }
1110cecf9d5Sandi
1120cecf9d5Sandi    function section_open($level) {
113a2d649c4Sandi        $this->doc .= "<div class=\"level$level\">".DOKU_LF;
1140cecf9d5Sandi    }
1150cecf9d5Sandi
1160cecf9d5Sandi    function section_close() {
117a2d649c4Sandi        $this->doc .= DOKU_LF.'</div>'.DOKU_LF;
1180cecf9d5Sandi    }
1190cecf9d5Sandi
1200cecf9d5Sandi    function cdata($text) {
121a2d649c4Sandi        $this->doc .= $this->_xmlEntities($text);
1220cecf9d5Sandi    }
1230cecf9d5Sandi
1240cecf9d5Sandi    function p_open() {
125a2d649c4Sandi        $this->doc .= DOKU_LF.'<p>'.DOKU_LF;
1260cecf9d5Sandi    }
1270cecf9d5Sandi
1280cecf9d5Sandi    function p_close() {
129a2d649c4Sandi        $this->doc .= DOKU_LF.'</p>'.DOKU_LF;
1300cecf9d5Sandi    }
1310cecf9d5Sandi
1320cecf9d5Sandi    function linebreak() {
133a2d649c4Sandi        $this->doc .= '<br/>'.DOKU_LF;
1340cecf9d5Sandi    }
1350cecf9d5Sandi
1360cecf9d5Sandi    function hr() {
137a2d649c4Sandi        $this->doc .= '<hr noshade="noshade" size="1" />'.DOKU_LF;
1380cecf9d5Sandi    }
1390cecf9d5Sandi
1400cecf9d5Sandi    function strong_open() {
141a2d649c4Sandi        $this->doc .= '<strong>';
1420cecf9d5Sandi    }
1430cecf9d5Sandi
1440cecf9d5Sandi    function strong_close() {
145a2d649c4Sandi        $this->doc .= '</strong>';
1460cecf9d5Sandi    }
1470cecf9d5Sandi
1480cecf9d5Sandi    function emphasis_open() {
149a2d649c4Sandi        $this->doc .= '<em>';
1500cecf9d5Sandi    }
1510cecf9d5Sandi
1520cecf9d5Sandi    function emphasis_close() {
153a2d649c4Sandi        $this->doc .= '</em>';
1540cecf9d5Sandi    }
1550cecf9d5Sandi
1560cecf9d5Sandi    function underline_open() {
157a2d649c4Sandi        $this->doc .= '<u>';
1580cecf9d5Sandi    }
1590cecf9d5Sandi
1600cecf9d5Sandi    function underline_close() {
161a2d649c4Sandi        $this->doc .= '</u>';
1620cecf9d5Sandi    }
1630cecf9d5Sandi
1640cecf9d5Sandi    function monospace_open() {
165a2d649c4Sandi        $this->doc .= '<code>';
1660cecf9d5Sandi    }
1670cecf9d5Sandi
1680cecf9d5Sandi    function monospace_close() {
169a2d649c4Sandi        $this->doc .= '</code>';
1700cecf9d5Sandi    }
1710cecf9d5Sandi
1720cecf9d5Sandi    function subscript_open() {
173a2d649c4Sandi        $this->doc .= '<sub>';
1740cecf9d5Sandi    }
1750cecf9d5Sandi
1760cecf9d5Sandi    function subscript_close() {
177a2d649c4Sandi        $this->doc .= '</sub>';
1780cecf9d5Sandi    }
1790cecf9d5Sandi
1800cecf9d5Sandi    function superscript_open() {
181a2d649c4Sandi        $this->doc .= '<sup>';
1820cecf9d5Sandi    }
1830cecf9d5Sandi
1840cecf9d5Sandi    function superscript_close() {
185a2d649c4Sandi        $this->doc .= '</sup>';
1860cecf9d5Sandi    }
1870cecf9d5Sandi
1880cecf9d5Sandi    function deleted_open() {
189a2d649c4Sandi        $this->doc .= '<del>';
1900cecf9d5Sandi    }
1910cecf9d5Sandi
1920cecf9d5Sandi    function deleted_close() {
193a2d649c4Sandi        $this->doc .= '</del>';
1940cecf9d5Sandi    }
1950cecf9d5Sandi
1960cecf9d5Sandi    function footnote_open() {
197433bef32Sandi        $id = $this->_newFootnoteId();
198a2d649c4Sandi        $this->doc .= '<a href="#fn'.$id.'" name="fnt'.$id.'" class="fn_top">'.$id.')</a>';
1997764a90aSandi
2007764a90aSandi        // move current content to store and record footnote
2017764a90aSandi        $this->store = $this->doc;
2027764a90aSandi        $this->doc   = '';
2037764a90aSandi
2047764a90aSandi        $this->doc .= '<div class="fn">';
2057764a90aSandi        $this->doc .= '<a href="#fnt'.$id.'" name="fn'.$id.'" class="fn_bot">';
2067764a90aSandi        $this->doc .= $id.')</a> '.DOKU_LF;
2070cecf9d5Sandi    }
2080cecf9d5Sandi
2090cecf9d5Sandi    function footnote_close() {
2107764a90aSandi       # $contents = ob_get_contents();
2117764a90aSandi       # ob_end_clean();
2127764a90aSandi       # $id = array_pop($this->footnoteIdStack);
2130cecf9d5Sandi
2147764a90aSandi       # $contents = '<div class="fn"><a href="#fnt'.
2157764a90aSandi       #     $id.'" name="fn'.$id.'" class="fn_bot">'.
2167764a90aSandi       #         $id.')</a> ' .DOKU_LF .$contents. "\n" . '</div>' . DOKU_LF;
2177764a90aSandi       # $this->footnotes[$id] = $contents;
2187764a90aSandi
2197764a90aSandi
2207764a90aSandi        $this->doc .= '</div>' . DOKU_LF;
2217764a90aSandi
2227764a90aSandi        // put recorded footnote into the stack and restore old content
2237764a90aSandi        $this->footnotes[count($this->footnotes)] = $this->doc;
2247764a90aSandi        $this->doc = $this->store;
2257764a90aSandi        $this->store = '';
2260cecf9d5Sandi    }
2270cecf9d5Sandi
2280cecf9d5Sandi    function listu_open() {
229a2d649c4Sandi        $this->doc .= '<ul>'.DOKU_LF;
2300cecf9d5Sandi    }
2310cecf9d5Sandi
2320cecf9d5Sandi    function listu_close() {
233a2d649c4Sandi        $this->doc .= '</ul>'.DOKU_LF;
2340cecf9d5Sandi    }
2350cecf9d5Sandi
2360cecf9d5Sandi    function listo_open() {
237a2d649c4Sandi        $this->doc .= '<ol>'.DOKU_LF;
2380cecf9d5Sandi    }
2390cecf9d5Sandi
2400cecf9d5Sandi    function listo_close() {
241a2d649c4Sandi        $this->doc .= '</ol>'.DOKU_LF;
2420cecf9d5Sandi    }
2430cecf9d5Sandi
2440cecf9d5Sandi    function listitem_open($level) {
245a2d649c4Sandi        $this->doc .= '<li class="level'.$level.'">';
2460cecf9d5Sandi    }
2470cecf9d5Sandi
2480cecf9d5Sandi    function listitem_close() {
249a2d649c4Sandi        $this->doc .= '</li>'.DOKU_LF;
2500cecf9d5Sandi    }
2510cecf9d5Sandi
2520cecf9d5Sandi    function listcontent_open() {
253a2d649c4Sandi        $this->doc .= '<span class="li">';
2540cecf9d5Sandi    }
2550cecf9d5Sandi
2560cecf9d5Sandi    function listcontent_close() {
257a2d649c4Sandi        $this->doc .= '</span>'.DOKU_LF;
2580cecf9d5Sandi    }
2590cecf9d5Sandi
2600cecf9d5Sandi    function unformatted($text) {
261a2d649c4Sandi        $this->doc .= $this->_xmlEntities($text);
2620cecf9d5Sandi    }
2630cecf9d5Sandi
2640cecf9d5Sandi    /**
2650cecf9d5Sandi    */
2660cecf9d5Sandi    function php($text) {
2674de671bcSandi        global $conf;
2684de671bcSandi        if($conf['phpok']){
2694de671bcSandi            eval($text);
2704de671bcSandi        }else{
2714de671bcSandi            $this->file($text);
2724de671bcSandi        }
2730cecf9d5Sandi    }
2740cecf9d5Sandi
2750cecf9d5Sandi    /**
2760cecf9d5Sandi    */
2770cecf9d5Sandi    function html($text) {
2784de671bcSandi        global $conf;
2794de671bcSandi        if($conf['htmlok']){
280a2d649c4Sandi          $this->doc .= $text;
2814de671bcSandi        }else{
2820cecf9d5Sandi          $this->file($text);
2830cecf9d5Sandi        }
2844de671bcSandi    }
2850cecf9d5Sandi
2860cecf9d5Sandi    function preformatted($text) {
287a2d649c4Sandi        $this->doc .= '<pre class="code">' . $this->_xmlEntities($text) . '</pre>'. DOKU_LF;
2880cecf9d5Sandi    }
2890cecf9d5Sandi
2900cecf9d5Sandi    function file($text) {
291a2d649c4Sandi        $this->doc .= '<pre class="file">' . $this->_xmlEntities($text). '</pre>'. DOKU_LF;
2920cecf9d5Sandi    }
2930cecf9d5Sandi
2940cecf9d5Sandi    /**
2950cecf9d5Sandi    * @TODO Shouldn't this output <blockquote??
2960cecf9d5Sandi    */
2970cecf9d5Sandi    function quote_open() {
298a2d649c4Sandi        $this->doc .= '<div class="quote">'.DOKU_LF;
2990cecf9d5Sandi    }
3000cecf9d5Sandi
3010cecf9d5Sandi    /**
3020cecf9d5Sandi    * @TODO Shouldn't this output </blockquote>?
3030cecf9d5Sandi    */
3040cecf9d5Sandi    function quote_close() {
305a2d649c4Sandi        $this->doc .= '</div>'.DOKU_LF;
3060cecf9d5Sandi    }
3070cecf9d5Sandi
3080cecf9d5Sandi    /**
3090cecf9d5Sandi    */
3100cecf9d5Sandi    function code($text, $language = NULL) {
3114de671bcSandi        global $conf;
3120cecf9d5Sandi
3130cecf9d5Sandi        if ( is_null($language) ) {
3140cecf9d5Sandi            $this->preformatted($text);
3150cecf9d5Sandi        } else {
316*313da78aSandi            //strip leading blank line
317*313da78aSandi            $text = preg_replace('/^\s*?\n/','',$text);
318*313da78aSandi            // Handle with Geshi here
3197196b541Sandi            require_once(DOKU_INC . 'inc/geshi.php');
3207196b541Sandi            $geshi = new GeSHi($text, strtolower($language), DOKU_INC . 'inc/geshi');
321*313da78aSandi            $geshi->set_encoding('utf-8');
3220cecf9d5Sandi            $geshi->enable_classes();
3230cecf9d5Sandi            $geshi->set_header_type(GESHI_HEADER_PRE);
3240cecf9d5Sandi            $geshi->set_overall_class('code');
3254de671bcSandi            $geshi->set_link_target($conf['target']['extern']);
3260cecf9d5Sandi
3270cecf9d5Sandi            $text = $geshi->parse_code();
328a2d649c4Sandi            $this->doc .= $text;
3290cecf9d5Sandi        }
3300cecf9d5Sandi    }
3310cecf9d5Sandi
3320cecf9d5Sandi    function acronym($acronym) {
3330cecf9d5Sandi
3340cecf9d5Sandi        if ( array_key_exists($acronym, $this->acronyms) ) {
3350cecf9d5Sandi
336433bef32Sandi            $title = $this->_xmlEntities($this->acronyms[$acronym]);
3370cecf9d5Sandi
338a2d649c4Sandi            $this->doc .= '<acronym title="'.$title
339433bef32Sandi                .'">'.$this->_xmlEntities($acronym).'</acronym>';
3400cecf9d5Sandi
3410cecf9d5Sandi        } else {
342a2d649c4Sandi            $this->doc .= $this->_xmlEntities($acronym);
3430cecf9d5Sandi        }
3440cecf9d5Sandi    }
3450cecf9d5Sandi
3460cecf9d5Sandi    /**
3470cecf9d5Sandi    */
3480cecf9d5Sandi    function smiley($smiley) {
3490cecf9d5Sandi        if ( array_key_exists($smiley, $this->smileys) ) {
350433bef32Sandi            $title = $this->_xmlEntities($this->smileys[$smiley]);
351a2d649c4Sandi            $this->doc .= '<img src="'.DOKU_BASE.'smileys/'.$this->smileys[$smiley].
3520cecf9d5Sandi                '" align="middle" alt="'.
353433bef32Sandi                    $this->_xmlEntities($smiley).'" />';
3540cecf9d5Sandi        } else {
355a2d649c4Sandi            $this->doc .= $this->_xmlEntities($smiley);
3560cecf9d5Sandi        }
3570cecf9d5Sandi    }
3580cecf9d5Sandi
3590cecf9d5Sandi    /**
3604de671bcSandi    * not used
3610cecf9d5Sandi    function wordblock($word) {
3620cecf9d5Sandi        if ( array_key_exists($word, $this->badwords) ) {
363a2d649c4Sandi            $this->doc .= '** BLEEP **';
3640cecf9d5Sandi        } else {
365a2d649c4Sandi            $this->doc .= $this->_xmlEntities($word);
3660cecf9d5Sandi        }
3670cecf9d5Sandi    }
3684de671bcSandi    */
3690cecf9d5Sandi
3700cecf9d5Sandi    function entity($entity) {
3710cecf9d5Sandi        if ( array_key_exists($entity, $this->entities) ) {
372a2d649c4Sandi            $this->doc .= $this->entities[$entity];
3730cecf9d5Sandi        } else {
374a2d649c4Sandi            $this->doc .= $this->_xmlEntities($entity);
3750cecf9d5Sandi        }
3760cecf9d5Sandi    }
3770cecf9d5Sandi
3780cecf9d5Sandi    function multiplyentity($x, $y) {
379a2d649c4Sandi        $this->doc .= "$x&times;$y";
3800cecf9d5Sandi    }
3810cecf9d5Sandi
3820cecf9d5Sandi    function singlequoteopening() {
383a2d649c4Sandi        $this->doc .= "&lsquo;";
3840cecf9d5Sandi    }
3850cecf9d5Sandi
3860cecf9d5Sandi    function singlequoteclosing() {
387a2d649c4Sandi        $this->doc .= "&rsquo;";
3880cecf9d5Sandi    }
3890cecf9d5Sandi
3900cecf9d5Sandi    function doublequoteopening() {
391a2d649c4Sandi        $this->doc .= "&ldquo;";
3920cecf9d5Sandi    }
3930cecf9d5Sandi
3940cecf9d5Sandi    function doublequoteclosing() {
395a2d649c4Sandi        $this->doc .= "&rdquo;";
3960cecf9d5Sandi    }
3970cecf9d5Sandi
3980cecf9d5Sandi    /**
3990cecf9d5Sandi    */
4000cecf9d5Sandi    function camelcaselink($link) {
40111d0aa47Sandi      $this->internallink($link,$link);
4020cecf9d5Sandi    }
4030cecf9d5Sandi
404cffcc403Sandi    /**
405cffcc403Sandi     * $search and $returnonly are not for the renderer but are used
406cffcc403Sandi     * elsewhere - no need to implement them in other renderers
407cffcc403Sandi     */
408cffcc403Sandi    function internallink($id, $name = NULL, $search=NULL,$returnonly=false) {
409ba11bd29Sandi        global $conf;
41037e34a5eSandi        global $ID;
4110cecf9d5Sandi
412433bef32Sandi        $name = $this->_getLinkTitle($name, $this->_simpleTitle($id), $isImage, $id);
41337e34a5eSandi        resolve_pageid(getNS($ID),$id,$exists);
4140cecf9d5Sandi
4150e1c636eSandi        if ( !$isImage ) {
4160e1c636eSandi            if ( $exists ) {
417ba11bd29Sandi                $class='wikilink1';
4180cecf9d5Sandi            } else {
419ba11bd29Sandi                $class='wikilink2';
4200cecf9d5Sandi            }
4210cecf9d5Sandi        } else {
422ba11bd29Sandi            $class='media';
4230cecf9d5Sandi        }
4240cecf9d5Sandi
425ba11bd29Sandi        //prepare for formating
426ba11bd29Sandi        $link['target'] = $conf['target']['wiki'];
427ba11bd29Sandi        $link['style']  = '';
428ba11bd29Sandi        $link['pre']    = '';
429ba11bd29Sandi        $link['suf']    = '';
43040eb54bbSjan        // highlight link to current page
43140eb54bbSjan        if ($id == $ID) {
43292795d04Sandi            $link['pre']    = '<span class="curid">';
43392795d04Sandi            $link['suf']    = '</span>';
43440eb54bbSjan        }
435ba11bd29Sandi        $link['more']   = 'onclick="return svchk()" onkeypress="return svchk()"';
436ba11bd29Sandi        $link['class']  = $class;
437ba11bd29Sandi        $link['url']    = wl($id);
438ba11bd29Sandi        $link['name']   = $name;
439ba11bd29Sandi        $link['title']  = $id;
4400cecf9d5Sandi
441723d78dbSandi        //add search string
442723d78dbSandi        if($search){
443723d78dbSandi            ($conf['userewrite']) ? $link['url'].='?s=' : $link['url'].='&amp;s=';
444723d78dbSandi            $link['url'] .= urlencode($search);
445723d78dbSandi        }
446723d78dbSandi
447ba11bd29Sandi        //output formatted
448cffcc403Sandi        if($returnonly){
449cffcc403Sandi            return $this->_formatLink($link);
450cffcc403Sandi        }else{
451a2d649c4Sandi            $this->doc .= $this->_formatLink($link);
4520cecf9d5Sandi        }
453cffcc403Sandi    }
4540cecf9d5Sandi
455b625487dSandi    function externallink($url, $name = NULL) {
456b625487dSandi        global $conf;
4570cecf9d5Sandi
458433bef32Sandi        $name = $this->_getLinkTitle($name, $url, $isImage);
4590cecf9d5Sandi
4600cecf9d5Sandi        if ( !$isImage ) {
461b625487dSandi            $class='urlextern';
4620cecf9d5Sandi        } else {
463b625487dSandi            $class='media';
4640cecf9d5Sandi        }
4650cecf9d5Sandi
466b625487dSandi        //prepare for formating
467b625487dSandi        $link['target'] = $conf['target']['extern'];
468b625487dSandi        $link['style']  = '';
469b625487dSandi        $link['pre']    = '';
470b625487dSandi        $link['suf']    = '';
471b625487dSandi        $link['more']   = 'onclick="return svchk()" onkeypress="return svchk()"';
472b625487dSandi        $link['class']  = $class;
473b625487dSandi        $link['url']    = $url;
474b625487dSandi        $link['name']   = $name;
475433bef32Sandi        $link['title']  = $this->_xmlEntities($url);
476b625487dSandi        if($conf['relnofollow']) $link['more'] .= ' rel="nofollow"';
4770cecf9d5Sandi
478b625487dSandi        //output formatted
479a2d649c4Sandi        $this->doc .= $this->_formatLink($link);
4800cecf9d5Sandi    }
4810cecf9d5Sandi
4820cecf9d5Sandi    /**
4830cecf9d5Sandi    */
48497a3e4e3Sandi    function interwikilink($match, $name = NULL, $wikiName, $wikiUri) {
485b625487dSandi        global $conf;
4860cecf9d5Sandi
48797a3e4e3Sandi        $link = array();
48897a3e4e3Sandi        $link['target'] = $conf['target']['interwiki'];
48997a3e4e3Sandi        $link['pre']    = '';
49097a3e4e3Sandi        $link['suf']    = '';
49197a3e4e3Sandi        $link['more']   = 'onclick="return svchk()" onkeypress="return svchk()"';
492433bef32Sandi        $link['name']   = $this->_getLinkTitle($name, $wikiUri, $isImage);
4930cecf9d5Sandi
4940cecf9d5Sandi        if ( !$isImage ) {
49597a3e4e3Sandi            $link['class'] = 'interwiki';
4960cecf9d5Sandi        } else {
49797a3e4e3Sandi            $link['class'] = 'media';
4980cecf9d5Sandi        }
4990cecf9d5Sandi
50097a3e4e3Sandi        //get interwiki URL
50197a3e4e3Sandi        if ( isset($this->interwiki[$wikiName]) ) {
50297a3e4e3Sandi            $url = $this->interwiki[$wikiName];
50397a3e4e3Sandi        } else {
50497a3e4e3Sandi            // Default to Google I'm feeling lucky
50597a3e4e3Sandi            $url = 'http://www.google.com/search?q={URL}&amp;btnI=lucky';
50697a3e4e3Sandi            $wikiName = 'go';
5070cecf9d5Sandi        }
5080cecf9d5Sandi
50997a3e4e3Sandi        if(!$isImage){
51097a3e4e3Sandi            //if ico exists set additional style
51197a3e4e3Sandi            if(@file_exists(DOKU_INC.'interwiki/'.$wikiName.'.png')){
51297a3e4e3Sandi                $link['style']='background: transparent url('.DOKU_BASE.'interwiki/'.$wikiName.'.png) 0px 1px no-repeat;';
51397a3e4e3Sandi            }elseif(@file_exists(DOKU_INC.'interwiki/'.$wikiName.'.gif')){
51497a3e4e3Sandi                $link['style']='background: transparent url('.DOKU_BASE.'interwiki/'.$wikiName.'.gif) 0px 1px no-repeat;';
51597a3e4e3Sandi            }
51697a3e4e3Sandi        }
5170cecf9d5Sandi
51897a3e4e3Sandi        //do we stay at the same server? Use local target
51997a3e4e3Sandi        if( strpos($url,DOKU_URL) === 0 ){
52097a3e4e3Sandi            $link['target'] = $conf['target']['wiki'];
52197a3e4e3Sandi        }
5220cecf9d5Sandi
52397a3e4e3Sandi        //replace placeholder
52497a3e4e3Sandi        if(preg_match('#\{(URL|NAME|SCHEME|HOST|PORT|PATH|QUERY)\}#',$url)){
52597a3e4e3Sandi            //use placeholders
52697a3e4e3Sandi            $url = str_replace('{URL}',urlencode($wikiUri),$url);
52797a3e4e3Sandi            $url = str_replace('{NAME}',$wikiUri,$url);
52897a3e4e3Sandi            $parsed = parse_url($wikiUri);
52997a3e4e3Sandi            if(!$parsed['port']) $parsed['port'] = 80;
53097a3e4e3Sandi            $url = str_replace('{SCHEME}',$parsed['scheme'],$url);
53197a3e4e3Sandi            $url = str_replace('{HOST}',$parsed['host'],$url);
53297a3e4e3Sandi            $url = str_replace('{PORT}',$parsed['port'],$url);
53397a3e4e3Sandi            $url = str_replace('{PATH}',$parsed['path'],$url);
53497a3e4e3Sandi            $url = str_replace('{QUERY}',$parsed['query'],$url);
53597a3e4e3Sandi            $link['url'] = $url;
53697a3e4e3Sandi        }else{
53797a3e4e3Sandi            //default
53897a3e4e3Sandi            $link['url'] = $url.urlencode($wikiUri);
53997a3e4e3Sandi        }
54097a3e4e3Sandi
54197a3e4e3Sandi        $link['title'] = htmlspecialchars($link['url']);
54297a3e4e3Sandi
54397a3e4e3Sandi        //output formatted
544a2d649c4Sandi        $this->doc .= $this->_formatLink($link);
5450cecf9d5Sandi    }
5460cecf9d5Sandi
54771352defSandi    /*
54897a3e4e3Sandi     * @deprecated not used!!!
5490cecf9d5Sandi     * @TODO Correct the CSS class for files? (not windows)
5500cecf9d5Sandi     * @TODO Remove hard coded URL to splitbrain.org
5510cecf9d5Sandi    function filelink($link, $title = NULL) {
552a2d649c4Sandi        $this->doc .= '<a';
5530cecf9d5Sandi
554433bef32Sandi        $title = $this->_getLinkTitle($title, $link, $isImage);
5550cecf9d5Sandi
5560cecf9d5Sandi        if ( !$isImage ) {
557a2d649c4Sandi            $this->doc .= ' class="windows"';
5580cecf9d5Sandi        } else {
559a2d649c4Sandi            $this->doc .= ' class="media"';
5600cecf9d5Sandi        }
5610cecf9d5Sandi
562a2d649c4Sandi        $this->doc .= ' href="'.$this->_xmlEntities($link).'"';
5630cecf9d5Sandi
564a2d649c4Sandi        $this->doc .= ' style="background: transparent url(http://wiki.splitbrain.org/images/windows.gif) 0px 1px no-repeat;"';
5650cecf9d5Sandi
566a2d649c4Sandi        $this->doc .= ' onclick="return svchk()" onkeypress="return svchk()">';
5670cecf9d5Sandi
568a2d649c4Sandi        $this->doc .= $title;
5690cecf9d5Sandi
570a2d649c4Sandi        $this->doc .= '</a>';
5710cecf9d5Sandi    }
57271352defSandi    */
5730cecf9d5Sandi
5740cecf9d5Sandi    /**
5750cecf9d5Sandi    */
5761d47afe1Sandi    function windowssharelink($url, $name = NULL) {
5771d47afe1Sandi        global $conf;
5781d47afe1Sandi        global $lang;
5791d47afe1Sandi        //simple setup
5801d47afe1Sandi        $link['target'] = $conf['target']['windows'];
5811d47afe1Sandi        $link['pre']    = '';
5821d47afe1Sandi        $link['suf']   = '';
5831d47afe1Sandi        $link['style']  = '';
5841d47afe1Sandi        //Display error on browsers other than IE
5851d47afe1Sandi        $link['more'] = 'onclick="if(document.all == null){alert(\''.
586433bef32Sandi                        $this->_xmlEntities($lang['nosmblinks'],ENT_QUOTES).
5871d47afe1Sandi                        '\');}" onkeypress="if(document.all == null){alert(\''.
588433bef32Sandi                        $this->_xmlEntities($lang['nosmblinks'],ENT_QUOTES).'\');}"';
5890cecf9d5Sandi
590433bef32Sandi        $link['name'] = $this->_getLinkTitle($name, $url, $isImage);
5910cecf9d5Sandi        if ( !$isImage ) {
5921d47afe1Sandi            $link['class'] = 'windows';
5930cecf9d5Sandi        } else {
5941d47afe1Sandi            $link['class'] = 'media';
5950cecf9d5Sandi        }
5960cecf9d5Sandi
5970cecf9d5Sandi
598433bef32Sandi        $link['title'] = $this->_xmlEntities($url);
5991d47afe1Sandi        $url = str_replace('\\','/',$url);
6001d47afe1Sandi        $url = 'file:///'.$url;
6011d47afe1Sandi        $link['url'] = $url;
6020cecf9d5Sandi
6031d47afe1Sandi        //output formatted
604a2d649c4Sandi        $this->doc .= $this->_formatLink($link);
6050cecf9d5Sandi    }
6060cecf9d5Sandi
60771352defSandi    function emaillink($address, $name = NULL) {
60871352defSandi        global $conf;
60971352defSandi        //simple setup
61071352defSandi        $link = array();
61171352defSandi        $link['target'] = '';
61271352defSandi        $link['pre']    = '';
61371352defSandi        $link['suf']   = '';
61471352defSandi        $link['style']  = '';
61571352defSandi        $link['more']   = '';
6160cecf9d5Sandi
61771352defSandi        //we just test for image here - we need to encode the title our self
618433bef32Sandi        $this->_getLinkTitle($name, $address, $isImage);
6190cecf9d5Sandi        if ( !$isImage ) {
62071352defSandi            $link['class']='mail';
6210cecf9d5Sandi        } else {
62271352defSandi            $link['class']='media';
6230cecf9d5Sandi        }
6240cecf9d5Sandi
62571352defSandi        //shields up
62671352defSandi        if($conf['mailguard']=='visible'){
62771352defSandi            //the mail name gets some visible encoding
62871352defSandi            $address = str_replace('@',' [at] ',$address);
62971352defSandi            $address = str_replace('.',' [dot] ',$address);
63071352defSandi            $address = str_replace('-',' [dash] ',$address);
6310cecf9d5Sandi
632433bef32Sandi            $title   = $this->_xmlEntities($address);
63371352defSandi            if(empty($name)){
634433bef32Sandi                $name = $this->_xmlEntities($address);
63571352defSandi            }else{
636433bef32Sandi                $name = $this->_xmlEntities($name);
63771352defSandi            }
63871352defSandi        }elseif($conf['mailguard']=='hex'){
63971352defSandi            //encode every char to a hex entity
64071352defSandi            for ($x=0; $x < strlen($address); $x++) {
64171352defSandi                $encode .= '&#x' . bin2hex($address[$x]).';';
64271352defSandi            }
64371352defSandi            $address = $encode;
64471352defSandi            $title   = $encode;
64571352defSandi            if(empty($name)){
64671352defSandi                $name = $encode;
64771352defSandi            }else{
648433bef32Sandi                $name = $this->_xmlEntities($name);
64971352defSandi            }
65071352defSandi        }else{
65171352defSandi            //keep address as is
652433bef32Sandi            $title   = $this->_xmlEntities($address);
65371352defSandi            if(empty($name)){
654433bef32Sandi                $name = $this->_xmlEntities($address);
65571352defSandi            }else{
656433bef32Sandi                $name = $this->_xmlEntities($name);
65771352defSandi            }
65871352defSandi        }
6590cecf9d5Sandi
66071352defSandi        $link['url']   = 'mailto:'.$address;
66171352defSandi        $link['name']  = $name;
66271352defSandi        $link['title'] = $title;
6630cecf9d5Sandi
66471352defSandi        //output formatted
665a2d649c4Sandi        $this->doc .= $this->_formatLink($link);
6660cecf9d5Sandi    }
6670cecf9d5Sandi
6680cecf9d5Sandi    /**
6694826ab45Sandi     * @todo don't add link for flash
6700cecf9d5Sandi     */
6714826ab45Sandi    function internalmedia ($src, $title=NULL, $align=NULL, $width=NULL,
6724826ab45Sandi                            $height=NULL, $cache=NULL) {
6733685f775Sandi        global $conf;
67437e34a5eSandi        global $ID;
67537e34a5eSandi        resolve_mediaid(getNS($ID),$src, $exists);
6760cecf9d5Sandi
6773685f775Sandi        $link = array();
6783685f775Sandi        $link['class']  = 'media';
6793685f775Sandi        $link['style']  = '';
6803685f775Sandi        $link['pre']    = '';
6813685f775Sandi        $link['suf']    = '';
6823685f775Sandi        $link['more']   = 'onclick="return svchk()" onkeypress="return svchk()"';
6833685f775Sandi        $link['target'] = $conf['target']['media'];
6843685f775Sandi
685433bef32Sandi        $link['title']  = $this->_xmlEntities($src);
6863685f775Sandi        $link['url']    = DOKU_BASE.'fetch.php?cache='.$cache.'&amp;media='.urlencode($src);
687433bef32Sandi        $link['name']   = $this->_media ($src, $title, $align, $width, $height, $cache);
6883685f775Sandi
6893685f775Sandi
6903685f775Sandi        //output formatted
691a2d649c4Sandi        $this->doc .= $this->_formatLink($link);
6920cecf9d5Sandi    }
6930cecf9d5Sandi
6940cecf9d5Sandi    /**
6954826ab45Sandi     * @todo don't add link for flash
6960cecf9d5Sandi     */
6974826ab45Sandi    function externalmedia ($src, $title=NULL, $align=NULL, $width=NULL,
6984826ab45Sandi                            $height=NULL, $cache=NULL) {
6993685f775Sandi        global $conf;
7000cecf9d5Sandi
7013685f775Sandi        $link = array();
7023685f775Sandi        $link['class']  = 'media';
7033685f775Sandi        $link['style']  = '';
7043685f775Sandi        $link['pre']    = '';
7053685f775Sandi        $link['suf']    = '';
7063685f775Sandi        $link['more']   = 'onclick="return svchk()" onkeypress="return svchk()"';
7073685f775Sandi        $link['target'] = $conf['target']['media'];
7083685f775Sandi
709433bef32Sandi        $link['title']  = $this->_xmlEntities($src);
7103685f775Sandi        $link['url']    = DOKU_BASE.'fetch.php?cache='.$cache.'&amp;media='.urlencode($src);
711433bef32Sandi        $link['name']   = $this->_media ($src, $title, $align, $width, $height, $cache);
7123685f775Sandi
7133685f775Sandi
7143685f775Sandi        //output formatted
715a2d649c4Sandi        $this->doc .= $this->_formatLink($link);
7160cecf9d5Sandi    }
7170cecf9d5Sandi
7184826ab45Sandi    /**
719b625487dSandi     * Renders an RSS feed using magpie
720b625487dSandi     *
721b625487dSandi     * @author Andreas Gohr <andi@splitbrain.org>
722b625487dSandi     */
723b625487dSandi    function rss ($url){
724b625487dSandi        global $lang;
725b625487dSandi        define('MAGPIE_CACHE_ON', false); //we do our own caching
726b625487dSandi        define('MAGPIE_DIR', DOKU_INC.'inc/magpie/');
727b625487dSandi        define('MAGPIE_OUTPUT_ENCODING','UTF-8'); //return all feeds as UTF-8
728b625487dSandi        require_once(MAGPIE_DIR.'/rss_fetch.inc');
729b625487dSandi
730b625487dSandi        //disable warning while fetching
731b625487dSandi        $elvl = error_reporting(E_ERROR);
732b625487dSandi        $rss  = fetch_rss($url);
733b625487dSandi        error_reporting($elvl);
734b625487dSandi
735a2d649c4Sandi        $this->doc .= '<ul class="rss">';
736b625487dSandi        if($rss){
737b625487dSandi            foreach ($rss->items as $item ) {
738a2d649c4Sandi                $this->doc .= '<li>';
739b625487dSandi                $this->externallink($item['link'],$item['title']);
740a2d649c4Sandi                $this->doc .= '</li>';
741b625487dSandi            }
742b625487dSandi        }else{
743a2d649c4Sandi            $this->doc .= '<li>';
744a2d649c4Sandi            $this->doc .= '<em>'.$lang['rssfailed'].'</em>';
745b625487dSandi            $this->externallink($url);
746a2d649c4Sandi            $this->doc .= '</li>';
747b625487dSandi        }
748a2d649c4Sandi        $this->doc .= '</ul>';
749b625487dSandi    }
750b625487dSandi
751b625487dSandi    /**
7524826ab45Sandi     * Renders internal and external media
7534826ab45Sandi     *
7544826ab45Sandi     * @author Andreas Gohr <andi@splitbrain.org>
7554826ab45Sandi     * @todo   handle center align
756b625487dSandi     * @todo   move to bottom
7574826ab45Sandi     */
758433bef32Sandi    function _media ($src, $title=NULL, $align=NULL, $width=NULL,
7594826ab45Sandi                      $height=NULL, $cache=NULL) {
7604826ab45Sandi
7614826ab45Sandi        $ret = '';
7624826ab45Sandi
7634826ab45Sandi        list($ext,$mime) = mimetype($src);
7644826ab45Sandi        if(substr($mime,0,5) == 'image'){
7654826ab45Sandi            //add image tag
7664329e752Sandi            $ret .= '<img src="'.DOKU_BASE.'fetch.php?w='.$width.'&amp;h='.$height.
767b625487dSandi                    '&amp;cache='.$cache.'&amp;media='.urlencode($src).'"';
7684826ab45Sandi
7694329e752Sandi            $ret .= ' class="media'.$align.'"';
7704329e752Sandi
771506ae684Sandi            if (!is_null($title)) {
772433bef32Sandi                $ret .= ' title="'.$this->_xmlEntities($title).'"';
773506ae684Sandi                $ret .= ' alt="'.$this->_xmlEntities($title).'"';
774506ae684Sandi            }else{
775506ae684Sandi                $ret .= ' alt=""';
776506ae684Sandi            }
7774826ab45Sandi
7784826ab45Sandi            if ( !is_null($width) )
779433bef32Sandi                $ret .= ' width="'.$this->_xmlEntities($width).'"';
7804826ab45Sandi
7814826ab45Sandi            if ( !is_null($height) )
782433bef32Sandi                $ret .= ' height="'.$this->_xmlEntities($height).'"';
7834826ab45Sandi
7844826ab45Sandi            $ret .= ' />';
7854826ab45Sandi
7864826ab45Sandi        }elseif($mime == 'application/x-shockwave-flash'){
7874826ab45Sandi            //FIXME default to a higher flash version?
7884826ab45Sandi
7894826ab45Sandi            $ret .= '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"'.
7904826ab45Sandi                    ' codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=5,0,0,0"';
791433bef32Sandi            if ( !is_null($width) ) $ret .= ' width="'.$this->_xmlEntities($width).'"';
792433bef32Sandi            if ( !is_null($height) ) $ret .= ' height="'.$this->_xmlEntities($height).'"';
7934826ab45Sandi            $ret .= '>'.DOKU_LF;
7944826ab45Sandi            $ret .= '<param name="movie" value="'.DOKU_BASE.'fetch.php?media='.urlencode($src).'" />'.DOKU_LF;
7954826ab45Sandi            $ret .= '<param name="quality" value="high" />'.DOKU_LF;
7964826ab45Sandi            $ret .= '<embed src="'.DOKU_BASE.'fetch.php?media='.urlencode($src).'"'.
7974826ab45Sandi                    ' quality="high" bgcolor="#000000"';
798433bef32Sandi            if ( !is_null($width) ) $ret .= ' width="'.$this->_xmlEntities($width).'"';
799433bef32Sandi            if ( !is_null($height) ) $ret .= ' height="'.$this->_xmlEntities($height).'"';
8004826ab45Sandi            $ret .= ' type="application/x-shockwave-flash"'.
8014826ab45Sandi                    ' pluginspage="http://www.macromedia.com/shockwave/download/index.cgi'.
8024826ab45Sandi                    '?P1_Prod_Version=ShockwaveFlash"></embed>'.DOKU_LF;
8034826ab45Sandi            $ret .= '</object>'.DOKU_LF;
8044826ab45Sandi
8054826ab45Sandi        }elseif(!is_null($title)){
8064826ab45Sandi            // well at least we have a title to display
807433bef32Sandi            $ret .= $this->_xmlEntities($title);
8084826ab45Sandi        }else{
8094826ab45Sandi            // just show the source
810433bef32Sandi            $ret .= $this->_xmlEntities($src);
8110cecf9d5Sandi        }
8120cecf9d5Sandi
8134826ab45Sandi        return $ret;
8140cecf9d5Sandi    }
8150cecf9d5Sandi
8160cecf9d5Sandi    // $numrows not yet implemented
8170cecf9d5Sandi    function table_open($maxcols = NULL, $numrows = NULL){
818a2d649c4Sandi        $this->doc .= '<table class="inline">'.DOKU_LF;
8190cecf9d5Sandi    }
8200cecf9d5Sandi
8210cecf9d5Sandi    function table_close(){
822a2d649c4Sandi        $this->doc .= '</table>'.DOKU_LF.'<br />'.DOKU_LF;
8230cecf9d5Sandi    }
8240cecf9d5Sandi
8250cecf9d5Sandi    function tablerow_open(){
826a2d649c4Sandi        $this->doc .= DOKU_TAB . '<tr>' . DOKU_LF . DOKU_TAB . DOKU_TAB;
8270cecf9d5Sandi    }
8280cecf9d5Sandi
8290cecf9d5Sandi    function tablerow_close(){
830a2d649c4Sandi        $this->doc .= DOKU_LF . DOKU_TAB . '</tr>' . DOKU_LF;
8310cecf9d5Sandi    }
8320cecf9d5Sandi
8330cecf9d5Sandi    function tableheader_open($colspan = 1, $align = NULL){
834a2d649c4Sandi        $this->doc .= '<th';
8350cecf9d5Sandi        if ( !is_null($align) ) {
836a2d649c4Sandi            $this->doc .= ' class="'.$align.'align"';
8370cecf9d5Sandi        }
8380cecf9d5Sandi        if ( $colspan > 1 ) {
839a2d649c4Sandi            $this->doc .= ' colspan="'.$colspan.'"';
8400cecf9d5Sandi        }
841a2d649c4Sandi        $this->doc .= '>';
8420cecf9d5Sandi    }
8430cecf9d5Sandi
8440cecf9d5Sandi    function tableheader_close(){
845a2d649c4Sandi        $this->doc .= '</th>';
8460cecf9d5Sandi    }
8470cecf9d5Sandi
8480cecf9d5Sandi    function tablecell_open($colspan = 1, $align = NULL){
849a2d649c4Sandi        $this->doc .= '<td';
8500cecf9d5Sandi        if ( !is_null($align) ) {
851a2d649c4Sandi            $this->doc .= ' class="'.$align.'align"';
8520cecf9d5Sandi        }
8530cecf9d5Sandi        if ( $colspan > 1 ) {
854a2d649c4Sandi            $this->doc .= ' colspan="'.$colspan.'"';
8550cecf9d5Sandi        }
856a2d649c4Sandi        $this->doc .= '>';
8570cecf9d5Sandi    }
8580cecf9d5Sandi
8590cecf9d5Sandi    function tablecell_close(){
860a2d649c4Sandi        $this->doc .= '</td>';
8610cecf9d5Sandi    }
8620cecf9d5Sandi
8630cecf9d5Sandi    //----------------------------------------------------------
8640cecf9d5Sandi    // Utils
8650cecf9d5Sandi
866ba11bd29Sandi    /**
867ba11bd29Sandi     * Assembles all parts defined by the link formater below
868ba11bd29Sandi     * Returns HTML for the link
869ba11bd29Sandi     *
870ba11bd29Sandi     * @author Andreas Gohr <andi@splitbrain.org>
871ba11bd29Sandi     */
872433bef32Sandi    function _formatLink($link){
873ba11bd29Sandi        //make sure the url is XHTML compliant (skip mailto)
874ba11bd29Sandi        if(substr($link['url'],0,7) != 'mailto:'){
875ba11bd29Sandi            $link['url'] = str_replace('&','&amp;',$link['url']);
876ba11bd29Sandi            $link['url'] = str_replace('&amp;amp;','&amp;',$link['url']);
877ba11bd29Sandi        }
878ba11bd29Sandi        //remove double encodings in titles
879ba11bd29Sandi        $link['title'] = str_replace('&amp;amp;','&amp;',$link['title']);
880ba11bd29Sandi
881ba11bd29Sandi        $ret  = '';
882ba11bd29Sandi        $ret .= $link['pre'];
883ba11bd29Sandi        $ret .= '<a href="'.$link['url'].'"';
884ba11bd29Sandi        if($link['class'])  $ret .= ' class="'.$link['class'].'"';
885ba11bd29Sandi        if($link['target']) $ret .= ' target="'.$link['target'].'"';
886ba11bd29Sandi        if($link['title'])  $ret .= ' title="'.$link['title'].'"';
887ba11bd29Sandi        if($link['style'])  $ret .= ' style="'.$link['style'].'"';
888ba11bd29Sandi        if($link['more'])   $ret .= ' '.$link['more'];
889ba11bd29Sandi        $ret .= '>';
890ba11bd29Sandi        $ret .= $link['name'];
891ba11bd29Sandi        $ret .= '</a>';
892ba11bd29Sandi        $ret .= $link['suf'];
893ba11bd29Sandi        return $ret;
894ba11bd29Sandi    }
895ba11bd29Sandi
896ba11bd29Sandi    /**
897ba11bd29Sandi     * Removes any Namespace from the given name but keeps
898ba11bd29Sandi     * casing and special chars
899ba11bd29Sandi     *
900ba11bd29Sandi     * @author Andreas Gohr <andi@splitbrain.org>
901ba11bd29Sandi     */
902433bef32Sandi    function _simpleTitle($name){
903ba11bd29Sandi        global $conf;
904ba11bd29Sandi        if($conf['useslash']){
905ba11bd29Sandi            $nssep = '[:;/]';
906ba11bd29Sandi        }else{
907ba11bd29Sandi            $nssep = '[:;]';
908ba11bd29Sandi        }
909ba11bd29Sandi        return preg_replace('!.*'.$nssep.'!','',$name);
910ba11bd29Sandi    }
911ba11bd29Sandi
912ba11bd29Sandi
913433bef32Sandi    function _newFootnoteId() {
9140cecf9d5Sandi        static $id = 1;
9150cecf9d5Sandi        return $id++;
9160cecf9d5Sandi    }
9170cecf9d5Sandi
918433bef32Sandi    function _xmlEntities($string) {
9190cecf9d5Sandi        return htmlspecialchars($string);
9200cecf9d5Sandi    }
9210cecf9d5Sandi
922433bef32Sandi    function _headerToLink($title) {
923ecf0d0d0Sandi        return str_replace(':','',cleanID($title));
9240cecf9d5Sandi    }
9250cecf9d5Sandi
926af587fa8Sandi    /**
927af587fa8Sandi     * Adds code for section editing button
928af587fa8Sandi     */
929433bef32Sandi    function _secedit($f, $t){
930a2d649c4Sandi        $this->doc .= '<!-- SECTION ['.$f.'-'.$t.'] -->';
931af587fa8Sandi    }
932af587fa8Sandi
933433bef32Sandi    function _getLinkTitle($title, $default, & $isImage, $id=NULL) {
934bb0a59d4Sjan        global $conf;
935bb0a59d4Sjan
9360cecf9d5Sandi        $isImage = FALSE;
9370cecf9d5Sandi
9380cecf9d5Sandi        if ( is_null($title) ) {
939bb0a59d4Sjan            if ($conf['useheading'] && $id) {
940bb0a59d4Sjan                $heading = p_get_first_heading($id);
941bb0a59d4Sjan                if ($heading) {
942433bef32Sandi                    return $this->_xmlEntities($heading);
943bb0a59d4Sjan                }
944bb0a59d4Sjan            }
945433bef32Sandi            return $this->_xmlEntities($default);
9460cecf9d5Sandi
9470cecf9d5Sandi        } else if ( is_string($title) ) {
9480cecf9d5Sandi
949433bef32Sandi            return $this->_xmlEntities($title);
9500cecf9d5Sandi
9510cecf9d5Sandi        } else if ( is_array($title) ) {
9520cecf9d5Sandi
9530cecf9d5Sandi            $isImage = TRUE;
954433bef32Sandi            return $this->_imageTitle($title);
9550cecf9d5Sandi
9560cecf9d5Sandi        }
9570cecf9d5Sandi    }
9580cecf9d5Sandi
9590cecf9d5Sandi    /**
9600cecf9d5Sandi     * @TODO Resolve namespace on internal images
9610cecf9d5Sandi     */
962433bef32Sandi    function _imageTitle($img) {
9630cecf9d5Sandi
9644826ab45Sandi        //FIXME resolve internal links
9654826ab45Sandi
966433bef32Sandi        return $this->_media($img['src'],
9674826ab45Sandi                              $img['title'],
9684826ab45Sandi                              $img['align'],
9694826ab45Sandi                              $img['width'],
9704826ab45Sandi                              $img['height'],
9714826ab45Sandi                              $img['cache']);
9724826ab45Sandi
9734826ab45Sandi/*
9740cecf9d5Sandi        if ( $img['type'] == 'internalmedia' ) {
9750cecf9d5Sandi
9760cecf9d5Sandi            // Resolve here...
9770cecf9d5Sandi            if ( strpos($img['src'],':') ) {
9780cecf9d5Sandi                $src = explode(':',$img['src']);
9790cecf9d5Sandi                $src = $src[1];
9800cecf9d5Sandi            } else {
9810cecf9d5Sandi                $src = $img['src'];
9820cecf9d5Sandi            }
9830cecf9d5Sandi
984433bef32Sandi            $imgStr = '<img class="media" src="http://wiki.splitbrain.org/media/wiki/'.$this->_xmlEntities($src).'"';
9850cecf9d5Sandi
9860cecf9d5Sandi        } else {
9870cecf9d5Sandi
988433bef32Sandi            $imgStr = '<img class="media" src="'.$this->_xmlEntities($img['src']).'"';
9890cecf9d5Sandi
9900cecf9d5Sandi        }
9910cecf9d5Sandi
9920cecf9d5Sandi        if ( !is_null($img['title']) ) {
993433bef32Sandi            $imgStr .= ' alt="'.$this->_xmlEntities($img['title']).'"';
9940cecf9d5Sandi        } else {
9950cecf9d5Sandi            $imgStr .= ' alt=""';
9960cecf9d5Sandi        }
9970cecf9d5Sandi
9980cecf9d5Sandi        if ( !is_null($img['align']) ) {
9990cecf9d5Sandi            $imgStr .= ' align="'.$img['align'].'"';
10000cecf9d5Sandi        }
10010cecf9d5Sandi
10020cecf9d5Sandi        if ( !is_null($img['width']) ) {
1003433bef32Sandi            $imgStr .= ' width="'.$this->_xmlEntities($img['width']).'"';
10040cecf9d5Sandi        }
10050cecf9d5Sandi
10060cecf9d5Sandi        if ( !is_null($img['height']) ) {
1007433bef32Sandi            $imgStr .= ' height="'.$this->_xmlEntities($img['height']).'"';
10080cecf9d5Sandi        }
10090cecf9d5Sandi
10100cecf9d5Sandi        $imgStr .= '/>';
10110cecf9d5Sandi
10120cecf9d5Sandi        return $imgStr;
10134826ab45Sandi*/
10140cecf9d5Sandi    }
10150cecf9d5Sandi}
10160cecf9d5Sandi
10170cecf9d5Sandi/**
10180cecf9d5Sandi* Test whether there's an image to display with this interwiki link
10190cecf9d5Sandi*/
10200cecf9d5Sandifunction interwikiImgExists($name) {
10210cecf9d5Sandi
10220cecf9d5Sandi    static $exists = array();
10230cecf9d5Sandi
10240cecf9d5Sandi    if ( array_key_exists($name,$exists) ) {
10250cecf9d5Sandi        return $exists[$name];
10260cecf9d5Sandi    }
10270cecf9d5Sandi
10280cecf9d5Sandi    if( @file_exists( DOKU. 'interwiki/'.$name.'.png') ) {
10290cecf9d5Sandi        $exists[$name] = 'png';
10300cecf9d5Sandi    } else if ( @file_exists( DOKU . 'interwiki/'.$name.'.gif') ) {
10310cecf9d5Sandi        $exists[$name] = 'gif';
10320cecf9d5Sandi    } else {
10330cecf9d5Sandi        $exists[$name] = FALSE;
10340cecf9d5Sandi    }
10350cecf9d5Sandi
10360cecf9d5Sandi    return $exists[$name];
10370cecf9d5Sandi}
10380cecf9d5Sandi
10390cecf9d5Sandi/**
10400cecf9d5Sandi * For determining whether to use CSS class "wikilink1" or "wikilink2"
10410cecf9d5Sandi * @todo use configinstead of DOKU_DATA
10420e1c636eSandi * @deprecated -> resolve_pagename should be used
10430cecf9d5Sandi */
10440cecf9d5Sandifunction wikiPageExists($name) {
1045af587fa8Sandimsg("deprecated wikiPageExists called",-1);
10460cecf9d5Sandi    static $pages = array();
10470cecf9d5Sandi
10480cecf9d5Sandi    if ( array_key_exists($name,$pages) ) {
10490cecf9d5Sandi        return $pages[$name];
10500cecf9d5Sandi    }
10510cecf9d5Sandi
10520cecf9d5Sandi    $file = str_replace(':','/',$name).'.txt';
10530cecf9d5Sandi
10540cecf9d5Sandi    if ( @file_exists( DOKU_DATA . $file ) ) {
10550cecf9d5Sandi        $pages[$name] = TRUE;
10560cecf9d5Sandi    } else {
10570cecf9d5Sandi        $pages[$name] = FALSE;
10580cecf9d5Sandi    }
10590cecf9d5Sandi
10600cecf9d5Sandi    return $pages[$name];
10610cecf9d5Sandi}
10620cecf9d5Sandi
1063340756e4Sandi
10644826ab45Sandi//Setup VIM: ex: et ts=4 enc=utf-8 :
1065