xref: /dokuwiki/inc/Parsing/ParserMode/Acronym.php (revision 71096e46fcbfaeaa808667aba794e77fe2780169)
1be906b56SAndreas Gohr<?php
2be906b56SAndreas Gohr
3be906b56SAndreas Gohrnamespace dokuwiki\Parsing\ParserMode;
4be906b56SAndreas Gohr
5*71096e46SAndreas Gohruse dokuwiki\Parsing\Handler;
6*71096e46SAndreas Gohr
7be906b56SAndreas Gohrclass Acronym extends AbstractMode
8be906b56SAndreas Gohr{
9be906b56SAndreas Gohr    // A list
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 */
25*71096e46SAndreas Gohr    public function getSort()
26*71096e46SAndreas Gohr    {
27*71096e46SAndreas Gohr        return 240;
28*71096e46SAndreas Gohr    }
29*71096e46SAndreas Gohr
30*71096e46SAndreas 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]';
36be906b56SAndreas Gohr        $acronyms = array_map(['\\dokuwiki\\Parsing\\Lexer\\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 */
51*71096e46SAndreas Gohr    public function handle($match, $state, $pos, Handler $handler)
52be906b56SAndreas Gohr    {
53*71096e46SAndreas Gohr        $handler->addCall('acronym', [$match], $pos);
54*71096e46SAndreas Gohr        return true;
55be906b56SAndreas Gohr    }
56be906b56SAndreas Gohr
57be906b56SAndreas Gohr    /**
58be906b56SAndreas Gohr     * sort callback to order by string length descending
59be906b56SAndreas Gohr     *
60be906b56SAndreas Gohr     * @param string $a
61be906b56SAndreas Gohr     * @param string $b
62be906b56SAndreas Gohr     *
63be906b56SAndreas Gohr     * @return int
64be906b56SAndreas Gohr     */
65be906b56SAndreas Gohr    protected function compare($a, $b)
66be906b56SAndreas Gohr    {
67be906b56SAndreas Gohr        $a_len = strlen($a);
68be906b56SAndreas Gohr        $b_len = strlen($b);
69be906b56SAndreas Gohr        if ($a_len > $b_len) {
70be906b56SAndreas Gohr            return -1;
71be906b56SAndreas Gohr        } elseif ($a_len < $b_len) {
72be906b56SAndreas Gohr            return 1;
73be906b56SAndreas Gohr        }
74be906b56SAndreas Gohr
75be906b56SAndreas Gohr        return 0;
76be906b56SAndreas Gohr    }
77be906b56SAndreas Gohr}
78