1<?php
2
3use dokuwiki\Extension\SyntaxPlugin;
4
5/**
6 * BBCode plugin: allows BBCode markup familiar from forum software
7 *
8 * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
9 * @author     Esther Brunner <esther@kaffeehaus.ch>
10 * @author     Luis Machuca Bezzaza <luis.machuca@gulix.cl>
11 */
12class syntax_plugin_bbcode_size extends SyntaxPlugin
13{
14    /** @inheritdoc */
15    public function getType()
16    {
17        return 'formatting';
18    }
19
20    /** @inheritdoc */
21    public function getAllowedTypes()
22    {
23        return ['formatting', 'substition', 'disabled'];
24    }
25
26    /** @inheritdoc */
27    public function getSort()
28    {
29        return 105;
30    }
31
32    /** @inheritdoc */
33    public function connectTo($mode)
34    {
35        $this->Lexer->addEntryPattern('\[size=.*?\](?=.*?\x5B/size\x5D)', $mode, 'plugin_bbcode_size');
36    }
37
38    /** @inheritdoc */
39    public function postConnect()
40    {
41        $this->Lexer->addExitPattern('\[/size\]', 'plugin_bbcode_size');
42    }
43
44    /** @inheritdoc */
45    public function handle($match, $state, $pos, Doku_Handler $handler)
46    {
47        switch ($state) {
48            case DOKU_LEXER_ENTER:
49                $match = substr($match, 6, -1);
50                if (preg_match('/".+?"/', $match)) $match = substr($match, 1, -1); // addition #1: unquote
51                if (preg_match('/^[0-6]$/', $match)) {
52                    $match = $this->relsz(intval($match));
53                } elseif (preg_match('/^\d+$/', $match)) {
54                    $match .= 'px';
55                }
56                return [$state, $match];
57
58            case DOKU_LEXER_UNMATCHED:
59                return [$state, $match];
60
61            case DOKU_LEXER_EXIT:
62                return [$state, ''];
63        }
64        return [];
65    }
66
67    /** @inheritdoc */
68    public function render($format, Doku_Renderer $renderer, $data)
69    {
70        if ($format == 'xhtml') {
71            [$state, $match] = $data;
72            switch ($state) {
73                case DOKU_LEXER_ENTER:
74                    $renderer->doc .= '<span style="font-size:' . $renderer->_xmlEntities($match) . '">';
75                    break;
76
77                case DOKU_LEXER_UNMATCHED:
78                    $renderer->doc .= $renderer->_xmlEntities($match);
79                    break;
80
81                case DOKU_LEXER_EXIT:
82                    $renderer->doc .= '</span>';
83                    break;
84            }
85            return true;
86        }
87        return false;
88    }
89
90    /**
91     * Returns a relative-size CSS keyword based on numbering.
92     *
93     * Provides a mapping to the series of size-related keywords in CSS 2.1
94     * (http://www.w3.org/TR/REC-CSS1/#font-size)
95     * Valid values are [0-6], with 3 for "medium" (as recommended by standard)
96     *
97     * @param int $value The size value as a number (0-6)
98     * @return string|false The corresponding CSS keyword, or false if invalid
99     * @author Luis Machuca Bezzaza <luis.machuca@gulix.cl>
100     */
101    protected function relsz($value)
102    {
103        switch ($value) {
104            case 0:
105                return 'xx-small';
106            case 1:
107                return 'x-small';
108            case 2:
109                return 'small';
110            case 4:
111                return 'large';
112            case 5:
113                return 'x-large';
114            case 6:
115                return 'xx-large';
116            case 3:
117                return 'medium';
118            default:
119                return false;
120        }
121    }
122}
123