xref: /plugin/mikioplugin/syntax/core.php (revision a401c3b7bbc9b6e99dde684722bac8c855cd2cce)
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', 'shadow-none', 'shadow-sm', 'shadow-lg', 'w-25', 'w-50', 'w-75', 'w-100', 'w-auto', 'h-25', 'h-50', 'h-75', 'h-100', 'h-auto', 'text-left', 'text-center', 'text-right', 'text-justify', 'text-wrap', 'text-nowrap', 'text-truncate', 'text-break', 'text-lowercase', 'text-uppercase', 'text-capitalize', 'font-weight-bold', 'font-weight-bolder', 'font-weight-normal', 'font-weight-light', 'font-weight-lighter', 'font-italic', 'text-monospace', 'text-reset', 'text-muted', 'text-decoration-none', 'text-primary', 'text-secondary', 'text-success', 'text-danger', 'text-warning', 'text-info', 'text-light'. 'text-dark', 'text-body', 'text-white', 'text-black', 'text-white-50', 'text-black-50', 'bg-primary', 'bg-secondary', 'bg-success', 'bg-danger', 'bg-warning', 'bg-info', 'bg-light', 'bg-dark', 'bg-white', 'bg-transparent', 'border', 'border-top', 'border-right', 'border-bottom', 'border-left', 'border-0', 'border-top-0', 'border-right-0', 'border-bottom-0', 'border-left-0', 'border-primary', 'border-secondary', 'border-success', 'border-danger', 'border-warning', 'border-info', 'border-light', 'border-dark', 'border-white', 'rounded', 'rounded-top', 'rounded-right', 'rounded-bottom', 'rounded-left', 'rounded-circle', 'rounded-pill', 'rounded-0', 'rounded-sm', 'rounded-lg', 'clearfix', 'align-baseline', 'align-top', 'align-middle', 'align-bottom', 'align-text-top', 'align-text-bottom', 'sm-1', 'sm-2', 'sm-3', 'sm-4', 'sm-5', 'sm-6', 'sm-7', 'sm-8', 'sm-9', 'sm-10', 'sm-11', 'sm-12', 'md-1', 'md-2', 'md-3', 'md-4', 'md-5', 'md-6', 'md-7', 'md-8', 'md-9', 'md-10', 'md-11', 'md-12', 'lg-1', 'lg-2', 'lg-3', 'lg-4', 'lg-5', 'lg-6', 'lg-7', 'lg-8', 'lg-9', 'lg-10', 'lg-11', 'lg-12');
22    public $incOptions          = array('width', 'min-width', 'max-width', 'height', 'min-height', 'max-height', 'overflow', 'tooltip', 'tooltip-html', 'tooltop-left', 'tooltip-top', 'tooltip-right', 'tooltip-bottom', 'tooltip-html-top', 'tooltip-html-left', 'tooltip-html-right', 'tooltip-html-bottom');
23
24
25    function __construct() {
26        if(count($this->incClasses) > 0) {
27            $this->options = array_merge($this->options, $this->incClasses, $this->incOptions);
28        }
29    }
30
31    public function getType() {
32        return 'formatting';
33    }
34
35
36    public function getAllowedTypes() { return array('formatting', 'substition', 'disabled'); }
37    public function getSort(){ return 32; }
38
39
40    public function connectTo($mode) {
41        if($this->pattern_entry == '' && $this->tag != '') {
42            if($this->noEndTag) {
43                $this->pattern_entry = '<(?:' . strtoupper($this->tag) . '|' . strtolower($this->tag) . ').*?>';
44            } else {
45                $this->pattern_entry = '<(?:' . strtoupper($this->tag) . '|' . strtolower($this->tag) . ').*?>(?=.*?</(?:' . strtoupper($this->tag) . '|' . strtolower($this->tag) . ')>)';
46            }
47        }
48
49        if($this->pattern_entry != '') {
50            if($this->noEndTag) {
51                $this->Lexer->addSpecialPattern($this->pattern_entry, $mode, 'plugin_mikioplugin_'.$this->getPluginComponent());
52            } else {
53                $this->Lexer->addEntryPattern($this->pattern_entry, $mode, 'plugin_mikioplugin_'.$this->getPluginComponent());
54            }
55        }
56    }
57
58
59    public function postConnect() {
60        if(!$this->noEndTag) {
61            if($this->pattern_exit == '' && $this->tag != '') {
62                $this->pattern_exit = '</(?:' . strtoupper($this->tag) . '|' . strtolower($this->tag) . ')>';
63            }
64
65            if($this->pattern_exit != '') {
66                $this->Lexer->addExitPattern($this->pattern_exit, 'plugin_mikioplugin_'.$this->getPluginComponent());
67            }
68        }
69    }
70
71    public function handle($match, $state, $pos, Doku_Handler $handler){
72        switch($state) {
73            case DOKU_LEXER_ENTER:
74            case DOKU_LEXER_SPECIAL:
75                $optionlist = preg_split('/\s(?=([^"]*"[^"]*")*[^"]*$)/', substr($match, strlen($this->tag) + 1, -1));
76
77                $options = array();
78                foreach($optionlist as $item) {
79                    $i = strpos($item, '=');
80                    if($i !== false) {
81                        $value = substr($item, $i + 1);
82
83                        if(substr($value, 0, 1) == '"') $value = substr($value, 1);
84                        if(substr($value, -1) == '"') $value = substr($value, 0, -1);
85
86                        $options[substr($item, 0, $i)] = $value;
87                    } else {
88                        $options[$item] = true;
89                    }
90                }
91
92                $options_clean = $this->cleanOptions($options);
93
94                $this->values = $options_clean;
95
96                return array($state, $options_clean);
97
98            case DOKU_LEXER_UNMATCHED:
99                return array($state, $match);
100
101            case DOKU_LEXER_EXIT:
102                return array($state, '');
103        }
104
105        return array();
106    }
107
108
109    public function cleanOptions($options) {
110        $options_clean = array();
111
112        foreach($this->options as $item => $value) {
113            if(is_string($value)) {
114                if(array_key_exists($value, $options)) {
115                    $options_clean[$value] = $options[$value];
116                } else {
117                    $options_clean[$value] = false;
118                }
119            } else if(is_array($value)) {
120                foreach($value as $avalue) {
121                    if(array_key_exists($avalue, $options)) {
122                        $options_clean[$item] = $avalue;
123                    }
124                }
125            }
126        }
127
128        foreach($this->defaults as $item => $value) {
129            if(array_key_exists($item, $options_clean) == false) {
130                $options_clean[$item] = $value;
131            }
132        }
133
134        return $options_clean;
135    }
136
137
138    public function render_lexer_enter(Doku_Renderer $renderer, $data) {
139
140    }
141
142
143    public function render_lexer_unmatched(Doku_Renderer $renderer, $data) {
144        $renderer->doc .= $renderer->_xmlEntities($data);
145    }
146
147
148    public function render_lexer_exit(Doku_Renderer $renderer, $data) {
149
150    }
151
152
153    public function render_lexer_special(Doku_Renderer $renderer, $data) {
154
155    }
156
157
158    public function render($mode, Doku_Renderer $renderer, $data) {
159        if($mode == 'xhtml'){
160            list($state,$match) = $data;
161
162            switch ($state) {
163                case DOKU_LEXER_ENTER:
164                    $this->render_lexer_enter($renderer, $match);
165                    return true;
166
167                case DOKU_LEXER_UNMATCHED :
168                    $this->render_lexer_unmatched($renderer, $match);
169                    return true;
170
171                case DOKU_LEXER_EXIT :
172                    $this->render_lexer_exit($renderer, $match);
173                    return true;
174
175                case DOKU_LEXER_SPECIAL:
176                    $this->render_lexer_special($renderer, $match);
177                    return true;
178            }
179
180            return true;
181        }
182
183        return false;
184    }
185
186
187    public function buildClassString($options=null, $classes=null, $prefix='') {
188        $s = array();
189
190        if($options != null) {
191            if($classes != null) {
192                foreach($classes as $item) {
193                    if(array_key_exists($item, $options) && $options[$item] !== false) {
194                        $classname = $item;
195
196                        if(is_string($options[$item])) {
197                            $classname = $options[$item];
198                        }
199
200                        if(is_string($prefix)) {
201                            $classname = $prefix . $classname;
202                        } else if(is_array($prefix)) {
203                            foreach($prefix as $pitem => $pvalue) {
204                                if(is_string($pvalue)) {
205                                    if($pvalue == $item) {
206                                        if(is_string($options[$item])) {
207                                            $classname = $pitem . $options[$item];
208                                        } else {
209                                            $classname = $pitem . $item;
210                                        }
211                                    }
212                                }
213
214                                if(is_array($pvalue)) {
215                                    foreach($pvalue as $ppitem) {
216                                        if($ppitem == $item) {
217                                            if(is_string($options[$item])) {
218                                                $classname = $pitem . $options[$item];
219                                            } else {
220                                                $classname = $pitem . $item;
221                                            }
222                                        }
223                                    }
224                                }
225                            }
226                        }
227
228                        $s[] = $classname;
229                    }
230                }
231            }
232
233            foreach($this->incClasses as $item => $value) {
234                if(array_key_exists($value, $options) && $options[$value] == true) {
235                    $pre = substr($value, 0, 3);
236                    if($pre == 'sm-' || $pre == 'md-' || $pre == 'lg-') $value = 'col-' . $value;
237
238                    $s[] = $value;
239                }
240            }
241        }
242
243        $s = ' ' . implode(' ', $s);
244        return $s;
245    }
246
247    public function buildStyleString($options, $ignore=null, $append='') {
248        $s = array();
249
250        if($options != null) {
251            foreach($options as $item => $value) {
252                if($value != false && ($ignore == null || (is_string($ignore) && $ignore != $item) || (is_array($ignore) && in_array($item, $ignore) == false))) {
253                    switch($item) {
254                        case 'width':
255                            $s[] = 'width:' . $value;
256                            break;
257                        case 'height':
258                            $s[] = 'height:' . $value;
259                            break;
260                        case 'min-width':
261                            $s[] = 'min-width:' . $value;
262                            break;
263                        case 'min-height':
264                            $s[] = 'min-height:' . $value;
265                            break;
266                        case 'max-width':
267                            $s[] = 'max-width:' . $value;
268                            break;
269                        case 'max-height':
270                            $s[] = 'max-height:' . $value;
271                            break;
272                        case 'overflow':
273                            $s[] = 'overflow:' . $value;
274                            break;
275                    }
276                }
277            }
278        }
279
280        $s = implode(';', $s) . $append;
281
282        if($s != '') $s = ' style="' . $s . '" ';
283
284        return $s;
285    }
286
287    public function buildTooltipString($options) {
288        $dataPlacement = 'top';
289        $dataHtml = false;
290        $title = '';
291
292        if($options != null) {
293            if(array_key_exists('tooltip-html-top', $options) && $options['tooltip-html-top'] != '') {
294                $title = $options['tooltip-html-top'];
295                $dataPlacement = 'top';
296            }
297
298            if(array_key_exists('tooltip-html-left', $options) && $options['tooltip-html-left'] != '') {
299                $title = $options['tooltip-html-left'];
300                $dataPlacement = 'left';
301            }
302
303            if(array_key_exists('tooltip-html-bottom', $options) && $options['tooltip-html-bottom'] != '') {
304                $title = $options['tooltip-html-bottom'];
305                $dataPlacement = 'bottom';
306            }
307
308            if(array_key_exists('tooltip-html-right', $options) && $options['tooltip-html-right'] != '') {
309                $title = $options['tooltip-html-right'];
310                $dataPlacement = 'right';
311            }
312
313            if(array_key_exists('tooltip-top', $options) && $options['tooltip-top'] != '') {
314                $title = $options['tooltip-top'];
315                $dataPlacement = 'top';
316            }
317
318            if(array_key_exists('tooltip-left', $options) && $options['tooltip-left'] != '') {
319                $title = $options['tooltip-left'];
320                $dataPlacement = 'left';
321            }
322
323            if(array_key_exists('tooltip-bottom', $options) && $options['tooltip-bottom'] != '') {
324                $title = $options['tooltip-bottom'];
325                $dataPlacement = 'bottom';
326            }
327
328            if(array_key_exists('tooltip-right', $options) && $options['tooltip-right'] != '') {
329                $title = $options['tooltip-right'];
330                $dataPlacement = 'right';
331            }
332
333            if(array_key_exists('tooltip-html', $options) && $options['tooltip-html'] != '') {
334                $title = $options['tooltip-html'];
335                $dataPlacement = 'top';
336            }
337
338            if(array_key_exists('tooltip', $options) && $options['tooltip'] != '') {
339                $title = $options['tooltip'];
340                $dataPlacement = 'top';
341            }
342        }
343
344        if($title != '') {
345            return ' data-toggle="tooltip" data-placement="' . $dataPlacement . '" ' . ($dataHtml == true ? 'data-html="true" ' : '') . 'title="' . $title . '" ';
346        }
347
348        return '';
349    }
350
351    public function getMediaFile($str) {
352        $i = strpos($str, '?');
353        if($i !== false) $str = substr($str, 0, $i);
354
355        $str = preg_replace('/[^\da-zA-Z:_.]+/', '', $str);
356
357        return(tpl_getMediaFile(array($str), false));
358    }
359
360
361    public function getLink($str) {
362        $i = strpos($str, '://');
363        if($i !== false) return $str;
364
365        return wl($str);
366    }
367
368
369    public function setAttr(&$attrList, $attr, $data, $newAttrName='', $newAttrVal='') {
370        if(array_key_exists($attr, $data) && $data[$attr] !== false) {
371            $value = $data[$attr];
372
373            if($newAttrName != '') $attr = $newAttrName;
374            if($newAttrVal != '') {
375                $newAttrVal = str_replace('%%VALUE%%', $value, $newAttrVal);
376                if(strpos($newAttrVal, '%%MEDIA%%') !== false) {
377                    $newAttrVal = str_replace('%%MEDIA%%', $this->getMediaFile($value), $newAttrVal);
378                }
379
380                $value = $newAttrVal;
381            }
382
383            $attrList[$attr] = $value;
384        }
385    }
386
387
388    public function listAttr($attrName, $attrs) {
389        $s = '';
390
391        if(count($attrs) > 0) {
392            foreach($attrs as $item => $value) {
393                $s .= $item . ':' . $value . ';';
394            }
395
396            $s = $attrName . '="' . $s . '" ';
397        }
398
399        return $s;
400    }
401
402
403    public function syntaxRender(Doku_Renderer $renderer, $className, $text, $data=null) {
404        $class = new $className;
405
406        if(!is_array($data)) $data = array();
407
408        $data = $class->cleanOptions($data);
409        $class->values = $data;
410
411        if($class->noEndTag) {
412            $class->render_lexer_special($renderer, $data);
413        } else {
414            $class->render_lexer_enter($renderer, $data);
415            $renderer->doc .= $text;
416            $class->render_lexer_exit($renderer, null);
417        }
418    }
419}