xref: /plugin/mikioplugin/syntax/core.php (revision a007b54ff6bb027bb0c994dbc80800a1cd362e77)
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', 'text-center', 'text-right');
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=null, $classes=null, $prefix='') {
187        $s = array();
188
189        if($options != null) {
190            if($classes != null) {
191                foreach($classes as $item) {
192                    if(array_key_exists($item, $options) && $options[$item] !== false) {
193                        $classname = $item;
194
195                        if(is_string($options[$item])) {
196                            $classname = $options[$item];
197                        }
198
199                        if(is_string($prefix)) {
200                            $classname = $prefix . $classname;
201                        } else if(is_array($prefix)) {
202                            foreach($prefix as $pitem => $pvalue) {
203                                if(is_string($pvalue)) {
204                                    if($pvalue == $item) {
205                                        if(is_string($options[$item])) {
206                                            $classname = $pitem . $options[$item];
207                                        } else {
208                                            $classname = $pitem . $item;
209                                        }
210                                    }
211                                }
212
213                                if(is_array($pvalue)) {
214                                    foreach($pvalue as $ppitem) {
215                                        if($ppitem == $item) {
216                                            if(is_string($options[$item])) {
217                                                $classname = $pitem . $options[$item];
218                                            } else {
219                                                $classname = $pitem . $item;
220                                            }
221                                        }
222                                    }
223                                }
224                            }
225                        }
226
227                        $s[] = $classname;
228                    }
229                }
230            }
231
232            foreach($this->incClasses as $item) {
233                if(array_key_exists($item, $options) && $options[$item] == true) $s[] = $item;
234            }
235        }
236
237        $s = ' ' . implode(' ', $s);
238        return $s;
239    }
240
241
242    public function getMediaFile($str) {
243        $i = strpos($str, '?');
244        if($i !== false) $str = substr($str, 0, $i);
245
246        $str = preg_replace('/[^\da-zA-Z:_.]+/', '', $str);
247
248        return(tpl_getMediaFile(array($str), false));
249    }
250
251
252    public function getLink($str) {
253        $i = strpos($str, '://');
254        if($i !== false) return $str;
255
256        return wl($str);
257    }
258
259
260    public function setAttr(&$attrList, $attr, $data, $newAttrName='', $newAttrVal='') {
261        if(array_key_exists($attr, $data) && $data[$attr] !== false) {
262            $value = $data[$attr];
263
264            if($newAttrName != '') $attr = $newAttrName;
265            if($newAttrVal != '') {
266                $newAttrVal = str_replace('%%VALUE%%', $value, $newAttrVal);
267                if(strpos($newAttrVal, '%%MEDIA%%') !== false) {
268                    $newAttrVal = str_replace('%%MEDIA%%', $this->getMediaFile($value), $newAttrVal);
269                }
270
271                $value = $newAttrVal;
272            }
273
274            $attrList[$attr] = $value;
275        }
276    }
277
278
279    public function listAttr($attrName, $attrs) {
280        $s = '';
281
282        if(count($attrs) > 0) {
283            foreach($attrs as $item => $value) {
284                $s .= $item . ':' . $value . ';';
285            }
286
287            $s = $attrName . '="' . $s . '" ';
288        }
289
290        return $s;
291    }
292
293
294    public function syntaxRender(Doku_Renderer $renderer, $className, $text, $data=null) {
295        $class = new $className;
296
297        if(!is_array($data)) $data = array();
298
299        $data = $class->cleanOptions($data);
300
301        if($class->noEndTag) {
302            $class->render_lexer_special($renderer, $data);
303        } else {
304            $class->render_lexer_enter($renderer, $data);
305            $renderer->doc .= $text;
306            $class->render_lexer_exit($renderer, null);
307        }
308    }
309}