1<?php
2/**
3 * Code Plugin: replaces Dokuwiki's own code syntax
4 *
5 * Syntax:     <code |title>
6 *   title     (optional) all text after '|' will be rendered above the main code text with a
7 *             different style.
8 *
9 * if no title is provided will render as native dokuwiki code syntax mode, e.g.
10 *   <pre class='code {lang}'> ... </pre>
11 *
12 * if title is provided will render as follows
13 *   <div class='code'>
14 *     <p>{title}</p>
15 *     <pre class='code {lang}'> ... </pre>
16 *   </div>
17 *
18 * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
19 * @author     Christopher Smith <chris@jalakai.co.uk>
20 * @author     Ilya Lebedev <ilya@lebedev.net>
21 */
22
23if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/');
24if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
25require_once(DOKU_PLUGIN.'syntax.php');
26
27/**
28 * All DokuWiki plugins to extend the parser/rendering mechanism
29 * need to inherit from this class
30 */
31class syntax_plugin_code_code extends DokuWiki_Syntax_Plugin {
32
33    var $syntax = "";
34
35    /**
36     * return some info
37     */
38    function getInfo(){
39      return array(
40        'author' => 'Ilya Lebedev',
41        'email'  => 'ilya@lebedev.net',
42        'date'   => '2008-02-02',
43        'name'   => 'Code Replacement Plugin',
44        'desc'   => 'Replacement for Dokuwiki\'s own <code> handler, adds a title to the box and JavaScript-based syntax highlighting.
45                     Syntax: <code |title>, title is optional and does not support any dokuwiki markup.',
46        'url'    => 'https://www.dokuwiki.org/plugin:code3',
47      );
48    }
49
50    function getType(){ return 'protected';}
51    function getPType(){ return 'block';}
52
53    // must return a number lower than returned by native 'code' mode (200)
54    function getSort(){ return 193; }
55
56    /**
57     * Connect pattern to lexer
58     */
59    function connectTo($mode) {
60      $this->Lexer->addEntryPattern('<code(?=[^\r\n]*?>.*?</co'.'de>)',$mode,'plugin_code_code');
61    }
62
63    function postConnect() {
64      $this->Lexer->addExitPattern('</co'.'de>', 'plugin_code_code');
65    }
66
67    /**
68     * Handle the match
69     */
70    function handle($match, $state, $pos, &$handler){
71
72        switch ($state) {
73            case DOKU_LEXER_ENTER:
74                $this->syntax = substr($match, 1);
75                return false;
76
77            case DOKU_LEXER_UNMATCHED:
78                // will include everything from <code ... to ... </code >
79                // e.g. ... [lang] [|title] > [content]
80                list($attr, $content) = preg_split('/>/u',$match,2);
81                list($lang, $title) = preg_split('/\|/u',$attr,2);
82
83                if ($this->syntax == 'code') {
84                    $lang = trim($lang);
85                    if ($lang == 'html') $lang = 'html4strict';
86                    if (!$lang) $lang = NULL;
87                } else {
88                    $lang = NULL;
89                }
90
91                return array($this->syntax, $lang, trim($title), $content);
92        }
93        return false;
94    }
95
96    /**
97     * Create output
98     */
99    function render($mode, &$renderer, $data) {
100
101      if($mode == 'xhtml'){
102        if (count($data) == 4) {
103
104            list($syntax, $lang, $title, $content) = $data;
105            if ($title) $renderer->doc .= "<div class='$syntax'><p>".$renderer->_xmlEntities($title)."</p>";
106            if ($syntax == 'code')
107                $renderer->doc .= "<pre class=\"code\">".$renderer->_xmlEntities($content)."</pre>";
108            else
109                $renderer->file($content);
110            if ($title) $renderer->doc .= "</div>";
111        }
112
113        return true;
114      }
115      return false;
116    }
117}
118
119//Setup VIM: ex: et ts=4 enc=utf-8 :
120