1<?php
2/**
3 * Info Plugin: Displays information about various DokuWiki internals
4 *
5 * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
6 * @author     Andreas Gohr <andi@splitbrain.org>
7 * @author     Esther Brunner <wikidesign@gmail.com>
8 */
9class syntax_plugin_info extends DokuWiki_Syntax_Plugin
10{
11
12    /**
13     * What kind of syntax are we?
14     */
15    public function getType()
16    {
17        return 'substition';
18    }
19
20    /**
21     * What about paragraphs?
22     */
23    public function getPType()
24    {
25        return 'block';
26    }
27
28    /**
29     * Where to sort in?
30     */
31    public function getSort()
32    {
33        return 155;
34    }
35
36
37    /**
38     * Connect pattern to lexer
39     */
40    public function connectTo($mode)
41    {
42        $this->Lexer->addSpecialPattern('~~INFO:\w+~~', $mode, 'plugin_info');
43    }
44
45    /**
46     * Handle the match
47     *
48     * @param   string       $match   The text matched by the patterns
49     * @param   int          $state   The lexer state for the match
50     * @param   int          $pos     The character position of the matched text
51     * @param   Doku_Handler $handler The Doku_Handler object
52     * @return  array Return an array with all data you want to use in render
53     */
54    public function handle($match, $state, $pos, Doku_Handler $handler)
55    {
56        $match = substr($match, 7, -2); //strip ~~INFO: from start and ~~ from end
57        return array(strtolower($match));
58    }
59
60    /**
61     * Create output
62     *
63     * @param string $format   string     output format being rendered
64     * @param Doku_Renderer    $renderer  the current renderer object
65     * @param array            $data      data created by handler()
66     * @return  boolean                 rendered correctly?
67     */
68    public function render($format, Doku_Renderer $renderer, $data)
69    {
70        if ($format == 'xhtml') {
71            /** @var Doku_Renderer_xhtml $renderer */
72            //handle various info stuff
73            switch ($data[0]) {
74                case 'syntaxmodes':
75                    $renderer->doc .= $this->renderSyntaxModes();
76                    break;
77                case 'syntaxtypes':
78                    $renderer->doc .= $this->renderSyntaxTypes();
79                    break;
80                case 'syntaxplugins':
81                    $this->renderPlugins('syntax', $renderer);
82                    break;
83                case 'adminplugins':
84                    $this->renderPlugins('admin', $renderer);
85                    break;
86                case 'actionplugins':
87                    $this->renderPlugins('action', $renderer);
88                    break;
89                case 'rendererplugins':
90                    $this->renderPlugins('renderer', $renderer);
91                    break;
92                case 'helperplugins':
93                    $this->renderPlugins('helper', $renderer);
94                    break;
95                case 'authplugins':
96                    $this->renderPlugins('auth', $renderer);
97                    break;
98                case 'remoteplugins':
99                    $this->renderPlugins('remote', $renderer);
100                    break;
101                case 'helpermethods':
102                    $this->renderHelperMethods($renderer);
103                    break;
104                case 'datetime':
105                    $renderer->doc .= date('r');
106                    break;
107                default:
108                    $renderer->doc .= "no info about ".htmlspecialchars($data[0]);
109            }
110            return true;
111        }
112        return false;
113    }
114
115    /**
116     * list all installed plugins
117     *
118     * uses some of the original renderer methods
119     *
120     * @param string $type
121     * @param Doku_Renderer_xhtml $renderer
122     */
123    protected function renderPlugins($type, Doku_Renderer_xhtml $renderer)
124    {
125        global $lang;
126        $renderer->doc .= '<ul>';
127
128        $plugins = plugin_list($type);
129        $plginfo = array();
130
131        // remove subparts
132        foreach ($plugins as $p) {
133            if (!$po = plugin_load($type, $p)) continue;
134            list($name,/* $part */) = explode('_', $p, 2);
135            $plginfo[$name] = $po->getInfo();
136        }
137
138        // list them
139        foreach ($plginfo as $info) {
140            $renderer->doc .= '<li><div class="li">';
141            $renderer->externallink($info['url'], $info['name']);
142            $renderer->doc .= ' ';
143            $renderer->doc .= '<em>'.$info['date'].'</em>';
144            $renderer->doc .= ' ';
145            $renderer->doc .= $lang['by'];
146            $renderer->doc .= ' ';
147            $renderer->emaillink($info['email'], $info['author']);
148            $renderer->doc .= '<br />';
149            $renderer->doc .= strtr(hsc($info['desc']), array("\n"=>"<br />"));
150            $renderer->doc .= '</div></li>';
151            unset($po);
152        }
153
154        $renderer->doc .= '</ul>';
155    }
156
157    /**
158     * list all installed plugins
159     *
160     * uses some of the original renderer methods
161     *
162     * @param Doku_Renderer_xhtml $renderer
163     */
164    protected function renderHelperMethods(Doku_Renderer_xhtml $renderer)
165    {
166        $plugins = plugin_list('helper');
167        foreach ($plugins as $p) {
168            if (!$po = plugin_load('helper', $p)) continue;
169
170            if (!method_exists($po, 'getMethods')) continue;
171            $methods = $po->getMethods();
172            $info = $po->getInfo();
173
174            $hid = $this->addToToc($info['name'], 2, $renderer);
175            $doc = '<h2><a name="'.$hid.'" id="'.$hid.'">'.hsc($info['name']).'</a></h2>';
176            $doc .= '<div class="level2">';
177            $doc .= '<p>'.strtr(hsc($info['desc']), array("\n"=>"<br />")).'</p>';
178            $doc .= '<pre class="code">$'.$p." = plugin_load('helper', '".$p."');</pre>";
179            $doc .= '</div>';
180            foreach ($methods as $method) {
181                $title = '$'.$p.'->'.$method['name'].'()';
182                $hid = $this->addToToc($title, 3, $renderer);
183                $doc .= '<h3><a name="'.$hid.'" id="'.$hid.'">'.hsc($title).'</a></h3>';
184                $doc .= '<div class="level3">';
185                $doc .= '<div class="table"><table class="inline"><tbody>';
186                $doc .= '<tr><th>Description</th><td colspan="2">'.$method['desc'].
187                    '</td></tr>';
188                if ($method['params']) {
189                    $c = count($method['params']);
190                    $doc .= '<tr><th rowspan="'.$c.'">Parameters</th><td>';
191                    $params = array();
192                    foreach ($method['params'] as $desc => $type) {
193                        $params[] = hsc($desc).'</td><td>'.hsc($type);
194                    }
195                    $doc .= join('</td></tr><tr><td>', $params).'</td></tr>';
196                }
197                if ($method['return']) {
198                    $doc .= '<tr><th>Return value</th><td>'.hsc(key($method['return'])).
199                        '</td><td>'.hsc(current($method['return'])).'</td></tr>';
200                }
201                $doc .= '</tbody></table></div>';
202                $doc .= '</div>';
203            }
204            unset($po);
205
206            $renderer->doc .= $doc;
207        }
208    }
209
210    /**
211     * lists all known syntax types and their registered modes
212     *
213     * @return string
214     */
215    protected function renderSyntaxTypes()
216    {
217        global $PARSER_MODES;
218        $doc  = '';
219
220        $doc .= '<div class="table"><table class="inline"><tbody>';
221        foreach ($PARSER_MODES as $mode => $modes) {
222            $doc .= '<tr>';
223            $doc .= '<td class="leftalign">';
224            $doc .= $mode;
225            $doc .= '</td>';
226            $doc .= '<td class="leftalign">';
227            $doc .= join(', ', $modes);
228            $doc .= '</td>';
229            $doc .= '</tr>';
230        }
231        $doc .= '</tbody></table></div>';
232        return $doc;
233    }
234
235    /**
236     * lists all known syntax modes and their sorting value
237     *
238     * @return string
239     */
240    protected function renderSyntaxModes()
241    {
242        $modes = p_get_parsermodes();
243
244        $compactmodes = array();
245        foreach ($modes as $mode) {
246            $compactmodes[$mode['sort']][] = $mode['mode'];
247        }
248        $doc  = '';
249        $doc .= '<div class="table"><table class="inline"><tbody>';
250
251        foreach ($compactmodes as $sort => $modes) {
252            $rowspan = '';
253            if (count($modes) > 1) {
254                $rowspan = ' rowspan="'.count($modes).'"';
255            }
256
257            foreach ($modes as $index => $mode) {
258                $doc .= '<tr>';
259                $doc .= '<td class="leftalign">';
260                $doc .= $mode;
261                $doc .= '</td>';
262
263                if ($index === 0) {
264                    $doc .= '<td class="rightalign" '.$rowspan.'>';
265                    $doc .= $sort;
266                    $doc .= '</td>';
267                }
268                $doc .= '</tr>';
269            }
270        }
271
272        $doc .= '</tbody></table></div>';
273        return $doc;
274    }
275
276    /**
277     * Adds a TOC item
278     *
279     * @param string $text
280     * @param int $level
281     * @param Doku_Renderer_xhtml $renderer
282     * @return string
283     */
284    protected function addToToc($text, $level, Doku_Renderer_xhtml $renderer)
285    {
286        global $conf;
287
288        $hid = '';
289        if (($level >= $conf['toptoclevel']) && ($level <= $conf['maxtoclevel'])) {
290            $hid  = $renderer->_headerToLink($text, true);
291            $renderer->toc[] = array(
292                'hid'   => $hid,
293                'title' => $text,
294                'type'  => 'ul',
295                'level' => $level - $conf['toptoclevel'] + 1
296            );
297        }
298        return $hid;
299    }
300}
301
302//Setup VIM: ex: et ts=4 :
303