1<?php
2/**
3 * DokuWiki Plugin foldablelist (Syntax Component)
4 *
5 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
6 * @author  medmen <med-men@gmx.net>
7 */
8
9// must be run within Dokuwiki
10if (!defined('DOKU_INC')) die();
11
12class syntax_plugin_foldablelist extends DokuWiki_Syntax_Plugin {
13    /**
14     * protected $entry_pattern = ' <note.*?>(?=.*?</note>)';
15     */
16    protected $entry_pattern   = '<foldablelist.*?>(?=.*?</foldablelist>)';
17    protected $exit_pattern    = '</foldablelist>';
18
19    /**
20     * @return string Syntax mode type
21     */
22    public function getType() {
23        return 'container';
24    }
25
26    function getAllowedTypes() {
27        return array('container','substition','protected','disabled','formatting','paragraphs');
28    }
29
30    /**
31     * @return string Paragraph type
32     */
33    public function getPType() {
34        return 'block';
35    }
36
37    /**
38     * @return int Sort order - Low numbers go before high numbers
39     */
40    public function getSort() {
41        return 201;
42    }
43
44    /**
45     * Connect lookup pattern to lexer.
46     *
47     * @param string $mode Parser mode
48     */
49    public function connectTo($mode) {
50        // $this->Lexer->addSpecialPattern($this->special_pattern, $mode, 'plugin_foldablelist');
51        $this->Lexer->addEntryPattern($this->entry_pattern, $mode, 'plugin_foldablelist');
52    }
53
54    public function postConnect() {
55        $this->Lexer->addExitPattern($this->exit_pattern, 'plugin_foldablelist');
56    }
57
58
59    /**
60     * Handle matches of the scrollticker syntax
61     *
62     * @param string          $match   The match of the syntax
63     * @param int             $state   The state of the handler
64     * @param int             $pos     The position in the document
65     * @param Doku_Handler    $handler The handler
66     * @return array Data for the renderer
67     */
68    public function handle($match, $state, $pos, Doku_Handler $handler){
69        global $conf;
70        $plugin = $this->getPluginName();
71
72        switch ($state) {
73            case DOKU_LEXER_ENTER:
74                /**
75                 * $match = "<foldablelist collapse_after=2>"
76                 */
77                $parameters = trim(substr($match, 13, -1)); // get string between "<foldablelist" and ">"
78                if(strlen(trim($parameters))< 3) {
79                    return array($state, $match, false); // no parameters given, dont bother with extra work
80                }
81
82                $params_arr = array();
83                if($parameters and strpos($parameters, '=')) { // see if we have a string and it contains at least one '='
84                    $parameters = preg_split('/\s+/', $parameters, -1, PREG_SPLIT_NO_EMPTY); // turn into array separated by whit spaces
85                    foreach($parameters as $parameter) {
86                        list($key, $val) = explode('=', $parameter);
87                        /**
88                        // override predefined settings!
89                        if (isset($conf['plugin'][$plugin][$key])) {
90                            $conf['plugin'][$plugin][$key] = $val;
91                        }
92                         **/
93                        $key = 'data-'.strtolower(trim(htmlspecialchars($key))); // http://html5doctor.com/html5-custom-data-attributes/
94                        $val = strtolower(trim(htmlspecialchars($val)));
95                        $params_arr[$key] = $val;
96                    }
97                }
98
99                return array($state, $match, $params_arr);
100
101            default:
102                return array($state, $match, false);
103        }
104    }
105
106    /**
107     * Render xhtml output or metadata
108     *
109     * @param string         $mode      Renderer mode (supported modes: xhtml)
110     * @param Doku_Renderer  $renderer  The renderer
111     * @param array          $data      The data from the handler() function
112     * @return bool If rendering was successful.
113     */
114    public function render($mode, Doku_Renderer $renderer, $data) {
115        global $conf;
116        if($mode != 'xhtml') return false;
117        if (empty($data)) return false;
118
119        list($state, $match, $parameters) = $data;
120
121        switch ($state) {
122            case DOKU_LEXER_ENTER :
123                // xdebug_break();
124                if(is_array($parameters) and count($parameters) > 0) {
125                    // implode array fast
126                    $parameters = http_build_query($parameters,'', ' ');
127                }
128
129                $renderer->doc .= '<div class="foldablelist" '.$parameters.'>';
130                break;
131            case DOKU_LEXER_UNMATCHED :
132                $renderer->doc .= $renderer->_xmlEntities($match);
133                break;
134            case DOKU_LEXER_EXIT :
135                $renderer->doc .= '</div>';
136                break;
137            default:
138                $renderer->doc.= 'MATCH: '.$renderer->_xmlEntities($match);
139                $renderer->doc.= 'STATE: '.$renderer->_xmlEntities($state);
140                $renderer->doc.= 'PARAMS: '.$renderer->_xmlEntities($parameters);
141        }
142
143        // $renderer->doc .= var_export($data, true); // might be helpful when debugging
144        return true;
145    }
146}
147
148// vim:ts=4:sw=4:et: