xref: /plugin/mikioplugin/syntax/core.php (revision 31359b6f91f10292b36c5fc0fc2aab76a95b00d7)
1<?php
2/**
3 * Mikio Core Syntax Plugin
4 *
5 * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
6 * @author     James Collins <james.collins@outlook.com.au>
7 */
8
9if (!defined('DOKU_INC')) die();
10if (!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
11
12
13class syntax_plugin_mikioplugin_core extends DokuWiki_Syntax_Plugin {
14    public $pattern_entry       = '';
15    public $pattern_exit        = '';
16    public $tag                 = '';
17    public $noEndTag            = false;
18    public $defaults            = array();
19    public $options             = array();
20    public $values              = array();
21    public $incClasses          = array('shadow');
22
23
24    function __construct() {
25        if(count($this->incClasses) > 0) {
26            $this->options = array_merge($this->options, $this->incClasses);
27        }
28    }
29
30    public function getType() {
31        return 'formatting';
32    }
33
34
35    public function getAllowedTypes() { return array('formatting', 'substition', 'disabled'); }
36    public function getSort(){ return 32; }
37
38
39    public function connectTo($mode) {
40        if($this->pattern_entry == '' && $this->tag != '') {
41            if($this->noEndTag) {
42                $this->pattern_entry = '<(?:' . strtoupper($this->tag) . '|' . strtolower($this->tag) . ').*?>';
43            } else {
44                $this->pattern_entry = '<(?:' . strtoupper($this->tag) . '|' . strtolower($this->tag) . ').*?>(?=.*?</(?:' . strtoupper($this->tag) . '|' . strtolower($this->tag) . ')>)';
45            }
46        }
47
48        if($this->pattern_entry != '') {
49            if($this->noEndTag) {
50                $this->Lexer->addSpecialPattern($this->pattern_entry, $mode, 'plugin_mikioplugin_'.$this->getPluginComponent());
51            } else {
52                $this->Lexer->addEntryPattern($this->pattern_entry, $mode, 'plugin_mikioplugin_'.$this->getPluginComponent());
53            }
54        }
55    }
56
57
58    public function postConnect() {
59        if(!$this->noEndTag) {
60            if($this->pattern_exit == '' && $this->tag != '') {
61                $this->pattern_exit = '</(?:' . strtoupper($this->tag) . '|' . strtolower($this->tag) . ')>';
62            }
63
64            if($this->pattern_exit != '') {
65                $this->Lexer->addExitPattern($this->pattern_exit, 'plugin_mikioplugin_'.$this->getPluginComponent());
66            }
67        }
68    }
69
70    public function handle($match, $state, $pos, Doku_Handler $handler){
71        switch($state) {
72            case DOKU_LEXER_ENTER:
73            case DOKU_LEXER_SPECIAL:
74                $optionlist = preg_split('/\s(?=([^"]*"[^"]*")*[^"]*$)/', substr($match, strlen($this->tag) + 1, -1));
75
76                $options = array();
77                foreach($optionlist as $item) {
78                    $i = strpos($item, '=');
79                    if($i !== false) {
80                        $value = substr($item, $i + 1);
81
82                        if(substr($value, 0, 1) == '"') $value = substr($value, 1);
83                        if(substr($value, -1) == '"') $value = substr($value, 0, -1);
84
85                        $options[substr($item, 0, $i)] = $value;
86                    } else {
87                        $options[$item] = true;
88                    }
89                }
90
91                $options_clean = $this->cleanOptions($options);
92
93                $this->values = $options_clean;
94
95                return array($state, $options_clean);
96
97            case DOKU_LEXER_UNMATCHED:
98                return array($state, $match);
99
100            case DOKU_LEXER_EXIT:
101                return array($state, '');
102        }
103
104        return array();
105    }
106
107
108    public function cleanOptions($options) {
109        $options_clean = array();
110
111        foreach($this->options as $item => $value) {
112            if(is_string($value)) {
113                if(array_key_exists($value, $options)) {
114                    $options_clean[$value] = $options[$value];
115                } else {
116                    $options_clean[$value] = false;
117                }
118            } else if(is_array($value)) {
119                foreach($value as $avalue) {
120                    if(array_key_exists($avalue, $options)) {
121                        $options_clean[$item] = $avalue;
122                    }
123                }
124            }
125        }
126
127        foreach($this->defaults as $item => $value) {
128            if(array_key_exists($item, $options_clean) == false) {
129                $options_clean[$item] = $value;
130            }
131        }
132
133        return $options_clean;
134    }
135
136
137    public function render_lexer_enter(Doku_Renderer $renderer, $data) {
138
139    }
140
141
142    public function render_lexer_unmatched(Doku_Renderer $renderer, $data) {
143        $renderer->doc .= $renderer->_xmlEntities($data);
144    }
145
146
147    public function render_lexer_exit(Doku_Renderer $renderer, $data) {
148
149    }
150
151
152    public function render_lexer_special(Doku_Renderer $renderer, $data) {
153
154    }
155
156
157    public function render($mode, Doku_Renderer $renderer, $data) {
158        if($mode == 'xhtml'){
159            list($state,$match) = $data;
160
161            switch ($state) {
162                case DOKU_LEXER_ENTER:
163                    $this->render_lexer_enter($renderer, $match);
164                    return true;
165
166                case DOKU_LEXER_UNMATCHED :
167                    $this->render_lexer_unmatched($renderer, $match);
168                    return true;
169
170                case DOKU_LEXER_EXIT :
171                    $this->render_lexer_exit($renderer, $match);
172                    return true;
173
174                    case DOKU_LEXER_SPECIAL:
175                        $this->render_lexer_special($renderer, $match);
176                        return true;
177            }
178
179            return true;
180        }
181
182        return false;
183    }
184
185
186    public function buildClassString($options, $classes, $prefix) {
187        $s = array();
188
189        foreach($classes as $item) {
190            if(array_key_exists($item, $options) && $options[$item] !== false) {
191                $classname = $item;
192
193                if(is_string($options[$item])) {
194                    $classname = $options[$item];
195                }
196
197                if(is_string($prefix)) {
198                    $classname = $prefix . $classname;
199                } else if(is_array($prefix)) {
200                    foreach($prefix as $pitem => $pvalue) {
201                        if(is_string($pvalue)) {
202                            if($pvalue == $item) {
203                                if(is_string($options[$item])) {
204                                    $classname = $pitem . $options[$item];
205                                } else {
206                                    $classname = $pitem . $item;
207                                }
208                            }
209                        }
210
211                        if(is_array($pvalue)) {
212                            foreach($pvalue as $ppitem) {
213                                if($ppitem == $item) {
214                                    if(is_string($options[$item])) {
215                                        $classname = $pitem . $options[$item];
216                                    } else {
217                                        $classname = $pitem . $item;
218                                    }
219                                }
220                            }
221                        }
222                    }
223                }
224
225                $s[] = $classname;
226            }
227        }
228
229        foreach($this->incClasses as $item) {
230            if(array_key_exists($item, $options) && $options[$item] == true) $s[] = $item;
231        }
232
233        $s = ' ' . implode(' ', $s);
234        return $s;
235    }
236
237
238    public function getMediaFile($str) {
239        $i = strpos($str, '?');
240        if($i !== false) $str = substr($str, 0, $i);
241
242        $str = preg_replace('/[^\da-zA-Z:_.]+/', '', $str);
243
244        return(tpl_getMediaFile(array($str), false));
245    }
246
247
248    public function getLink($str) {
249        $i = strpos($str, '://');
250        if($i !== false) return $str;
251
252        return wl($str);
253    }
254
255
256    public function setAttr(&$attrList, $attr, $data, $newAttrName='', $newAttrVal='') {
257        if(array_key_exists($attr, $data) && $data[$attr] !== false) {
258            $value = $data[$attr];
259
260            if($newAttrName != '') $attr = $newAttrName;
261            if($newAttrVal != '') {
262                $newAttrVal = str_replace('%%VALUE%%', $value, $newAttrVal);
263                if(strpos($newAttrVal, '%%MEDIA%%') !== false) {
264                    $newAttrVal = str_replace('%%MEDIA%%', $this->getMediaFile($value), $newAttrVal);
265                }
266
267                $value = $newAttrVal;
268            }
269
270            $attrList[$attr] = $value;
271        }
272    }
273
274
275    public function listAttr($attrName, $attrs) {
276        $s = '';
277
278        if(count($attrs) > 0) {
279            foreach($attrs as $item => $value) {
280                $s .= $item . ':' . $value . ';';
281            }
282
283            $s = $attrName . '="' . $s . '" ';
284        }
285
286        return $s;
287    }
288
289
290    public function syntaxRender(Doku_Renderer $renderer, $className, $text, $data=null) {
291        $class = new $className;
292
293        if(!is_array($data)) $data = array();
294
295        $data = $class->cleanOptions($data);
296
297        if($class->noEndTag) {
298            $class->render_lexer_special($renderer, $data);
299        } else {
300            $class->render_lexer_enter($renderer, $data);
301            $renderer->doc .= $text;
302            $class->render_lexer_exit($renderer, null);
303        }
304    }
305}