xref: /dokuwiki/inc/Parsing/ParserMode/Acronym.php (revision 504c13e8df88563c11b3720b317991bc38835a35)
1<?php
2
3namespace dokuwiki\Parsing\ParserMode;
4
5use dokuwiki\Parsing\Handler;
6use dokuwiki\Parsing\Lexer\Lexer;
7
8class Acronym extends AbstractMode
9{
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(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     * @return int
63     */
64    protected function compare($a, $b)
65    {
66        return strlen($b) <=> strlen($a);
67    }
68}
69