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