1<?php
2/**
3 * DokuWiki Plugin syntaxhighlightjs (Syntax Component)
4 *
5 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
6 * @author  Claud D. Park <posquit0.bj@gmail.com>
7 */
8
9// must be run within Dokuwiki
10if (!defined('DOKU_INC')) die();
11if (!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN', DOKU_INC.'lib/plugins/');
12require_once(DOKU_PLUGIN.'syntax.php');
13
14class syntax_plugin_syntaxhighlightjs_sxh extends DokuWiki_Syntax_Plugin {
15    /**
16     * @return string Syntax mode type
17     */
18    public function getType() {
19        return 'protected';
20    }
21    /**
22     * @return string Paragraph type
23     */
24    public function getPType() {
25        return 'block';
26    }
27    /**
28     * @return int Sort order - Low numbers go before high numbers
29     */
30    public function getSort() {
31        return 195;
32    }
33
34    /**
35     * Connect lookup pattern to lexer.
36     *
37     * @param string $mode Parser mode
38     */
39    public function connectTo($mode) {
40        $syntax = $this->getConf('syntax');
41        $special_pattern = '<'.$syntax.'\b[^>\r\n]*?/>';
42        $entry_pattern = '<'.$syntax.'\b.*?>\s*(?=.*?</'.$syntax.'>)';
43
44        $this->Lexer->addSpecialPattern(
45            $special_pattern,
46            $mode,
47            'plugin_syntaxhighlightjs_'.$this->getPluginComponent()
48        );
49        $this->Lexer->addEntryPattern(
50            $entry_pattern,
51            $mode,
52            'plugin_syntaxhighlightjs_'.$this->getPluginComponent()
53        );
54    }
55
56    public function postConnect() {
57        $syntax = $this->getConf('syntax');
58        $exit_pattern = '</'.$syntax.'>';
59
60        $this->Lexer->addExitPattern(
61            $exit_pattern,
62            'plugin_syntaxhighlightjs_'.$this->getPluginComponent()
63        );
64    }
65
66    /**
67     * Handle matches of the highlightjs syntax
68     *
69     * @param string $match The match of the syntax
70     * @param int    $state The state of the handler
71     * @param int    $pos The position in the document
72     * @param Doku_Handler    $handler The handler
73     * @return array Data for the renderer
74     */
75    public function handle($match, $state, $pos, Doku_Handler $handler){
76        $data = array();
77
78        switch ($state) {
79            case DOKU_LEXER_ENTER:
80            case DOKU_LEXER_SPECIAL:
81                $data = strtolower(trim(substr($match, strpos($match, ' '), -1), " \t\n/"));
82                return array($state, $data);
83
84            case DOKU_LEXER_UNMATCHED:
85                $handler->_addCall('cdata', array($match), $pos);
86                break;
87
88            case DOKU_LEXER_EXIT:
89                return array($state, '');
90        }
91
92        return false;
93    }
94
95    /**
96     * Render xhtml output or metadata
97     *
98     * @param string         $mode      Renderer mode (supported modes: xhtml)
99     * @param Doku_Renderer  $renderer  The renderer
100     * @param array          $_data      The data from the handler() function
101     * @return bool If rendering was successful.
102     */
103    public function render($mode, Doku_Renderer $renderer, $_data) {
104        if (empty($_data)) return false;
105        list($state, $data) = $_data;
106
107        if ($mode == 'xhtml') {
108            /** @var Doku_Renderer_xhtml $renderer */
109            switch ($state) {
110                case DOKU_LEXER_ENTER:
111                case DOKU_LEXER_SPECIAL:
112                    $helper = $this->loadHelper('syntaxhighlightjs');
113                    $attr = $helper->buildAttributes($data);
114
115                    $renderer->doc .= '<pre class=\'hljs-wrap\'><code'.$attr.'>';
116                    if ($state == DOKU_LEXER_SPECIAL) $renderer->doc .= '</code></pre>';
117                    break;
118
119                case DOKU_LEXER_EXIT:
120                    $renderer->doc .= '</code></pre>';
121                    break;
122            }
123            return true;
124        }
125
126        return false;
127    }
128}
129
130// vim:ts=4:sw=4:et:
131