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