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