xref: /plugin/mikioplugin/syntax/core.php (revision 7f46de55f8445ea175d26da79ef2c8de5796cf57)
117e6d639SJames Collins<?php
20e73f855Snomadjimbob
317e6d639SJames Collins/**
417e6d639SJames Collins * Mikio Core Syntax Plugin
517e6d639SJames Collins *
67935713eSJames Collins * @link    http://github.com/nomadjimbob/mikioplugin
717e6d639SJames Collins * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
817e6d639SJames Collins * @author  James Collins <james.collins@outlook.com.au>
917e6d639SJames Collins */
10b007ca42SJames Collinsif (!defined('DOKU_INC')) { die();
11b007ca42SJames Collins}
12b007ca42SJames Collinsif (!defined('DOKU_PLUGIN')) { define('DOKU_PLUGIN', DOKU_INC . 'lib/plugins/');
13b007ca42SJames Collins}
1417e6d639SJames Collins
15*7f46de55SJames Collinsrequire_once(dirname(__FILE__).'/../disabled-tags.php');
16*7f46de55SJames Collins
177935713eSJames Collinsdefine('MIKIO_LEXER_AUTO', 0);
187935713eSJames Collinsdefine('MIKIO_LEXER_ENTER', 1);
197935713eSJames Collinsdefine('MIKIO_LEXER_EXIT', 2);
207935713eSJames Collinsdefine('MIKIO_LEXER_SPECIAL', 3);
2117e6d639SJames Collins
227935713eSJames Collinsclass syntax_plugin_mikioplugin_core extends DokuWiki_Syntax_Plugin
237935713eSJames Collins{
2417e6d639SJames Collins    public $pattern_entry       = '';
253deaf3a5SJames Collins    public $pattern             = '';
2617e6d639SJames Collins    public $pattern_exit        = '';
2717e6d639SJames Collins    public $tag                 = '';
28*7f46de55SJames Collins    public $requires_tag        = '';
297935713eSJames Collins    public $hasEndTag           = true;
3017e6d639SJames Collins    public $options             = array();
317935713eSJames Collins
327935713eSJames Collins    protected $tagPrefix          = ''; //'mikio-';
337935713eSJames Collins    protected $classPrefix        = 'mikiop-';
347935713eSJames Collins    protected $elemClass          = 'mikiop';
357935713eSJames Collins
367935713eSJames Collins    private $values              = array();
3717e6d639SJames Collins
3817e6d639SJames Collins
390e73f855Snomadjimbob    function __construct()
400e73f855Snomadjimbob    {
41*7f46de55SJames Collins        global $mikio_disabled_tags;
42*7f46de55SJames Collins
43*7f46de55SJames Collins        if (isset($mikio_disabled_tags) === true) {
44*7f46de55SJames Collins            if(array_key_exists($this->tag, $mikio_disabled_tags) === true && $mikio_disabled_tags[$this->tag] === false) {
45*7f46de55SJames Collins                $this->tag = '';
46*7f46de55SJames Collins            }
47*7f46de55SJames Collins
48*7f46de55SJames Collins            // check requirements
49*7f46de55SJames Collins            if($this->requires_tag !== '') {
50*7f46de55SJames Collins                if(array_key_exists($this->tag, $this->requires_tag) === true && $mikio_disabled_tags[$this->requires_tag] === false) {
51*7f46de55SJames Collins                    $this->tag = '';
52*7f46de55SJames Collins                }
53*7f46de55SJames Collins            }
54*7f46de55SJames Collins        }
550e73f855Snomadjimbob    }
560e73f855Snomadjimbob    public function getType()
570e73f855Snomadjimbob    {
580e73f855Snomadjimbob        return 'formatting';
590e73f855Snomadjimbob    }
600e73f855Snomadjimbob    public function getAllowedTypes()
610e73f855Snomadjimbob    {
620e73f855Snomadjimbob        return array('formatting', 'substition', 'disabled', 'paragraphs');
630e73f855Snomadjimbob    }
647935713eSJames Collins    // public function getAllowedTypes() { return array('formatting', 'substition', 'disabled'); }
650e73f855Snomadjimbob    public function getSort()
660e73f855Snomadjimbob    {
670e73f855Snomadjimbob        return 32;
680e73f855Snomadjimbob    }
690e73f855Snomadjimbob    public function getPType()
700e73f855Snomadjimbob    {
710e73f855Snomadjimbob        return 'stack';
720e73f855Snomadjimbob    }
7317e6d639SJames Collins
7417e6d639SJames Collins
757935713eSJames Collins    public function connectTo($mode)
767935713eSJames Collins    {
7717e6d639SJames Collins        if ($this->pattern_entry == '' && $this->tag != '') {
787935713eSJames Collins            if ($this->hasEndTag) {
797935713eSJames Collins                $this->pattern_entry = '<(?i:' . $this->tagPrefix . $this->tag . ')(?=[ >]).*?>(?=.*?</(?i:' . $this->tagPrefix . $this->tag . ')>)';
8017e6d639SJames Collins            } else {
817935713eSJames Collins                $this->pattern_entry = '<(?i:' . $this->tagPrefix . $this->tag . ').*?>';
8217e6d639SJames Collins            }
8317e6d639SJames Collins        }
8417e6d639SJames Collins
8517e6d639SJames Collins        if ($this->pattern_entry != '') {
867935713eSJames Collins            if ($this->hasEndTag) {
8717e6d639SJames Collins                $this->Lexer->addEntryPattern($this->pattern_entry, $mode, 'plugin_mikioplugin_' . $this->getPluginComponent());
887935713eSJames Collins            } else {
897935713eSJames Collins                $this->Lexer->addSpecialPattern($this->pattern_entry, $mode, 'plugin_mikioplugin_' . $this->getPluginComponent());
907935713eSJames Collins            }
9117e6d639SJames Collins        }
9217e6d639SJames Collins    }
933deaf3a5SJames Collins
9417e6d639SJames Collins
957935713eSJames Collins    public function postConnect()
967935713eSJames Collins    {
977935713eSJames Collins        if ($this->hasEndTag) {
9817e6d639SJames Collins            if ($this->pattern_exit == '' && $this->tag != '') {
997935713eSJames Collins                $this->pattern_exit = '</(?i:' . $this->tagPrefix . $this->tag . ')>';
10017e6d639SJames Collins            }
10117e6d639SJames Collins
10217e6d639SJames Collins            if ($this->pattern_exit != '') {
10317e6d639SJames Collins                $this->Lexer->addExitPattern($this->pattern_exit, 'plugin_mikioplugin_' . $this->getPluginComponent());
10417e6d639SJames Collins            }
10517e6d639SJames Collins        }
10617e6d639SJames Collins    }
10717e6d639SJames Collins
1087935713eSJames Collins    public function handle($match, $state, $pos, Doku_Handler $handler)
1097935713eSJames Collins    {
11017e6d639SJames Collins        switch ($state) {
11117e6d639SJames Collins        case DOKU_LEXER_ENTER:
11217e6d639SJames Collins        case DOKU_LEXER_SPECIAL:
113c5f7fed6SJames Collins            $match_fix = preg_replace('/\s*=\s*/', '=', trim(substr($match, strlen($this->tagPrefix . $this->tag) + 1, -1)));
114c5f7fed6SJames Collins            $optionlist = preg_split('/\s(?=([^"]*"[^"]*")*[^"]*$)/', $match_fix);
11517e6d639SJames Collins
11617e6d639SJames Collins            $options = array();
11717e6d639SJames Collins            foreach ($optionlist as $item) {
11817e6d639SJames Collins                $i = strpos($item, '=');
11917e6d639SJames Collins                if ($i !== false) {
12017e6d639SJames Collins                    $value = substr($item, $i + 1);
12117e6d639SJames Collins
122b007ca42SJames Collins                    if (substr($value, 0, 1) == '"') { $value = substr($value, 1);
123b007ca42SJames Collins                    }
124b007ca42SJames Collins                    if (substr($value, -1) == '"') { $value = substr($value, 0, -1);
125b007ca42SJames Collins                    }
12617e6d639SJames Collins
12717e6d639SJames Collins                    $options[substr($item, 0, $i)] = $value;
12817e6d639SJames Collins                } else {
12917e6d639SJames Collins                    $options[$item] = true;
13017e6d639SJames Collins                }
13117e6d639SJames Collins            }
13217e6d639SJames Collins
1337935713eSJames Collins            if (count($this->options) > 0) {
13431359b6fSJames Collins                $options_clean = $this->cleanOptions($options);
1357935713eSJames Collins            } else {
1367935713eSJames Collins                $options_clean = $options;
1377935713eSJames Collins            }
13831359b6fSJames Collins
13931359b6fSJames Collins            $this->values = $options_clean;
14031359b6fSJames Collins
14131359b6fSJames Collins            return array($state, $options_clean);
14231359b6fSJames Collins
1433deaf3a5SJames Collins        case DOKU_LEXER_MATCHED:
1443deaf3a5SJames Collins            return array($state, $match);
1453deaf3a5SJames Collins
14631359b6fSJames Collins        case DOKU_LEXER_UNMATCHED:
14731359b6fSJames Collins            return array($state, $match);
14831359b6fSJames Collins
14931359b6fSJames Collins        case DOKU_LEXER_EXIT:
150f4aa5cdcSJames Collins            return array($state, $this->values);
15131359b6fSJames Collins        }
15231359b6fSJames Collins
15331359b6fSJames Collins        return array();
15431359b6fSJames Collins    }
15531359b6fSJames Collins
15631359b6fSJames Collins
1577935713eSJames Collins    /*
1587935713eSJames Collins    * clean element options to only supported attributes, setting defaults if required
1597935713eSJames Collins    *
1607935713eSJames Collins    * @param $options   options passed to element
1617935713eSJames Collins    * @return           array of options supported with default set
1627935713eSJames Collins    */
1637935713eSJames Collins    protected function cleanOptions($data, $options = null)
1647935713eSJames Collins    {
1657935713eSJames Collins        $optionsCleaned = array();
16631359b6fSJames Collins
167b007ca42SJames Collins        if ($options == null) { $options = $this->options;
168b007ca42SJames Collins        }
1697935713eSJames Collins
1707935713eSJames Collins        // Match DokuWiki passed options to syntax options
1717935713eSJames Collins        foreach ($data as $optionKey => $optionValue) {
1727935713eSJames Collins            foreach ($options as $syntaxKey => $syntaxValue) {
1737935713eSJames Collins                if (strcasecmp($optionKey, $syntaxKey) == 0) {
1747935713eSJames Collins                    if (array_key_exists('type', $options[$syntaxKey])) {
1757935713eSJames Collins                        $type = $options[$syntaxKey]['type'];
1767935713eSJames Collins
1777935713eSJames Collins                        switch ($type) {
1787935713eSJames Collins                        case 'boolean':
1797935713eSJames Collins                            $optionsCleaned[$syntaxKey] = filter_var($optionValue, FILTER_VALIDATE_BOOLEAN);
1807935713eSJames Collins                            break;
1817935713eSJames Collins                        case 'number':
1827935713eSJames Collins                            $optionsCleaned[$syntaxKey] = filter_var($optionValue, FILTER_VALIDATE_INT);
1837935713eSJames Collins                            break;
1847935713eSJames Collins                        case 'float':
1857935713eSJames Collins                            $optionsCleaned[$syntaxKey] = filter_var($optionValue, FILTER_VALIDATE_FLOAT);
1867935713eSJames Collins                            break;
1877935713eSJames Collins                        case 'text':
1887935713eSJames Collins                            $optionsCleaned[$syntaxKey] = $optionValue;
1897935713eSJames Collins                            break;
1907935713eSJames Collins                        case 'size':
1917935713eSJames Collins                            $s = strtolower($optionValue);
1927935713eSJames Collins                            $i = '';
1937935713eSJames Collins                            if (substr($s, -3) == 'rem') {
1947935713eSJames Collins                                $i = substr($s, 0, -3);
1957935713eSJames Collins                                $s = 'rem';
1967935713eSJames Collins                            } elseif (substr($s, -2) == 'em') {
1977935713eSJames Collins                                $i = substr($s, 0, -2);
1987935713eSJames Collins                                $s = 'em';
1990e73f855Snomadjimbob                            } elseif (substr($s, -2) == 'px') {
2007935713eSJames Collins                                $i = substr($s, 0, -2);
2017935713eSJames Collins                                $s = 'px';
2020e73f855Snomadjimbob                            } elseif (substr($s, -1) == '%') {
2037935713eSJames Collins                                $i = substr($s, 0, -1);
2047935713eSJames Collins                                $s = '%';
2050e73f855Snomadjimbob                            } else {
20618e323fdSJames Collins                                if ($s != 'auto') {
2077935713eSJames Collins                                    $i = filter_var($s, FILTER_VALIDATE_INT);
208b007ca42SJames Collins                                    if ($i == '') { $i = '1';
209b007ca42SJames Collins                                    }
2107935713eSJames Collins                                    $s = 'rem';
2117935713eSJames Collins                                }
21218e323fdSJames Collins                            }
2137935713eSJames Collins
2147935713eSJames Collins                            $optionsCleaned[$syntaxKey] = $i . $s;
2157935713eSJames Collins                            break;
21618e323fdSJames Collins                        case 'multisize':
21718e323fdSJames Collins                            $val = '';
21818e323fdSJames Collins                            $parts = explode(' ', $optionValue);
21918e323fdSJames Collins                            foreach ($parts as &$part) {
22018e323fdSJames Collins                                $s = strtolower($part);
22118e323fdSJames Collins                                $i = '';
22218e323fdSJames Collins                                if (substr($s, -3) == 'rem') {
22318e323fdSJames Collins                                    $i = substr($s, 0, -3);
22418e323fdSJames Collins                                    $s = 'rem';
22518e323fdSJames Collins                                } elseif (substr($s, -2) == 'em') {
22618e323fdSJames Collins                                    $i = substr($s, 0, -2);
22718e323fdSJames Collins                                    $s = 'em';
2280e73f855Snomadjimbob                                } elseif (substr($s, -2) == 'px') {
22918e323fdSJames Collins                                    $i = substr($s, 0, -2);
23018e323fdSJames Collins                                    $s = 'px';
2310e73f855Snomadjimbob                                } elseif (substr($s, -2) == 'fr') {
2322608c53cSJames Collins                                    $i = substr($s, 0, -2);
2332608c53cSJames Collins                                    $s = 'fr';
2340e73f855Snomadjimbob                                } elseif (substr($s, -1) == '%') {
23518e323fdSJames Collins                                    $i = substr($s, 0, -1);
23618e323fdSJames Collins                                    $s = '%';
2370e73f855Snomadjimbob                                } else {
23818e323fdSJames Collins                                    if ($s != 'auto') {
23918e323fdSJames Collins                                        $i = filter_var($s, FILTER_VALIDATE_INT);
240b007ca42SJames Collins                                        if ($i === '') { $i = '1';
241b007ca42SJames Collins                                        }
24218e323fdSJames Collins                                        if ($i != 0) {
24318e323fdSJames Collins                                            $s = 'rem';
24418e323fdSJames Collins                                        } else {
24518e323fdSJames Collins                                            $s = '';
24618e323fdSJames Collins                                        }
24718e323fdSJames Collins                                    }
24818e323fdSJames Collins                                }
24918e323fdSJames Collins
25018e323fdSJames Collins                                $part = $i . $s;
25118e323fdSJames Collins                            }
25218e323fdSJames Collins
25318e323fdSJames Collins                            $optionsCleaned[$syntaxKey] = implode(' ', $parts);
25418e323fdSJames Collins                            break;
2557935713eSJames Collins                        case 'color':
2567935713eSJames Collins                            if (strlen($optionValue) == 3 || strlen($optionValue) == 6) {
2577935713eSJames Collins                                preg_match('/([[:xdigit:]]{3}){1,2}/', $optionValue, $matches);
2587935713eSJames Collins                                if (count($matches) > 1) {
2597935713eSJames Collins                                    $optionsCleaned[$syntaxKey] = '#' . $matches[0];
2600e73f855Snomadjimbob                                } else {
2610e73f855Snomadjimbob                                    $optionsCleaned[$syntaxKey] = $optionValue;
2627935713eSJames Collins                                }
26317e6d639SJames Collins                            } else {
2647935713eSJames Collins                                $optionsCleaned[$syntaxKey] = $optionValue;
26517e6d639SJames Collins                            }
2667935713eSJames Collins                            break;
2677935713eSJames Collins                        case 'url':
2687935713eSJames Collins                            $optionsCleaned[$syntaxKey] = $this->buildLink($optionValue);
2697935713eSJames Collins                            break;
2707935713eSJames Collins                        case 'media':
2717935713eSJames Collins                            $optionsCleaned[$syntaxKey] = $this->buildMediaLink($optionValue);
2727935713eSJames Collins                            break;
2737935713eSJames Collins                        case 'choice':
2747935713eSJames Collins                            if (array_key_exists('data', $options[$syntaxKey])) {
2757935713eSJames Collins                                foreach ($options[$syntaxKey]['data'] as $choiceKey => $choiceValue) {
27618e323fdSJames Collins                                    if (strcasecmp($optionValue, $choiceKey) == 0) {
27718e323fdSJames Collins                                        $optionsCleaned[$syntaxKey] = $choiceKey;
27818e323fdSJames Collins                                        break;
27918e323fdSJames Collins                                    }
28018e323fdSJames Collins
2817935713eSJames Collins                                    if (is_array($choiceValue)) {
2827935713eSJames Collins                                        foreach ($choiceValue as $choiceItem) {
2837935713eSJames Collins                                            if (strcasecmp($optionValue, $choiceItem) == 0) {
2847935713eSJames Collins                                                $optionsCleaned[$syntaxKey] = $choiceKey;
2857935713eSJames Collins                                                break 2;
28617e6d639SJames Collins                                            }
28717e6d639SJames Collins                                        }
288ebb7bc5aSJames Collins                                    } else {
2897935713eSJames Collins                                        if (strcasecmp($optionValue, $choiceValue) == 0) {
2907935713eSJames Collins                                            $optionsCleaned[$syntaxKey] = $choiceValue;
2917935713eSJames Collins                                            break;
2927935713eSJames Collins                                        }
2937935713eSJames Collins                                    }
2947935713eSJames Collins                                }
2957935713eSJames Collins                            }
2967935713eSJames Collins                            break;
2977935713eSJames Collins                        case 'set':
2987935713eSJames Collins                            if (array_key_exists('option', $options[$syntaxKey]) && array_key_exists('data', $options[$syntaxKey])) {
2997935713eSJames Collins                                $optionsCleaned[$options[$syntaxKey]['option']] = $options[$syntaxKey]['data'];
3007935713eSJames Collins                            }
3017935713eSJames Collins                            break;
3027935713eSJames Collins                        }
303ebb7bc5aSJames Collins                    }
30417e6d639SJames Collins
3057935713eSJames Collins                    break;
3067935713eSJames Collins                }
3077935713eSJames Collins            }
3089a439316SJames Collins        }
3099a439316SJames Collins
310ec319cf1SJames Collins
3119a439316SJames Collins        foreach ($data as $optionKey => $optionValue) {
312ec319cf1SJames Collins            if (!array_key_exists($optionKey, $optionsCleaned)) {
313ec319cf1SJames Collins                foreach ($options as $syntaxKey => $syntaxValue) {
314ec319cf1SJames Collins                    if (array_key_exists('type', $options[$syntaxKey])) {
31554ee1cccSJames Collins                        if (array_key_exists('data', $options[$syntaxKey]) && is_array($options[$syntaxKey]['data'])) {
316ec319cf1SJames Collins                            foreach ($options[$syntaxKey]['data'] as $choiceKey => $choiceValue) {
317ec319cf1SJames Collins                                if (is_array($choiceValue)) {
318ec319cf1SJames Collins                                    if (in_array($optionKey, $choiceValue)) {
319ec319cf1SJames Collins                                        $optionsCleaned[$syntaxKey] = $choiceKey;
320ec319cf1SJames Collins                                    }
321ec319cf1SJames Collins                                } else {
322ec319cf1SJames Collins                                    if (strcasecmp($choiceValue, $optionKey) == 0) {
323ec319cf1SJames Collins                                        $optionsCleaned[$syntaxKey] = $choiceValue;
324ec319cf1SJames Collins                                    }
325ec319cf1SJames Collins                                }
326ec319cf1SJames Collins                            }
327ec319cf1SJames Collins                        }
328ec319cf1SJames Collins                    }
3297935713eSJames Collins                }
3307935713eSJames Collins            }
3317935713eSJames Collins        }
33217e6d639SJames Collins
3337935713eSJames Collins        // Add in syntax options that are missing
3347935713eSJames Collins        foreach ($options as $optionKey => $optionValue) {
3357935713eSJames Collins            if (!array_key_exists($optionKey, $optionsCleaned)) {
3367935713eSJames Collins                if (array_key_exists('default', $options[$optionKey])) {
3377935713eSJames Collins                    switch ($options[$optionKey]['type']) {
3387935713eSJames Collins                    case 'boolean':
3397935713eSJames Collins                        $optionsCleaned[$optionKey] = filter_var($options[$optionKey]['default'], FILTER_VALIDATE_BOOLEAN);
3407935713eSJames Collins                        break;
3417935713eSJames Collins                    case 'number':
3427935713eSJames Collins                        $optionsCleaned[$optionKey] = filter_var($options[$optionKey]['default'], FILTER_VALIDATE_INT);
3437935713eSJames Collins                        break;
3447935713eSJames Collins                    default:
3457935713eSJames Collins                        $optionsCleaned[$optionKey] = $options[$optionKey]['default'];
3467935713eSJames Collins                        break;
3477935713eSJames Collins                    }
3487935713eSJames Collins                }
3497935713eSJames Collins            }
35017e6d639SJames Collins        }
35117e6d639SJames Collins
3527935713eSJames Collins        return $optionsCleaned;
35317e6d639SJames Collins    }
35417e6d639SJames Collins
3557935713eSJames Collins    /* Lexer renderers */
3560e73f855Snomadjimbob    protected function render_lexer_enter(Doku_Renderer $renderer, $data)
3570e73f855Snomadjimbob    {
3580e73f855Snomadjimbob    }
3590e73f855Snomadjimbob    protected function render_lexer_unmatched(Doku_Renderer $renderer, $data)
3600e73f855Snomadjimbob    {
3610e73f855Snomadjimbob        $renderer->doc .= $renderer->_xmlEntities($data);
3620e73f855Snomadjimbob    }
3630e73f855Snomadjimbob    protected function render_lexer_exit(Doku_Renderer $renderer, $data)
3640e73f855Snomadjimbob    {
3650e73f855Snomadjimbob    }
3660e73f855Snomadjimbob    protected function render_lexer_special(Doku_Renderer $renderer, $data)
3670e73f855Snomadjimbob    {
3680e73f855Snomadjimbob    }
3690e73f855Snomadjimbob    protected function render_lexer_match(Doku_Renderer $renderer, $data)
3700e73f855Snomadjimbob    {
3710e73f855Snomadjimbob    }
37217e6d639SJames Collins
3737935713eSJames Collins    /* Renderer */
3747935713eSJames Collins    public function render($mode, Doku_Renderer $renderer, $data)
3757935713eSJames Collins    {
37617e6d639SJames Collins        if ($mode == 'xhtml') {
37717e6d639SJames Collins            list($state, $match) = $data;
37817e6d639SJames Collins
37917e6d639SJames Collins            switch ($state) {
38017e6d639SJames Collins            case DOKU_LEXER_ENTER:
38117e6d639SJames Collins                $this->render_lexer_enter($renderer, $match);
38217e6d639SJames Collins                return true;
38317e6d639SJames Collins
38417e6d639SJames Collins            case DOKU_LEXER_UNMATCHED:
38517e6d639SJames Collins                $this->render_lexer_unmatched($renderer, $match);
38617e6d639SJames Collins                return true;
38717e6d639SJames Collins
3883deaf3a5SJames Collins            case DOKU_LEXER_MATCHED:
3893deaf3a5SJames Collins                $this->render_lexer_match($renderer, $match);
3903deaf3a5SJames Collins                return true;
3913deaf3a5SJames Collins
39217e6d639SJames Collins            case DOKU_LEXER_EXIT:
39317e6d639SJames Collins                $this->render_lexer_exit($renderer, $match);
39417e6d639SJames Collins                return true;
39517e6d639SJames Collins
39617e6d639SJames Collins            case DOKU_LEXER_SPECIAL:
39717e6d639SJames Collins                $this->render_lexer_special($renderer, $match);
39817e6d639SJames Collins                return true;
39917e6d639SJames Collins            }
40017e6d639SJames Collins
40117e6d639SJames Collins            return true;
40217e6d639SJames Collins        }
40317e6d639SJames Collins
40417e6d639SJames Collins        return false;
40517e6d639SJames Collins    }
40617e6d639SJames Collins
4077935713eSJames Collins    /*
4087935713eSJames Collins    * return a class list with mikiop- prefix
4097935713eSJames Collins    *
4107935713eSJames Collins    * @param $options       options of syntax element. Options with key 'class'=true are automatically added
4117935713eSJames Collins    * @param $classes       classes to build from options as array
4127935713eSJames Collins    * @param $inclAttr      include class="" in the return string
4139d56a2c2SJames Collins    * @param $optionsTemplate   allow a different options template instead of $this->options (for findTags)
4147935713eSJames Collins    * @return               a string of classes from options/classes variable
4157935713eSJames Collins    */
4169d56a2c2SJames Collins    public function buildClass($options = null, $classes = null, $inclAttr = false, $optionsTemplate = null)
4177935713eSJames Collins    {
41817e6d639SJames Collins        $s = array();
41917e6d639SJames Collins
4207935713eSJames Collins        if (is_array($options)) {
421b007ca42SJames Collins            if ($classes == null) { $classes = array();
422b007ca42SJames Collins            }
423b007ca42SJames Collins            if ($optionsTemplate == null) { $optionsTemplate = $this->options;
424b007ca42SJames Collins            }
42517e6d639SJames Collins
4269d56a2c2SJames Collins            foreach ($optionsTemplate as $key => $value) {
427b007ca42SJames Collins                if (array_key_exists('class', $value) && $value['class'] == true) {
4287935713eSJames Collins                    array_push($classes, $key);
42917e6d639SJames Collins                }
43017e6d639SJames Collins            }
43117e6d639SJames Collins
4327935713eSJames Collins            foreach ($classes as $class) {
433b007ca42SJames Collins                if (array_key_exists($class, $options) && $options[$class] !== false && $options[$class] != '') {
4347935713eSJames Collins                    $prefix = $this->classPrefix;
4357935713eSJames Collins
4369d56a2c2SJames Collins                    if (array_key_exists($class, $optionsTemplate) && array_key_exists('prefix', $optionsTemplate[$class])) {
4379d56a2c2SJames Collins                        $prefix .= $optionsTemplate[$class]['prefix'];
43817e6d639SJames Collins                    }
4397935713eSJames Collins
440b007ca42SJames Collins                    if (array_key_exists($class, $optionsTemplate) && array_key_exists('classNoSuffix', $optionsTemplate[$class]) && $optionsTemplate[$class]['classNoSuffix'] == true) {
4412f5b9ce6SJames Collins                        $s[] = $prefix . $class;
4422f5b9ce6SJames Collins                    } else {
443b007ca42SJames Collins                        $s[] = $prefix . $class . ($options[$class] !== true ? '-' . $options[$class] : '');
44417e6d639SJames Collins                    }
44517e6d639SJames Collins                }
4462f5b9ce6SJames Collins            }
447a007b54fSJames Collins        }
44817e6d639SJames Collins
4497935713eSJames Collins        $s = implode(' ', $s);
450b007ca42SJames Collins        if ($s != '') { $s = ' ' . $s;
451b007ca42SJames Collins        }
4528f786230SJames Collins
453b007ca42SJames Collins        if ($inclAttr) { $s = ' classes="' . $s . '"';
454b007ca42SJames Collins        }
4556cfe6dadSJames Collins
456ad1dae96SJames Collins        return $s;
457ad1dae96SJames Collins    }
45817e6d639SJames Collins
4597935713eSJames Collins
4607935713eSJames Collins
4617935713eSJames Collins
4627935713eSJames Collins    /*
4637935713eSJames Collins    * build style string
4647935713eSJames Collins    *
4657935713eSJames Collins    * @param $list          style list as key => value. Empty values are not included
4667935713eSJames Collins    * @param $inclAttr      include style="" in the return string
4677935713eSJames Collins    * @return               style list string
4687935713eSJames Collins    */
4697935713eSJames Collins    public function buildStyle($list, $inclAttr = false)
4707935713eSJames Collins    {
4717935713eSJames Collins        $s = '';
4727935713eSJames Collins
4737935713eSJames Collins        if (is_array($list) && count($list) > 0) {
4747935713eSJames Collins            foreach ($list as $key => $value) {
4757935713eSJames Collins                if ($value != '') {
4767935713eSJames Collins                    $s .= $key . ':' . $value . ';';
4777935713eSJames Collins                }
4787935713eSJames Collins            }
4797935713eSJames Collins        }
4807935713eSJames Collins
4817935713eSJames Collins        if ($s != '' && $inclAttr) {
4827935713eSJames Collins            $s = ' style="' . $s . '"';
4837935713eSJames Collins        }
4847935713eSJames Collins
4857935713eSJames Collins        return $s;
4867935713eSJames Collins    }
4877935713eSJames Collins
4887935713eSJames Collins
4897935713eSJames Collins    public function buildTooltipString($options)
4907935713eSJames Collins    {
491a401c3b7SJames Collins        $dataPlacement = 'top';
492a401c3b7SJames Collins        $dataHtml = false;
493a401c3b7SJames Collins        $title = '';
494a401c3b7SJames Collins
495a401c3b7SJames Collins        if ($options != null) {
496a401c3b7SJames Collins            if (array_key_exists('tooltip-html-top', $options) && $options['tooltip-html-top'] != '') {
497a401c3b7SJames Collins                $title = $options['tooltip-html-top'];
498a401c3b7SJames Collins                $dataPlacement = 'top';
499a401c3b7SJames Collins            }
500a401c3b7SJames Collins
501a401c3b7SJames Collins            if (array_key_exists('tooltip-html-left', $options) && $options['tooltip-html-left'] != '') {
502a401c3b7SJames Collins                $title = $options['tooltip-html-left'];
503a401c3b7SJames Collins                $dataPlacement = 'left';
504a401c3b7SJames Collins            }
505a401c3b7SJames Collins
506a401c3b7SJames Collins            if (array_key_exists('tooltip-html-bottom', $options) && $options['tooltip-html-bottom'] != '') {
507a401c3b7SJames Collins                $title = $options['tooltip-html-bottom'];
508a401c3b7SJames Collins                $dataPlacement = 'bottom';
509a401c3b7SJames Collins            }
510a401c3b7SJames Collins
511a401c3b7SJames Collins            if (array_key_exists('tooltip-html-right', $options) && $options['tooltip-html-right'] != '') {
512a401c3b7SJames Collins                $title = $options['tooltip-html-right'];
513a401c3b7SJames Collins                $dataPlacement = 'right';
514a401c3b7SJames Collins            }
515a401c3b7SJames Collins
516a401c3b7SJames Collins            if (array_key_exists('tooltip-top', $options) && $options['tooltip-top'] != '') {
517a401c3b7SJames Collins                $title = $options['tooltip-top'];
518a401c3b7SJames Collins                $dataPlacement = 'top';
519a401c3b7SJames Collins            }
520a401c3b7SJames Collins
521a401c3b7SJames Collins            if (array_key_exists('tooltip-left', $options) && $options['tooltip-left'] != '') {
522a401c3b7SJames Collins                $title = $options['tooltip-left'];
523a401c3b7SJames Collins                $dataPlacement = 'left';
524a401c3b7SJames Collins            }
525a401c3b7SJames Collins
526a401c3b7SJames Collins            if (array_key_exists('tooltip-bottom', $options) && $options['tooltip-bottom'] != '') {
527a401c3b7SJames Collins                $title = $options['tooltip-bottom'];
528a401c3b7SJames Collins                $dataPlacement = 'bottom';
529a401c3b7SJames Collins            }
530a401c3b7SJames Collins
531a401c3b7SJames Collins            if (array_key_exists('tooltip-right', $options) && $options['tooltip-right'] != '') {
532a401c3b7SJames Collins                $title = $options['tooltip-right'];
533a401c3b7SJames Collins                $dataPlacement = 'right';
534a401c3b7SJames Collins            }
535a401c3b7SJames Collins
536a401c3b7SJames Collins            if (array_key_exists('tooltip-html', $options) && $options['tooltip-html'] != '') {
537a401c3b7SJames Collins                $title = $options['tooltip-html'];
538a401c3b7SJames Collins                $dataPlacement = 'top';
539a401c3b7SJames Collins            }
540a401c3b7SJames Collins
541a401c3b7SJames Collins            if (array_key_exists('tooltip', $options) && $options['tooltip'] != '') {
542a401c3b7SJames Collins                $title = $options['tooltip'];
543a401c3b7SJames Collins                $dataPlacement = 'top';
544a401c3b7SJames Collins            }
545a401c3b7SJames Collins        }
546a401c3b7SJames Collins
547a401c3b7SJames Collins        if ($title != '') {
548a401c3b7SJames Collins            return ' data-toggle="tooltip" data-placement="' . $dataPlacement . '" ' . ($dataHtml == true ? 'data-html="true" ' : '') . 'title="' . $title . '" ';
549a401c3b7SJames Collins        }
550a401c3b7SJames Collins
551a401c3b7SJames Collins        return '';
552a401c3b7SJames Collins    }
553a401c3b7SJames Collins
5547935713eSJames Collins    /*
5557935713eSJames Collins    * convert the URL to a DokuWiki media link (if required)
5567935713eSJames Collins    *
5577935713eSJames Collins    * @param $url   url to parse
5587935713eSJames Collins    * @return       url string
5597935713eSJames Collins    */
5607935713eSJames Collins    public function buildMediaLink($url)
5617935713eSJames Collins    {
5627935713eSJames Collins        $i = strpos($url, '?');
563b007ca42SJames Collins        if ($i !== false) { $url = substr($url, 0, $i);
564b007ca42SJames Collins        }
56517e6d639SJames Collins
56666f3b00dSJames Collins        $url = preg_replace('/[^\da-zA-Z:_.-]+/', '', $url);
56717e6d639SJames Collins
568b007ca42SJames Collins        return (tpl_getMediaFile(array($url), false));
56917e6d639SJames Collins    }
57017e6d639SJames Collins
57117e6d639SJames Collins
5727935713eSJames Collins    /*
5737935713eSJames Collins    * returns either a url or dokuwiki link
5747935713eSJames Collins    *
5757935713eSJames Collins    * @param    $url    link to build from
5767935713eSJames Collins    * @return           built link
5777935713eSJames Collins    */
5787935713eSJames Collins    public function buildLink($url)
5797935713eSJames Collins    {
5807935713eSJames Collins        $i = strpos($url, '://');
581b007ca42SJames Collins        if ($i !== false || substr($url, 0, 1) == '#') { return $url;
582b007ca42SJames Collins        }
583f1a539d8SJames Collins
5847935713eSJames Collins        return wl($url);
585f1a539d8SJames Collins    }
586f1a539d8SJames Collins
5877935713eSJames Collins    /*
5887935713eSJames Collins    * Call syntax renderer of mikio syntax plugin
5897935713eSJames Collins    *
5907935713eSJames Collins    * @param $renderer          DokuWiki renderer object
5917935713eSJames Collins    * @param $className         mikio syntax class to call
5927935713eSJames Collins    * @param $text              unmatched text to pass outside of lexer. Only used when $lexer=MIKIO_LEXER_AUTO
5937935713eSJames Collins    * @param $data              tag options to pass to syntax class. Runs through cleanOptions to validate first
5947935713eSJames Collins    * @param $lexer             which lexer to call
5957935713eSJames Collins    */
5967935713eSJames Collins    public function syntaxRender(Doku_Renderer $renderer, $className, $text, $data = null, $lexer = MIKIO_LEXER_AUTO)
5977935713eSJames Collins    {
59803f82c7cSnomadjimbob        $className = 'syntax_plugin_mikioplugin_' . str_replace('-', '', $className);
5997935713eSJames Collins
6007935713eSJames Collins        if (class_exists($className)) {
60117e6d639SJames Collins            $class = new $className;
60217e6d639SJames Collins
603b007ca42SJames Collins            if (!is_array($data)) { $data = array();
604b007ca42SJames Collins            }
60531359b6fSJames Collins
60618e323fdSJames Collins
6077935713eSJames Collins            if (count($class->options) > 0) {
60818e323fdSJames Collins                $data = $class->cleanOptions($data, $class->options);
6097935713eSJames Collins            }
61031359b6fSJames Collins
6117935713eSJames Collins            switch ($lexer) {
6127935713eSJames Collins            case MIKIO_LEXER_AUTO:
6137935713eSJames Collins                if ($class->hasEndTag) {
614b007ca42SJames Collins                    if (method_exists($class, 'render_lexer_enter')) { $class->render_lexer_enter($renderer, $data);
615b007ca42SJames Collins                    }
61617e6d639SJames Collins                    $renderer->doc .= $text;
617b007ca42SJames Collins                    if (method_exists($class, 'render_lexer_exit')) { $class->render_lexer_exit($renderer, $data);
618b007ca42SJames Collins                    }
6197935713eSJames Collins                } else {
620b007ca42SJames Collins                    if (method_exists($class, 'render_lexer_special')) { $class->render_lexer_special($renderer, $data);
621b007ca42SJames Collins                    }
6227935713eSJames Collins                }
6237935713eSJames Collins
6247935713eSJames Collins                break;
6257935713eSJames Collins            case MIKIO_LEXER_ENTER:
626b007ca42SJames Collins                if (method_exists($class, 'render_lexer_enter')) { $class->render_lexer_enter($renderer, $data);
627b007ca42SJames Collins                }
6287935713eSJames Collins                break;
6297935713eSJames Collins            case MIKIO_LEXER_EXIT:
630b007ca42SJames Collins                if (method_exists($class, 'render_lexer_exit')) { $class->render_lexer_exit($renderer, $data);
631b007ca42SJames Collins                }
6327935713eSJames Collins                break;
6337935713eSJames Collins            case MIKIO_LEXER_SPECIAL:
634b007ca42SJames Collins                if (method_exists($class, 'render_lexer_special')) { $class->render_lexer_special($renderer, $data);
635b007ca42SJames Collins                }
6367935713eSJames Collins                break;
6377935713eSJames Collins            }
63817e6d639SJames Collins        }
63917e6d639SJames Collins    }
640ebb7bc5aSJames Collins
6412f5b9ce6SJames Collins
6420e73f855Snomadjimbob    protected function callMikioTag($className, $data)
6430e73f855Snomadjimbob    {
64418e323fdSJames Collins        // $className = 'syntax_plugin_mikioplugin_'.$className;
6452f5b9ce6SJames Collins
6462f5b9ce6SJames Collins
64718e323fdSJames Collins        // if(class_exists($className)) {
64818e323fdSJames Collins        //$class = new $className;
64918e323fdSJames Collins        if (!plugin_isdisabled('mikioplugin')) {
65018e323fdSJames Collins            $class = plugin_load('syntax', 'mikioplugin_' . $className);
65118e323fdSJames Collins            // echo '^^'.$className.'^^';
65218e323fdSJames Collins
65318e323fdSJames Collins
654b007ca42SJames Collins            if (method_exists($class, 'mikioCall')) { return $class->mikioCall($data);
655b007ca42SJames Collins            }
6562f5b9ce6SJames Collins        }
6572f5b9ce6SJames Collins
65818e323fdSJames Collins        // }
65918e323fdSJames Collins
6602f5b9ce6SJames Collins        return '';
6612f5b9ce6SJames Collins    }
6622f5b9ce6SJames Collins
6632f5b9ce6SJames Collins
6640e73f855Snomadjimbob    protected function callMikioOptionDefault($className, $option)
6650e73f855Snomadjimbob    {
666f003e4a8SJames Collins        $className = 'syntax_plugin_mikioplugin_' . $className;
667f003e4a8SJames Collins
668f003e4a8SJames Collins        if (class_exists($className)) {
669f003e4a8SJames Collins            $class = new $className;
670f003e4a8SJames Collins
671f003e4a8SJames Collins            if (array_key_exists($option, $class->options) && array_key_exists('default', $class->options[$option])) {
672f003e4a8SJames Collins                return $class->options[$option]['default'];
673f003e4a8SJames Collins            }
674f003e4a8SJames Collins        }
675f003e4a8SJames Collins
676f003e4a8SJames Collins        return '';
677f003e4a8SJames Collins    }
678f003e4a8SJames Collins
679f003e4a8SJames Collins
6800e73f855Snomadjimbob    protected function buildTooltip($text)
6810e73f855Snomadjimbob    {
6822f5b9ce6SJames Collins        if ($text != '') {
6832f5b9ce6SJames Collins            return ' data-tooltip="' . $text . '"';
6842f5b9ce6SJames Collins        }
6852f5b9ce6SJames Collins
6862f5b9ce6SJames Collins        return '';
6872f5b9ce6SJames Collins    }
6882f5b9ce6SJames Collins
6897935713eSJames Collins    /*
6907935713eSJames Collins    * Create array with passed elements and include them if their values are not empty
6917935713eSJames Collins    *
6927935713eSJames Collins    * @param ...        array items
6937935713eSJames Collins    */
6940e73f855Snomadjimbob    protected function arrayRemoveEmpties($items)
6950e73f855Snomadjimbob    {
6967935713eSJames Collins        $result = array();
6977935713eSJames Collins
6987935713eSJames Collins        foreach ($items as $key => $value) {
6997935713eSJames Collins            if ($value != '') {
7007935713eSJames Collins                $result[$key] = $value;
7017935713eSJames Collins            }
7027935713eSJames Collins        }
7037935713eSJames Collins
7047935713eSJames Collins        return $result;
7057935713eSJames Collins    }
7067935713eSJames Collins
7077935713eSJames Collins    public function getFirstArrayKey($data)
7087935713eSJames Collins    {
709ebb7bc5aSJames Collins        if (!function_exists('array_key_first')) {
710ebb7bc5aSJames Collins            foreach ($data as $key => $unused) {
711ebb7bc5aSJames Collins                return $key;
712ebb7bc5aSJames Collins            }
713ebb7bc5aSJames Collins        }
714ebb7bc5aSJames Collins
715ebb7bc5aSJames Collins        return array_key_first($data);
716ebb7bc5aSJames Collins    }
7177935713eSJames Collins
7187935713eSJames Collins
7197935713eSJames Collins    /*
7207935713eSJames Collins    * add common options to options
7217935713eSJames Collins    *
7227935713eSJames Collins    * @param $typelist      common option to add
7237935713eSJames Collins    * @param $options   save in options
7247935713eSJames Collins    */
7250e73f855Snomadjimbob    public function addCommonOptions($typelist)
7260e73f855Snomadjimbob    {
7277935713eSJames Collins        $types = explode(' ', $typelist);
7287935713eSJames Collins        foreach ($types as $type) {
7297935713eSJames Collins            if (strcasecmp($type, 'shadow') == 0) {
7300e73f855Snomadjimbob                $this->options['shadow'] =          array(
7310e73f855Snomadjimbob                    'type'     => 'choice',
7327935713eSJames Collins                    'data'     => array('large' => array('shadow-large', 'shadow-lg'), 'small' => array('shadow-small', 'shadow-sm'), true),
7337935713eSJames Collins                    'default'  => '',
7340e73f855Snomadjimbob                    'class'    => true
7350e73f855Snomadjimbob                );
7367935713eSJames Collins            }
7377935713eSJames Collins
7387935713eSJames Collins            if (strcasecmp($type, 'width') == 0) {
7390e73f855Snomadjimbob                $this->options['width'] =           array(
7400e73f855Snomadjimbob                    'type'     => 'size',
7410e73f855Snomadjimbob                    'default'  => ''
7420e73f855Snomadjimbob                );
7437935713eSJames Collins            }
7447935713eSJames Collins
7457935713eSJames Collins            if (strcasecmp($type, 'height') == 0) {
7460e73f855Snomadjimbob                $this->options['height'] =          array(
7470e73f855Snomadjimbob                    'type'     => 'size',
7480e73f855Snomadjimbob                    'default'  => ''
7490e73f855Snomadjimbob                );
7507935713eSJames Collins            }
7517935713eSJames Collins
75218e323fdSJames Collins            if (strcasecmp($type, 'text-color') == 0) {
7530e73f855Snomadjimbob                $this->options['text-color'] =          array(
7540e73f855Snomadjimbob                    'type'      => 'color',
7550e73f855Snomadjimbob                    'default'  => ''
7560e73f855Snomadjimbob                );
75718e323fdSJames Collins            }
75818e323fdSJames Collins
7597935713eSJames Collins            if (strcasecmp($type, 'type') == 0) {
7600e73f855Snomadjimbob                $this->options['type'] =              array(
7610e73f855Snomadjimbob                    'type'     => 'text',
762e84ad5e7SJames Collins                    'data'     => array('primary', 'secondary', 'success', 'danger', 'warning', 'info', 'light', 'dark', 'outline-primary', 'outline-secondary', 'outline-success', 'outline-danger', 'outline-warning', 'outline-info', 'outline-light', 'outline-dark'),
7637935713eSJames Collins                    'default'  => '',
7640e73f855Snomadjimbob                    'class'    => true
7650e73f855Snomadjimbob                );
7667935713eSJames Collins            }
7677935713eSJames Collins
7687935713eSJames Collins            if (strcasecmp($type, 'text-align') == 0) {
7690e73f855Snomadjimbob                $this->options['text-align'] =      array(
7700e73f855Snomadjimbob                    'type'     => 'choice',
7717935713eSJames Collins                    'data'     => array('left' => array('text-left'), 'center' => array('text-center'), 'right' => array('text-right')),
7727935713eSJames Collins                    'default'  => '',
7730e73f855Snomadjimbob                    'class'    => true
7740e73f855Snomadjimbob                );
7757935713eSJames Collins            }
7767935713eSJames Collins
7777935713eSJames Collins            if (strcasecmp($type, 'align') == 0) {
7780e73f855Snomadjimbob                $this->options['align'] =           array(
7790e73f855Snomadjimbob                    'type'     => 'choice',
7807935713eSJames Collins                    'data'     => array('left' => array('align-left'), 'center' => array('align-center'), 'right' => array('align-right')),
7817935713eSJames Collins                    'default'  => '',
7820e73f855Snomadjimbob                    'class'    => true
7830e73f855Snomadjimbob                );
7847935713eSJames Collins            }
7852f5b9ce6SJames Collins
7862f5b9ce6SJames Collins            if (strcasecmp($type, 'tooltip') == 0) {
7870e73f855Snomadjimbob                $this->options['tooltip'] =         array(
7880e73f855Snomadjimbob                    'type'     => 'text',
7892f5b9ce6SJames Collins                    'default'  => '',
7902f5b9ce6SJames Collins                    'class'    => true,
7910e73f855Snomadjimbob                    'classNoSuffix'   => true
7920e73f855Snomadjimbob                );
7932f5b9ce6SJames Collins            }
79418e323fdSJames Collins
79518e323fdSJames Collins            if (strcasecmp($type, 'vertical-align') == 0) {
7960e73f855Snomadjimbob                $this->options['vertical-align'] =  array(
7970e73f855Snomadjimbob                    'type'    => 'choice',
79818e323fdSJames Collins                    'data'    => array('top' => array('align-top'), 'middle' => array('align-middle'), 'bottom' => array('align-bottom')),
79918e323fdSJames Collins                    'default' => '',
8000e73f855Snomadjimbob                    'class'   => true
8010e73f855Snomadjimbob                );
80218e323fdSJames Collins            }
80318e323fdSJames Collins
80418e323fdSJames Collins            if (strcasecmp($type, 'links-match') == 0) {
8050e73f855Snomadjimbob                $this->options['links-match'] =     array(
8060e73f855Snomadjimbob                    'type'    => 'boolean',
80718e323fdSJames Collins                    'default' => 'false',
8080e73f855Snomadjimbob                    'class'   => true
8090e73f855Snomadjimbob                );
81018e323fdSJames Collins            }
8117935713eSJames Collins        }
8127935713eSJames Collins    }
8137935713eSJames Collins
8147935713eSJames Collins
8157935713eSJames Collins    /*
8167935713eSJames Collins    * Find HTML tags in string. Parse tags options. Used in parsing subtags
8177935713eSJames Collins    *
8187935713eSJames Collins    * @param $tagName       tagName to search for. Name is exclusive
8197935713eSJames Collins    * @param $content       search within content
8207935713eSJames Collins    * @param $options       parse options similar to syntax element options
821f0df6cccSJames Collins    * @param $hasEndTag     tagName search also looks for an end tag
8227935713eSJames Collins    * @return               array of tags containing 'options' => array of 'name' => 'value', 'content' => content inside the tag
8237935713eSJames Collins    */
8240e73f855Snomadjimbob    protected function findTags($tagName, $content, $options, $hasEndTag = true)
8250e73f855Snomadjimbob    {
8267935713eSJames Collins        $items = array();
827f0df6cccSJames Collins        $search = '/<(?i:' . $tagName . ')(.*?)>(.*?)<\/(?i:' . $tagName . ')>/s';
8287935713eSJames Collins
829f0df6cccSJames Collins        if (!$hasEndTag) {
830f0df6cccSJames Collins            $search = '/<(?i:' . $tagName . ')(.*?)>/s';
831f0df6cccSJames Collins        }
832f0df6cccSJames Collins
833f0df6cccSJames Collins        if (preg_match_all($search, $content, $match)) {
8347935713eSJames Collins            if (count($match) >= 2) {
8357935713eSJames Collins                for ($i = 0; $i < count($match[1]); $i++) {
8367935713eSJames Collins                    $item = array('options' => array(), 'content' => $this->render_text($match[2][$i]));
8377935713eSJames Collins
8387935713eSJames Collins                    $optionlist = preg_split('/\s(?=([^"]*"[^"]*")*[^"]*$)/', trim($match[1][$i]));
8397935713eSJames Collins
8407935713eSJames Collins                    foreach ($optionlist as $option) {
8417935713eSJames Collins                        $j = strpos($option, '=');
8427935713eSJames Collins                        if ($j !== false) {
8437935713eSJames Collins                            $value = substr($option, $j + 1);
8447935713eSJames Collins
845b007ca42SJames Collins                            if (substr($value, 0, 1) == '"') { $value = substr($value, 1);
846b007ca42SJames Collins                            }
847b007ca42SJames Collins                            if (substr($value, -1) == '"') { $value = substr($value, 0, -1);
848b007ca42SJames Collins                            }
8497935713eSJames Collins
8507935713eSJames Collins                            $item['options'][substr($option, 0, $j)] = $value;
8517935713eSJames Collins                        } else {
8527935713eSJames Collins                            $item['options'][$option] = true;
8537935713eSJames Collins                        }
8547935713eSJames Collins                    }
8557935713eSJames Collins
8563cbf07a0SJames Collins                    $item['options'] = $this->cleanOptions($item['options'], $options);
8577935713eSJames Collins
8587935713eSJames Collins                    $items[] = $item;
8597935713eSJames Collins                }
8607935713eSJames Collins            }
8617935713eSJames Collins        }
8627935713eSJames Collins
8637935713eSJames Collins        return $items;
8647935713eSJames Collins    }
86531359b6fSJames Collins}
866