xref: /plugin/mikioplugin/syntax/core.php (revision 7935713e90ae66bca4380ea057ab7fd4f3e18daa)
117e6d639SJames Collins<?php
217e6d639SJames Collins/**
317e6d639SJames Collins * Mikio Core Syntax Plugin
417e6d639SJames Collins *
5*7935713eSJames Collins * @link        http://github.com/nomadjimbob/mikioplugin
617e6d639SJames Collins * @license     GPL 2 (http://www.gnu.org/licenses/gpl.html)
717e6d639SJames Collins * @author      James Collins <james.collins@outlook.com.au>
817e6d639SJames Collins */
917e6d639SJames Collinsif (!defined('DOKU_INC')) die();
1017e6d639SJames Collinsif (!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN', DOKU_INC . 'lib/plugins/');
1117e6d639SJames Collins
12*7935713eSJames Collinsdefine('MIKIO_LEXER_AUTO', 0);
13*7935713eSJames Collinsdefine('MIKIO_LEXER_ENTER', 1);
14*7935713eSJames Collinsdefine('MIKIO_LEXER_EXIT', 2);
15*7935713eSJames Collinsdefine('MIKIO_LEXER_SPECIAL', 3);
1617e6d639SJames Collins
17*7935713eSJames Collinsclass syntax_plugin_mikioplugin_core extends DokuWiki_Syntax_Plugin
18*7935713eSJames Collins{
1917e6d639SJames Collins    public $pattern_entry       = '';
203deaf3a5SJames Collins    public $pattern             = '';
2117e6d639SJames Collins    public $pattern_exit        = '';
2217e6d639SJames Collins    public $tag                 = '';
23*7935713eSJames Collins    public $hasEndTag           = true;
2417e6d639SJames Collins    public $options             = array();
25*7935713eSJames Collins
26*7935713eSJames Collins    protected $tagPrefix          = ''; //'mikio-';
27*7935713eSJames Collins    protected $classPrefix        = 'mikiop-';
28*7935713eSJames Collins    protected $elemClass          = 'mikiop';
29*7935713eSJames Collins
30*7935713eSJames Collins    private $values              = array();
3117e6d639SJames Collins
3217e6d639SJames Collins
33*7935713eSJames Collins    function __construct() { }
34*7935713eSJames Collins    public function getType() { return 'formatting'; }
35*7935713eSJames Collins    public function getAllowedTypes() { return array('formatting', 'substition', 'disabled', 'paragraphs'); }
36*7935713eSJames Collins    // public function getAllowedTypes() { return array('formatting', 'substition', 'disabled'); }
3717e6d639SJames Collins    public function getSort() { return 32; }
38*7935713eSJames Collins    public function getPType() { return 'stack'; }
3917e6d639SJames Collins
4017e6d639SJames Collins
41*7935713eSJames Collins    public function connectTo($mode)
42*7935713eSJames Collins    {
4317e6d639SJames Collins        if ($this->pattern_entry == '' && $this->tag != '') {
44*7935713eSJames Collins            if ($this->hasEndTag) {
45*7935713eSJames Collins                $this->pattern_entry = '<(?i:' . $this->tagPrefix . $this->tag . ')(?=[ >]).*?>(?=.*?</(?i:' . $this->tagPrefix . $this->tag . ')>)';
4617e6d639SJames Collins            } else {
47*7935713eSJames Collins                $this->pattern_entry = '<(?i:' . $this->tagPrefix . $this->tag . ').*?>';
4817e6d639SJames Collins            }
4917e6d639SJames Collins        }
5017e6d639SJames Collins
5117e6d639SJames Collins        if ($this->pattern_entry != '') {
52*7935713eSJames Collins            if ($this->hasEndTag) {
5317e6d639SJames Collins                $this->Lexer->addEntryPattern($this->pattern_entry, $mode, 'plugin_mikioplugin_' . $this->getPluginComponent());
54*7935713eSJames Collins            } else {
55*7935713eSJames Collins                $this->Lexer->addSpecialPattern($this->pattern_entry, $mode, 'plugin_mikioplugin_' . $this->getPluginComponent());
56*7935713eSJames Collins            }
5717e6d639SJames Collins        }
5817e6d639SJames Collins    }
593deaf3a5SJames Collins
6017e6d639SJames Collins
61*7935713eSJames Collins    public function postConnect()
62*7935713eSJames Collins    {
63*7935713eSJames Collins        if ($this->hasEndTag) {
6417e6d639SJames Collins            if ($this->pattern_exit == '' && $this->tag != '') {
65*7935713eSJames Collins                $this->pattern_exit = '</(?i:' . $this->tagPrefix . $this->tag . ')>';
6617e6d639SJames Collins            }
6717e6d639SJames Collins
6817e6d639SJames Collins            if ($this->pattern_exit != '') {
6917e6d639SJames Collins                $this->Lexer->addExitPattern($this->pattern_exit, 'plugin_mikioplugin_' . $this->getPluginComponent());
7017e6d639SJames Collins            }
7117e6d639SJames Collins        }
7217e6d639SJames Collins    }
7317e6d639SJames Collins
74*7935713eSJames Collins    public function handle($match, $state, $pos, Doku_Handler $handler)
75*7935713eSJames Collins    {
7617e6d639SJames Collins        switch ($state) {
7717e6d639SJames Collins            case DOKU_LEXER_ENTER:
7817e6d639SJames Collins            case DOKU_LEXER_SPECIAL:
79*7935713eSJames Collins                $optionlist = preg_split('/\s(?=([^"]*"[^"]*")*[^"]*$)/', trim(substr($match, strlen($this->tagPrefix . $this->tag) + 1, -1)));
8017e6d639SJames Collins
8117e6d639SJames Collins                $options = array();
8217e6d639SJames Collins                foreach ($optionlist as $item) {
8317e6d639SJames Collins                    $i = strpos($item, '=');
8417e6d639SJames Collins                    if ($i !== false) {
8517e6d639SJames Collins                        $value = substr($item, $i + 1);
8617e6d639SJames Collins
8717e6d639SJames Collins                        if (substr($value, 0, 1) == '"') $value = substr($value, 1);
8817e6d639SJames Collins                        if (substr($value, -1) == '"') $value = substr($value, 0, -1);
8917e6d639SJames Collins
9017e6d639SJames Collins                        $options[substr($item, 0, $i)] = $value;
9117e6d639SJames Collins                    } else {
9217e6d639SJames Collins                        $options[$item] = true;
9317e6d639SJames Collins                    }
9417e6d639SJames Collins                }
9517e6d639SJames Collins
96*7935713eSJames Collins                if(count($this->options) > 0) {
9731359b6fSJames Collins                    $options_clean = $this->cleanOptions($options);
98*7935713eSJames Collins                } else {
99*7935713eSJames Collins                    $options_clean = $options;
100*7935713eSJames Collins                }
10131359b6fSJames Collins
10231359b6fSJames Collins                $this->values = $options_clean;
10331359b6fSJames Collins
10431359b6fSJames Collins                return array($state, $options_clean);
10531359b6fSJames Collins
1063deaf3a5SJames Collins            case DOKU_LEXER_MATCHED:
1073deaf3a5SJames Collins                return array($state, $match);
1083deaf3a5SJames Collins
10931359b6fSJames Collins            case DOKU_LEXER_UNMATCHED:
11031359b6fSJames Collins                return array($state, $match);
11131359b6fSJames Collins
11231359b6fSJames Collins            case DOKU_LEXER_EXIT:
113f4aa5cdcSJames Collins                return array($state, $this->values);
11431359b6fSJames Collins        }
11531359b6fSJames Collins
11631359b6fSJames Collins        return array();
11731359b6fSJames Collins    }
11831359b6fSJames Collins
11931359b6fSJames Collins
120*7935713eSJames Collins    /*
121*7935713eSJames Collins    * clean element options to only supported attributes, setting defaults if required
122*7935713eSJames Collins    *
123*7935713eSJames Collins    * @param $options   options passed to element
124*7935713eSJames Collins    * @return           array of options supported with default set
125*7935713eSJames Collins    */
126*7935713eSJames Collins    protected function cleanOptions($data, $options=null)
127*7935713eSJames Collins    {
128*7935713eSJames Collins        $optionsCleaned = array();
12931359b6fSJames Collins
130*7935713eSJames Collins        if($options == null) $options = $this->options;
131*7935713eSJames Collins
132*7935713eSJames Collins        // Match DokuWiki passed options to syntax options
133*7935713eSJames Collins        foreach ($data as $optionKey => $optionValue) {
134*7935713eSJames Collins            foreach ($options as $syntaxKey => $syntaxValue) {
135*7935713eSJames Collins                if (strcasecmp($optionKey, $syntaxKey) == 0) {
136*7935713eSJames Collins                    if (array_key_exists('type', $options[$syntaxKey])) {
137*7935713eSJames Collins                        $type = $options[$syntaxKey]['type'];
138*7935713eSJames Collins
139*7935713eSJames Collins                        switch ($type) {
140*7935713eSJames Collins                            case 'boolean':
141*7935713eSJames Collins                                $optionsCleaned[$syntaxKey] = filter_var($optionValue, FILTER_VALIDATE_BOOLEAN);
142*7935713eSJames Collins                                break;
143*7935713eSJames Collins                            case 'number':
144*7935713eSJames Collins                                $optionsCleaned[$syntaxKey] = filter_var($optionValue, FILTER_VALIDATE_INT);
145*7935713eSJames Collins                                break;
146*7935713eSJames Collins                            case 'float':
147*7935713eSJames Collins                                $optionsCleaned[$syntaxKey] = filter_var($optionValue, FILTER_VALIDATE_FLOAT);
148*7935713eSJames Collins                                break;
149*7935713eSJames Collins                            case 'text':
150*7935713eSJames Collins                                $optionsCleaned[$syntaxKey] = $optionValue;
151*7935713eSJames Collins                                break;
152*7935713eSJames Collins                            case 'size':
153*7935713eSJames Collins                                $s = strtolower($optionValue);
154*7935713eSJames Collins                                $i = '';
155*7935713eSJames Collins                                if (substr($s, -3) == 'rem') {
156*7935713eSJames Collins                                    $i = substr($s, 0, -3);
157*7935713eSJames Collins                                    $s = 'rem';
158*7935713eSJames Collins                                } elseif (substr($s, -2) == 'em') {
159*7935713eSJames Collins                                    $i = substr($s, 0, -2);
160*7935713eSJames Collins                                    $s = 'em';
161*7935713eSJames Collins                                }
162*7935713eSJames Collins                                elseif (substr($s, -2) == 'px') {
163*7935713eSJames Collins                                    $i = substr($s, 0, -2);
164*7935713eSJames Collins                                    $s = 'px';
165*7935713eSJames Collins                                }
166*7935713eSJames Collins                                elseif (substr($s, -1) == '%') {
167*7935713eSJames Collins                                    $i = substr($s, 0, -1);
168*7935713eSJames Collins                                    $s = '%';
169*7935713eSJames Collins                                }
170*7935713eSJames Collins                                else {
171*7935713eSJames Collins                                    $i = filter_var($s, FILTER_VALIDATE_INT);
172*7935713eSJames Collins                                    if ($i == '') $i = '1';
173*7935713eSJames Collins                                    $s = 'rem';
174*7935713eSJames Collins                                }
175*7935713eSJames Collins
176*7935713eSJames Collins                                $optionsCleaned[$syntaxKey] = $i . $s;
177*7935713eSJames Collins                                break;
178*7935713eSJames Collins                            case 'color':
179*7935713eSJames Collins                                if (strlen($optionValue) == 3 || strlen($optionValue) == 6) {
180*7935713eSJames Collins                                    preg_match('/([[:xdigit:]]{3}){1,2}/', $optionValue, $matches);
181*7935713eSJames Collins                                    if (count($matches) > 1) {
182*7935713eSJames Collins                                        $optionsCleaned[$syntaxKey] = '#' . $matches[0];
183*7935713eSJames Collins                                    }
18417e6d639SJames Collins                                } else {
185*7935713eSJames Collins                                    $optionsCleaned[$syntaxKey] = $optionValue;
18617e6d639SJames Collins                                }
187*7935713eSJames Collins                                break;
188*7935713eSJames Collins                            case 'url':
189*7935713eSJames Collins                                $optionsCleaned[$syntaxKey] = $this->buildLink($optionValue);
190*7935713eSJames Collins                                break;
191*7935713eSJames Collins                            case 'media':
192*7935713eSJames Collins                                $optionsCleaned[$syntaxKey] = $this->buildMediaLink($optionValue);
193*7935713eSJames Collins                                break;
194*7935713eSJames Collins                            case 'choice':
195*7935713eSJames Collins                                if (array_key_exists('data', $options[$syntaxKey])) {
196*7935713eSJames Collins                                    foreach ($options[$syntaxKey]['data'] as $choiceKey => $choiceValue) {
197*7935713eSJames Collins                                        if (is_array($choiceValue)) {
198*7935713eSJames Collins                                            foreach ($choiceValue as $choiceItem) {
199*7935713eSJames Collins                                                if (strcasecmp($optionValue, $choiceItem) == 0) {
200*7935713eSJames Collins                                                    $optionsCleaned[$syntaxKey] = $choiceKey;
201*7935713eSJames Collins                                                    break 2;
20217e6d639SJames Collins                                                }
20317e6d639SJames Collins                                            }
204ebb7bc5aSJames Collins                                        } else {
205*7935713eSJames Collins                                            if (strcasecmp($optionValue, $choiceValue) == 0) {
206*7935713eSJames Collins                                                $optionsCleaned[$syntaxKey] = $choiceValue;
207*7935713eSJames Collins                                                break;
208*7935713eSJames Collins                                            }
209*7935713eSJames Collins                                        }
210*7935713eSJames Collins                                    }
211*7935713eSJames Collins                                }
212*7935713eSJames Collins                                break;
213*7935713eSJames Collins                            case 'set':
214*7935713eSJames Collins                                if (array_key_exists('option', $options[$syntaxKey]) && array_key_exists('data', $options[$syntaxKey])) {
215*7935713eSJames Collins                                    $optionsCleaned[$options[$syntaxKey]['option']] = $options[$syntaxKey]['data'];
216*7935713eSJames Collins                                }
217*7935713eSJames Collins                                break;
218*7935713eSJames Collins                        }
219ebb7bc5aSJames Collins                    }
22017e6d639SJames Collins
221*7935713eSJames Collins                    break;
222*7935713eSJames Collins                } else {
223*7935713eSJames Collins                    if (array_key_exists('type', $options[$syntaxKey]) && $options[$syntaxKey]['type'] == 'choice' && array_key_exists('data', $options[$syntaxKey])) {
224*7935713eSJames Collins                        foreach ($options[$syntaxKey]['data'] as $choiceKey => $choiceValue) {
225*7935713eSJames Collins                            if (is_array($choiceValue)) {
226*7935713eSJames Collins                                foreach ($choiceValue as $choiceItem) {
227*7935713eSJames Collins                                    if (strcasecmp($optionKey, $choiceItem) == 0) {
228*7935713eSJames Collins                                        $optionsCleaned[$syntaxKey] = $choiceKey;
229*7935713eSJames Collins                                        break 2;
230*7935713eSJames Collins                                    }
231*7935713eSJames Collins                                }
232*7935713eSJames Collins                            } else {
233*7935713eSJames Collins                                if (strcasecmp($optionKey, $choiceValue) == 0) {
234*7935713eSJames Collins                                    $optionsCleaned[$syntaxKey] = $choiceValue;
235*7935713eSJames Collins                                    break;
236*7935713eSJames Collins                                }
237*7935713eSJames Collins                            }
238*7935713eSJames Collins                        }
239*7935713eSJames Collins                    }
240*7935713eSJames Collins                }
241*7935713eSJames Collins            }
24217e6d639SJames Collins        }
24317e6d639SJames Collins
244*7935713eSJames Collins        // Add in syntax options that are missing
245*7935713eSJames Collins        foreach ($options as $optionKey => $optionValue) {
246*7935713eSJames Collins            if (!array_key_exists($optionKey, $optionsCleaned)) {
247*7935713eSJames Collins                if (array_key_exists('default', $options[$optionKey])) {
248*7935713eSJames Collins                    switch ($options[$optionKey]['type']) {
249*7935713eSJames Collins                        case 'boolean':
250*7935713eSJames Collins                            $optionsCleaned[$optionKey] = filter_var($options[$optionKey]['default'], FILTER_VALIDATE_BOOLEAN);
251*7935713eSJames Collins                            break;
252*7935713eSJames Collins                        case 'number':
253*7935713eSJames Collins                            $optionsCleaned[$optionKey] = filter_var($options[$optionKey]['default'], FILTER_VALIDATE_INT);
254*7935713eSJames Collins                            break;
255*7935713eSJames Collins                        default:
256*7935713eSJames Collins                            $optionsCleaned[$optionKey] = $options[$optionKey]['default'];
257*7935713eSJames Collins                            break;
258*7935713eSJames Collins                    }
259*7935713eSJames Collins                }
260*7935713eSJames Collins            }
26117e6d639SJames Collins        }
26217e6d639SJames Collins
263*7935713eSJames Collins        return $optionsCleaned;
26417e6d639SJames Collins    }
26517e6d639SJames Collins
266*7935713eSJames Collins    /* Lexer renderers */
267*7935713eSJames Collins    protected function render_lexer_enter(Doku_Renderer $renderer, $data) { }
268*7935713eSJames Collins    protected function render_lexer_unmatched(Doku_Renderer $renderer, $data) { $renderer->doc .= $renderer->_xmlEntities($data); }
269*7935713eSJames Collins    protected function render_lexer_exit(Doku_Renderer $renderer, $data) { }
270*7935713eSJames Collins    protected function render_lexer_special(Doku_Renderer $renderer, $data) { }
271*7935713eSJames Collins    protected function render_lexer_match(Doku_Renderer $renderer, $data) { }
27217e6d639SJames Collins
273*7935713eSJames Collins    /* Renderer */
274*7935713eSJames Collins    public function render($mode, Doku_Renderer $renderer, $data)
275*7935713eSJames Collins    {
27617e6d639SJames Collins        if ($mode == 'xhtml') {
27717e6d639SJames Collins            list($state, $match) = $data;
27817e6d639SJames Collins
27917e6d639SJames Collins            switch ($state) {
28017e6d639SJames Collins                case DOKU_LEXER_ENTER:
28117e6d639SJames Collins                    $this->render_lexer_enter($renderer, $match);
28217e6d639SJames Collins                    return true;
28317e6d639SJames Collins
28417e6d639SJames Collins                case DOKU_LEXER_UNMATCHED:
28517e6d639SJames Collins                    $this->render_lexer_unmatched($renderer, $match);
28617e6d639SJames Collins                    return true;
28717e6d639SJames Collins
2883deaf3a5SJames Collins                case DOKU_LEXER_MATCHED:
2893deaf3a5SJames Collins                    $this->render_lexer_match($renderer, $match);
2903deaf3a5SJames Collins                    return true;
2913deaf3a5SJames Collins
29217e6d639SJames Collins                case DOKU_LEXER_EXIT:
29317e6d639SJames Collins                    $this->render_lexer_exit($renderer, $match);
29417e6d639SJames Collins                    return true;
29517e6d639SJames Collins
29617e6d639SJames Collins                case DOKU_LEXER_SPECIAL:
29717e6d639SJames Collins                    $this->render_lexer_special($renderer, $match);
29817e6d639SJames Collins                    return true;
29917e6d639SJames Collins            }
30017e6d639SJames Collins
30117e6d639SJames Collins            return true;
30217e6d639SJames Collins        }
30317e6d639SJames Collins
30417e6d639SJames Collins        return false;
30517e6d639SJames Collins    }
30617e6d639SJames Collins
307*7935713eSJames Collins    /*
308*7935713eSJames Collins    * return a class list with mikiop- prefix
309*7935713eSJames Collins    *
310*7935713eSJames Collins    * @param $options       options of syntax element. Options with key 'class'=true are automatically added
311*7935713eSJames Collins    * @param $classes       classes to build from options as array
312*7935713eSJames Collins    * @param $inclAttr      include class="" in the return string
313*7935713eSJames Collins    * @return               a string of classes from options/classes variable
314*7935713eSJames Collins    */
315*7935713eSJames Collins    public function buildClass($options = null, $classes = null, $inclAttr = false)
316*7935713eSJames Collins    {
31717e6d639SJames Collins        $s = array();
31817e6d639SJames Collins
319*7935713eSJames Collins        if (is_array($options)) {
320*7935713eSJames Collins            if($classes == null) $classes = array();
32117e6d639SJames Collins
322*7935713eSJames Collins            foreach($this->options as $key => $value) {
323*7935713eSJames Collins                if(array_key_exists('class', $value) && $value['class'] == TRUE) {
324*7935713eSJames Collins                    array_push($classes, $key);
32517e6d639SJames Collins                }
32617e6d639SJames Collins            }
32717e6d639SJames Collins
328*7935713eSJames Collins            foreach ($classes as $class) {
329*7935713eSJames Collins                if (array_key_exists($class, $options) && $options[$class] !== FALSE && $options[$class] != '') {
330*7935713eSJames Collins                    $prefix = $this->classPrefix;
331*7935713eSJames Collins
332*7935713eSJames Collins                    if (array_key_exists($class, $this->options) && array_key_exists('prefix', $this->options[$class])) {
333*7935713eSJames Collins                        $prefix .= $this->options[$class]['prefix'];
33417e6d639SJames Collins                    }
335*7935713eSJames Collins
336*7935713eSJames Collins                    $s[] = $prefix . $class . ($options[$class] !== TRUE ? '-' . $options[$class] : '');
33717e6d639SJames Collins                }
33817e6d639SJames Collins            }
33917e6d639SJames Collins
340a007b54fSJames Collins        }
34117e6d639SJames Collins
342*7935713eSJames Collins        $s = implode(' ', $s);
343*7935713eSJames Collins        if($s != '') $s = ' ' . $s;
3448f786230SJames Collins
345*7935713eSJames Collins        if($inclAttr) $s = ' classes="' . $s . '"';
3466cfe6dadSJames Collins
347ad1dae96SJames Collins        return $s;
348ad1dae96SJames Collins    }
34917e6d639SJames Collins
350*7935713eSJames Collins
351*7935713eSJames Collins
352*7935713eSJames Collins
353*7935713eSJames Collins    /*
354*7935713eSJames Collins    * build style string
355*7935713eSJames Collins    *
356*7935713eSJames Collins    * @param $list          style list as key => value. Empty values are not included
357*7935713eSJames Collins    * @param $inclAttr      include style="" in the return string
358*7935713eSJames Collins    * @return               style list string
359*7935713eSJames Collins    */
360*7935713eSJames Collins    public function buildStyle($list, $inclAttr = false)
361*7935713eSJames Collins    {
362*7935713eSJames Collins        $s = '';
363*7935713eSJames Collins
364*7935713eSJames Collins        if (is_array($list) && count($list) > 0) {
365*7935713eSJames Collins            foreach ($list as $key => $value) {
366*7935713eSJames Collins                if($value != '') {
367*7935713eSJames Collins                    $s .= $key . ':' . $value . ';';
368*7935713eSJames Collins                }
369*7935713eSJames Collins            }
370*7935713eSJames Collins        }
371*7935713eSJames Collins
372*7935713eSJames Collins        if($s != '' && $inclAttr) {
373*7935713eSJames Collins            $s = ' style="' . $s . '"';
374*7935713eSJames Collins        }
375*7935713eSJames Collins
376*7935713eSJames Collins        return $s;
377*7935713eSJames Collins    }
378*7935713eSJames Collins
379*7935713eSJames Collins
380*7935713eSJames Collins    public function buildTooltipString($options)
381*7935713eSJames Collins    {
382a401c3b7SJames Collins        $dataPlacement = 'top';
383a401c3b7SJames Collins        $dataHtml = false;
384a401c3b7SJames Collins        $title = '';
385a401c3b7SJames Collins
386a401c3b7SJames Collins        if ($options != null) {
387a401c3b7SJames Collins            if (array_key_exists('tooltip-html-top', $options) && $options['tooltip-html-top'] != '') {
388a401c3b7SJames Collins                $title = $options['tooltip-html-top'];
389a401c3b7SJames Collins                $dataPlacement = 'top';
390a401c3b7SJames Collins            }
391a401c3b7SJames Collins
392a401c3b7SJames Collins            if (array_key_exists('tooltip-html-left', $options) && $options['tooltip-html-left'] != '') {
393a401c3b7SJames Collins                $title = $options['tooltip-html-left'];
394a401c3b7SJames Collins                $dataPlacement = 'left';
395a401c3b7SJames Collins            }
396a401c3b7SJames Collins
397a401c3b7SJames Collins            if (array_key_exists('tooltip-html-bottom', $options) && $options['tooltip-html-bottom'] != '') {
398a401c3b7SJames Collins                $title = $options['tooltip-html-bottom'];
399a401c3b7SJames Collins                $dataPlacement = 'bottom';
400a401c3b7SJames Collins            }
401a401c3b7SJames Collins
402a401c3b7SJames Collins            if (array_key_exists('tooltip-html-right', $options) && $options['tooltip-html-right'] != '') {
403a401c3b7SJames Collins                $title = $options['tooltip-html-right'];
404a401c3b7SJames Collins                $dataPlacement = 'right';
405a401c3b7SJames Collins            }
406a401c3b7SJames Collins
407a401c3b7SJames Collins            if (array_key_exists('tooltip-top', $options) && $options['tooltip-top'] != '') {
408a401c3b7SJames Collins                $title = $options['tooltip-top'];
409a401c3b7SJames Collins                $dataPlacement = 'top';
410a401c3b7SJames Collins            }
411a401c3b7SJames Collins
412a401c3b7SJames Collins            if (array_key_exists('tooltip-left', $options) && $options['tooltip-left'] != '') {
413a401c3b7SJames Collins                $title = $options['tooltip-left'];
414a401c3b7SJames Collins                $dataPlacement = 'left';
415a401c3b7SJames Collins            }
416a401c3b7SJames Collins
417a401c3b7SJames Collins            if (array_key_exists('tooltip-bottom', $options) && $options['tooltip-bottom'] != '') {
418a401c3b7SJames Collins                $title = $options['tooltip-bottom'];
419a401c3b7SJames Collins                $dataPlacement = 'bottom';
420a401c3b7SJames Collins            }
421a401c3b7SJames Collins
422a401c3b7SJames Collins            if (array_key_exists('tooltip-right', $options) && $options['tooltip-right'] != '') {
423a401c3b7SJames Collins                $title = $options['tooltip-right'];
424a401c3b7SJames Collins                $dataPlacement = 'right';
425a401c3b7SJames Collins            }
426a401c3b7SJames Collins
427a401c3b7SJames Collins            if (array_key_exists('tooltip-html', $options) && $options['tooltip-html'] != '') {
428a401c3b7SJames Collins                $title = $options['tooltip-html'];
429a401c3b7SJames Collins                $dataPlacement = 'top';
430a401c3b7SJames Collins            }
431a401c3b7SJames Collins
432a401c3b7SJames Collins            if (array_key_exists('tooltip', $options) && $options['tooltip'] != '') {
433a401c3b7SJames Collins                $title = $options['tooltip'];
434a401c3b7SJames Collins                $dataPlacement = 'top';
435a401c3b7SJames Collins            }
436a401c3b7SJames Collins        }
437a401c3b7SJames Collins
438a401c3b7SJames Collins        if ($title != '') {
439a401c3b7SJames Collins            return ' data-toggle="tooltip" data-placement="' . $dataPlacement . '" ' . ($dataHtml == true ? 'data-html="true" ' : '') . 'title="' . $title . '" ';
440a401c3b7SJames Collins        }
441a401c3b7SJames Collins
442a401c3b7SJames Collins        return '';
443a401c3b7SJames Collins    }
444a401c3b7SJames Collins
445*7935713eSJames Collins    /*
446*7935713eSJames Collins    * convert the URL to a DokuWiki media link (if required)
447*7935713eSJames Collins    *
448*7935713eSJames Collins    * @param $url   url to parse
449*7935713eSJames Collins    * @return       url string
450*7935713eSJames Collins    */
451*7935713eSJames Collins    public function buildMediaLink($url)
452*7935713eSJames Collins    {
453*7935713eSJames Collins        $i = strpos($url, '?');
454*7935713eSJames Collins        if ($i !== FALSE) $url = substr($url, 0, $i);
45517e6d639SJames Collins
456*7935713eSJames Collins        $url = preg_replace('/[^\da-zA-Z:_.]+/', '', $url);
45717e6d639SJames Collins
458*7935713eSJames Collins        return (tpl_getMediaFile(array($url), FALSE));
45917e6d639SJames Collins    }
46017e6d639SJames Collins
46117e6d639SJames Collins
462*7935713eSJames Collins    /*
463*7935713eSJames Collins    * returns either a url or dokuwiki link
464*7935713eSJames Collins    *
465*7935713eSJames Collins    * @param    $url    link to build from
466*7935713eSJames Collins    * @return           built link
467*7935713eSJames Collins    */
468*7935713eSJames Collins    public function buildLink($url)
469*7935713eSJames Collins    {
470*7935713eSJames Collins        $i = strpos($url, '://');
471*7935713eSJames Collins        if ($i !== FALSE) return $url;
472f1a539d8SJames Collins
473*7935713eSJames Collins        return wl($url);
474f1a539d8SJames Collins    }
475f1a539d8SJames Collins
476f1a539d8SJames Collins
47717e6d639SJames Collins
47817e6d639SJames Collins
47917e6d639SJames Collins
48017e6d639SJames Collins
481*7935713eSJames Collins    /*
482*7935713eSJames Collins    * Call syntax renderer of mikio syntax plugin
483*7935713eSJames Collins    *
484*7935713eSJames Collins    * @param $renderer          DokuWiki renderer object
485*7935713eSJames Collins    * @param $className         mikio syntax class to call
486*7935713eSJames Collins    * @param $text              unmatched text to pass outside of lexer. Only used when $lexer=MIKIO_LEXER_AUTO
487*7935713eSJames Collins    * @param $data              tag options to pass to syntax class. Runs through cleanOptions to validate first
488*7935713eSJames Collins    * @param $lexer             which lexer to call
489*7935713eSJames Collins    */
490*7935713eSJames Collins    public function syntaxRender(Doku_Renderer $renderer, $className, $text, $data = null, $lexer = MIKIO_LEXER_AUTO)
491*7935713eSJames Collins    {
492*7935713eSJames Collins        $className = 'syntax_plugin_mikioplugin_'.$className;
493*7935713eSJames Collins
494*7935713eSJames Collins        if(class_exists($className)) {
49517e6d639SJames Collins            $class = new $className;
49617e6d639SJames Collins
49731359b6fSJames Collins            if (!is_array($data)) $data = array();
49831359b6fSJames Collins
499*7935713eSJames Collins            if(count($class->options) > 0) {
50031359b6fSJames Collins                $data = $class->cleanOptions($data);
501*7935713eSJames Collins            }
50231359b6fSJames Collins
503*7935713eSJames Collins            switch($lexer) {
504*7935713eSJames Collins                case MIKIO_LEXER_AUTO:
505*7935713eSJames Collins                    if ($class->hasEndTag) {
506*7935713eSJames Collins                        if(method_exists($class, 'render_lexer_enter')) $class->render_lexer_enter($renderer, $data);
50717e6d639SJames Collins                        $renderer->doc .= $text;
508*7935713eSJames Collins                        if(method_exists($class, 'render_lexer_exit')) $class->render_lexer_exit($renderer, $data);
509*7935713eSJames Collins                    } else {
510*7935713eSJames Collins                        if(method_exists($class, 'render_lexer_special')) $class->render_lexer_special($renderer, $data);
511*7935713eSJames Collins                    }
512*7935713eSJames Collins
513*7935713eSJames Collins                    break;
514*7935713eSJames Collins                case MIKIO_LEXER_ENTER:
515*7935713eSJames Collins                    if(method_exists($class, 'render_lexer_enter')) $class->render_lexer_enter($renderer, $data);
516*7935713eSJames Collins                    break;
517*7935713eSJames Collins                case MIKIO_LEXER_EXIT:
518*7935713eSJames Collins                    if(method_exists($class, 'render_lexer_exit')) $class->render_lexer_exit($renderer, $data);
519*7935713eSJames Collins                    break;
520*7935713eSJames Collins                case MIKIO_LEXER_SPECIAL:
521*7935713eSJames Collins                    if(method_exists($class, 'render_lexer_special')) $class->render_lexer_special($renderer, $data);
522*7935713eSJames Collins                    break;
523*7935713eSJames Collins            }
52417e6d639SJames Collins        }
52517e6d639SJames Collins    }
526ebb7bc5aSJames Collins
527*7935713eSJames Collins    /*
528*7935713eSJames Collins    * Create array with passed elements and include them if their values are not empty
529*7935713eSJames Collins    *
530*7935713eSJames Collins    * @param ...        array items
531*7935713eSJames Collins    */
532*7935713eSJames Collins    protected function arrayRemoveEmpties($items) {
533*7935713eSJames Collins        $result = array();
534*7935713eSJames Collins
535*7935713eSJames Collins        foreach($items as $key => $value) {
536*7935713eSJames Collins            if($value != '') {
537*7935713eSJames Collins                $result[$key] = $value;
538*7935713eSJames Collins            }
539*7935713eSJames Collins        }
540*7935713eSJames Collins
541*7935713eSJames Collins        return $result;
542*7935713eSJames Collins    }
543*7935713eSJames Collins
544*7935713eSJames Collins    public function getFirstArrayKey($data)
545*7935713eSJames Collins    {
546ebb7bc5aSJames Collins        if (!function_exists('array_key_first')) {
547ebb7bc5aSJames Collins            foreach ($data as $key => $unused) {
548ebb7bc5aSJames Collins                return $key;
549ebb7bc5aSJames Collins            }
550ebb7bc5aSJames Collins        }
551ebb7bc5aSJames Collins
552ebb7bc5aSJames Collins        return array_key_first($data);
553ebb7bc5aSJames Collins    }
554*7935713eSJames Collins
555*7935713eSJames Collins
556*7935713eSJames Collins    /*
557*7935713eSJames Collins    * add common options to options
558*7935713eSJames Collins    *
559*7935713eSJames Collins    * @param $typelist      common option to add
560*7935713eSJames Collins    * @param $options   save in options
561*7935713eSJames Collins    */
562*7935713eSJames Collins    public function addCommonOptions($typelist) {
563*7935713eSJames Collins        $types = explode(' ', $typelist);
564*7935713eSJames Collins        foreach($types as $type) {
565*7935713eSJames Collins            if(strcasecmp($type, 'shadow') == 0) {
566*7935713eSJames Collins                $this->options['shadow'] =          array('type'     => 'choice',
567*7935713eSJames Collins                                                          'data'     => array('large'=> array('shadow-large', 'shadow-lg'), 'small' => array('shadow-small', 'shadow-sm'), true),
568*7935713eSJames Collins                                                          'default'  => '',
569*7935713eSJames Collins                                                          'class'    => true);
570*7935713eSJames Collins            }
571*7935713eSJames Collins
572*7935713eSJames Collins            if(strcasecmp($type, 'width') == 0) {
573*7935713eSJames Collins                $this->options['width'] =           array('type'     => 'size',
574*7935713eSJames Collins                                                          'default'  => '');
575*7935713eSJames Collins            }
576*7935713eSJames Collins
577*7935713eSJames Collins            if(strcasecmp($type, 'height') == 0) {
578*7935713eSJames Collins                $this->options['height'] =          array('type'     => 'size',
579*7935713eSJames Collins                                                          'default'  => '');
580*7935713eSJames Collins            }
581*7935713eSJames Collins
582*7935713eSJames Collins            if(strcasecmp($type, 'type') == 0) {
583*7935713eSJames Collins                $this->options['type'] =            array('type'     => 'choice',
584*7935713eSJames Collins                                                          'data'     => array('primary', 'secondary', 'success', 'danger', 'warning', 'info', 'light', 'dark'),
585*7935713eSJames Collins                                                          'default'  => '',
586*7935713eSJames Collins                                                          'class'    => true);
587*7935713eSJames Collins            }
588*7935713eSJames Collins
589*7935713eSJames Collins            if(strcasecmp($type, 'text-align') == 0) {
590*7935713eSJames Collins                $this->options['text-align'] =      array('type'     => 'choice',
591*7935713eSJames Collins                                                          'data'     => array('left' => array('text-left'), 'center' => array('text-center'), 'right' => array('text-right')),
592*7935713eSJames Collins                                                          'default'  => '',
593*7935713eSJames Collins                                                          'class'    => true);
594*7935713eSJames Collins            }
595*7935713eSJames Collins
596*7935713eSJames Collins            if(strcasecmp($type, 'align') == 0) {
597*7935713eSJames Collins                $this->options['align'] =           array('type'     => 'choice',
598*7935713eSJames Collins                                                          'data'     => array('left' => array('align-left'), 'center' => array('align-center'), 'right' => array('align-right')),
599*7935713eSJames Collins                                                          'default'  => '',
600*7935713eSJames Collins                                                          'class'    => true);
601*7935713eSJames Collins            }
602*7935713eSJames Collins        }
603*7935713eSJames Collins    }
604*7935713eSJames Collins
605*7935713eSJames Collins
606*7935713eSJames Collins    /*
607*7935713eSJames Collins    * Find HTML tags in string. Parse tags options. Used in parsing subtags
608*7935713eSJames Collins    *
609*7935713eSJames Collins    * @param $tagName       tagName to search for. Name is exclusive
610*7935713eSJames Collins    * @param $content       search within content
611*7935713eSJames Collins    * @param $options       parse options similar to syntax element options
612*7935713eSJames Collins    * @return               array of tags containing 'options' => array of 'name' => 'value', 'content' => content inside the tag
613*7935713eSJames Collins    */
614*7935713eSJames Collins    protected function findTags($tagName, $content, $options) {
615*7935713eSJames Collins        $items = array();
616*7935713eSJames Collins
617*7935713eSJames Collins        if(preg_match_all('/<(?i:' . $tagName . ')(.*?)>(.*?)<\/(?i:' . $tagName . ')>/s', $content, $match)) {
618*7935713eSJames Collins            if(count($match) >= 2) {
619*7935713eSJames Collins                for($i = 0; $i < count($match[1]); $i++) {
620*7935713eSJames Collins                    $item = array('options' => array(), 'content' => $this->render_text($match[2][$i]));
621*7935713eSJames Collins
622*7935713eSJames Collins                    $optionlist = preg_split('/\s(?=([^"]*"[^"]*")*[^"]*$)/', trim($match[1][$i]));
623*7935713eSJames Collins
624*7935713eSJames Collins                    foreach ($optionlist as $option) {
625*7935713eSJames Collins                        $j = strpos($option, '=');
626*7935713eSJames Collins                        if ($j !== false) {
627*7935713eSJames Collins                            $value = substr($option, $j + 1);
628*7935713eSJames Collins
629*7935713eSJames Collins                            if (substr($value, 0, 1) == '"') $value = substr($value, 1);
630*7935713eSJames Collins                            if (substr($value, -1) == '"') $value = substr($value, 0, -1);
631*7935713eSJames Collins
632*7935713eSJames Collins                            $item['options'][substr($option, 0, $j)] = $value;
633*7935713eSJames Collins                        } else {
634*7935713eSJames Collins                            $item['options'][$option] = true;
635*7935713eSJames Collins                        }
636*7935713eSJames Collins                    }
637*7935713eSJames Collins
638*7935713eSJames Collins                    $this->cleanOptions($item['options'], $options);
639*7935713eSJames Collins
640*7935713eSJames Collins                    $items[] = $item;
641*7935713eSJames Collins                }
642*7935713eSJames Collins            }
643*7935713eSJames Collins        }
644*7935713eSJames Collins
645*7935713eSJames Collins        return $items;
646*7935713eSJames Collins    }
64731359b6fSJames Collins}