xref: /dokuwiki/inc/Parsing/ParserMode/Acronym.php (revision 71096e46fcbfaeaa808667aba794e77fe2780169)
1<?php
2
3namespace dokuwiki\Parsing\ParserMode;
4
5use dokuwiki\Parsing\Handler;
6
7class Acronym extends AbstractMode
8{
9    // A list
10    protected $acronyms = [];
11    protected $pattern = '';
12
13    /**
14     * Acronym constructor.
15     *
16     * @param string[] $acronyms
17     */
18    public function __construct($acronyms)
19    {
20        usort($acronyms, $this->compare(...));
21        $this->acronyms = $acronyms;
22    }
23
24    /** @inheritdoc */
25    public function getSort()
26    {
27        return 240;
28    }
29
30    /** @inheritdoc */
31    public function preConnect()
32    {
33        if (!count($this->acronyms)) return;
34
35        $bound = '[\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]';
36        $acronyms = array_map(['\\dokuwiki\\Parsing\\Lexer\\Lexer', 'escape'], $this->acronyms);
37        $this->pattern = '(?<=^|' . $bound . ')(?:' . implode('|', $acronyms) . ')(?=' . $bound . ')';
38    }
39
40    /** @inheritdoc */
41    public function connectTo($mode)
42    {
43        if (!count($this->acronyms)) return;
44
45        if ((string) $this->pattern !== '') {
46            $this->Lexer->addSpecialPattern($this->pattern, $mode, 'acronym');
47        }
48    }
49
50    /** @inheritdoc */
51    public function handle($match, $state, $pos, Handler $handler)
52    {
53        $handler->addCall('acronym', [$match], $pos);
54        return true;
55    }
56
57    /**
58     * sort callback to order by string length descending
59     *
60     * @param string $a
61     * @param string $b
62     *
63     * @return int
64     */
65    protected function compare($a, $b)
66    {
67        $a_len = strlen($a);
68        $b_len = strlen($b);
69        if ($a_len > $b_len) {
70            return -1;
71        } elseif ($a_len < $b_len) {
72            return 1;
73        }
74
75        return 0;
76    }
77}
78