1<?php
2/**
3 * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
4 * @author     Andreas Gohr <andi@splitbrain.org>
5 */
6// must be run within Dokuwiki
7if(!defined('DOKU_INC')) die();
8
9if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
10require_once(DOKU_PLUGIN.'syntax.php');
11
12class syntax_plugin_xref extends DokuWiki_Syntax_Plugin {
13
14    var $dir = '';
15    var $web = '';
16
17    function syntax_plugin_xref(){
18        $this->dir = rtrim($this->getConf('dir'),'/');
19        $this->web = rtrim($this->getConf('web'),'/');
20    }
21
22    /**
23     * What kind of syntax are we?
24     */
25    function getType(){
26        return 'substition';
27    }
28
29    /**
30     * What about paragraphs?
31     */
32    function getPType(){
33        return 'normal';
34    }
35
36    /**
37     * Where to sort in?
38     */
39    function getSort(){
40        return 150;
41    }
42
43
44    /**
45     * Connect pattern to lexer
46     */
47    function connectTo($mode) {
48        $this->Lexer->addSpecialPattern('\[\[xref>.+?\]\]',$mode,'plugin_xref');
49    }
50
51
52    /**
53     * Handle the match
54     */
55    function handle($match, $state, $pos, Doku_Handler $handler){
56        $match = trim(substr($match,7,-2));
57
58        list($link,$name) = explode('|',$match,2);
59        list($link,$anchor) = explode('#',$link,2);
60        if(!$name) $name = $link;
61        if($anchor) $anchor = "#".$anchor;
62
63        $first = 0;
64        if($link[0] == '$') $first = 4;
65        $found = $this->_find($link,$first);
66
67        return array($link,$found,$name,$anchor);
68    }
69
70    /**
71     * Create output
72     */
73    function render($format, Doku_Renderer $R, $data) {
74        global $conf;
75        if($format != 'xhtml') return false;
76
77        //prepare for formating
78        $link['target'] = $conf['target']['extern'];
79        $link['style']  = '';
80        $link['pre']    = '';
81        $link['suf']    = '';
82        $link['more']   = '';
83        $link['class']  = 'xref_plugin';
84        $link['name']  = hsc($data[2]);
85
86        if(!$data[1]){
87            $link['url']   = $this->web;
88            $link['title'] = $this->getLang('unknown');
89            $link['class'] .= ' xref_plugin_err';
90        }else{
91            $link['url']  = $this->web.'/'.$data[1].hsc($data[3]);
92            $link['title']  = sprintf($this->getLang('view'),hsc($data[0]));
93        }
94
95        $R->doc .= $R->_formatLink($link);
96        return true;
97    }
98
99    /**
100     * Try to find the given name in the xref directory
101     *
102     * @param int $first - defines which type should be searched first for the name
103     */
104    function _find($name,$first=0){
105        $paths = array(
106                    0 => '_functions',
107                    1 => '_classes',
108                    2 => '_constants',
109                    3 => '_tables',
110                    4 => '_variables'
111                );
112
113        $clean = preg_replace('/[^\w\-_]+/','',$name);
114        $small = strtolower($clean);
115
116        $path = $paths[$first];
117        unset($paths[$first]);
118        do{
119            $check = $path.'/'.$clean.'.html';
120            if(@file_exists($this->dir.'/'.$check)) return $check;
121            $check = $path.'/'.$small.'.html';
122            if(@file_exists($this->dir.'/'.$check)) return $check;
123            $path = array_shift($paths);
124        }while($path);
125
126        // still here? might be a file reference
127        $clean = preg_replace('/\.\.+/','.',$name);
128        if(@file_exists($this->dir.'/'.$clean.'.html')){
129            return $clean.'.html';
130        }
131
132        return '';
133    }
134
135}
136
137//Setup VIM: ex: et ts=4 enc=utf-8 :
138