xref: /dokuwiki/inc/Parsing/ParserMode/Acronym.php (revision 259e91d9cbe9e692d758265730a1b3b4f8e3f356)
1be906b56SAndreas Gohr<?php
2be906b56SAndreas Gohr
3be906b56SAndreas Gohrnamespace dokuwiki\Parsing\ParserMode;
4be906b56SAndreas Gohr
571096e46SAndreas Gohruse dokuwiki\Parsing\Handler;
6*259e91d9SAndreas Gohruse dokuwiki\Parsing\Lexer\Lexer;
771096e46SAndreas Gohr
8be906b56SAndreas Gohrclass Acronym extends AbstractMode
9be906b56SAndreas Gohr{
10bcaec9f4SAndreas Gohr    protected $acronyms = [];
11be906b56SAndreas Gohr    protected $pattern = '';
12be906b56SAndreas Gohr
13be906b56SAndreas Gohr    /**
14be906b56SAndreas Gohr     * Acronym constructor.
15be906b56SAndreas Gohr     *
16be906b56SAndreas Gohr     * @param string[] $acronyms
17be906b56SAndreas Gohr     */
18be906b56SAndreas Gohr    public function __construct($acronyms)
19be906b56SAndreas Gohr    {
20093fe67eSAndreas Gohr        usort($acronyms, $this->compare(...));
21be906b56SAndreas Gohr        $this->acronyms = $acronyms;
22be906b56SAndreas Gohr    }
23be906b56SAndreas Gohr
24be906b56SAndreas Gohr    /** @inheritdoc */
2571096e46SAndreas Gohr    public function getSort()
2671096e46SAndreas Gohr    {
2771096e46SAndreas Gohr        return 240;
2871096e46SAndreas Gohr    }
2971096e46SAndreas Gohr
3071096e46SAndreas Gohr    /** @inheritdoc */
31be906b56SAndreas Gohr    public function preConnect()
32be906b56SAndreas Gohr    {
33be906b56SAndreas Gohr        if (!count($this->acronyms)) return;
34be906b56SAndreas Gohr
35be906b56SAndreas Gohr        $bound = '[\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]';
36*259e91d9SAndreas Gohr        $acronyms = array_map(Lexer::escape(...), $this->acronyms);
37bcaec9f4SAndreas Gohr        $this->pattern = '(?<=^|' . $bound . ')(?:' . implode('|', $acronyms) . ')(?=' . $bound . ')';
38be906b56SAndreas Gohr    }
39be906b56SAndreas Gohr
40be906b56SAndreas Gohr    /** @inheritdoc */
41be906b56SAndreas Gohr    public function connectTo($mode)
42be906b56SAndreas Gohr    {
43be906b56SAndreas Gohr        if (!count($this->acronyms)) return;
44be906b56SAndreas Gohr
45093fe67eSAndreas Gohr        if ((string) $this->pattern !== '') {
46be906b56SAndreas Gohr            $this->Lexer->addSpecialPattern($this->pattern, $mode, 'acronym');
47be906b56SAndreas Gohr        }
48be906b56SAndreas Gohr    }
49be906b56SAndreas Gohr
50be906b56SAndreas Gohr    /** @inheritdoc */
5171096e46SAndreas Gohr    public function handle($match, $state, $pos, Handler $handler)
52be906b56SAndreas Gohr    {
5371096e46SAndreas Gohr        $handler->addCall('acronym', [$match], $pos);
5471096e46SAndreas Gohr        return true;
55be906b56SAndreas Gohr    }
56be906b56SAndreas Gohr
57be906b56SAndreas Gohr    /**
58*259e91d9SAndreas Gohr     * Sort callback to order by string length descending
59be906b56SAndreas Gohr     *
60be906b56SAndreas Gohr     * @param string $a
61be906b56SAndreas Gohr     * @param string $b
62be906b56SAndreas Gohr     * @return int
63be906b56SAndreas Gohr     */
64be906b56SAndreas Gohr    protected function compare($a, $b)
65be906b56SAndreas Gohr    {
66*259e91d9SAndreas Gohr        return strlen($b) <=> strlen($a);
67be906b56SAndreas Gohr    }
68be906b56SAndreas Gohr}
69