xref: /dokuwiki/inc/Parsing/ParserMode/Media.php (revision 95f694202286c1add4c442936a5caa38db0dd603)
1<?php
2
3namespace dokuwiki\Parsing\ParserMode;
4
5use dokuwiki\Parsing\Handler;
6use dokuwiki\Parsing\Helpers\Media as MediaHelper;
7
8class Media extends AbstractMode
9{
10    /** @inheritdoc */
11    public function getSort()
12    {
13        return 320;
14    }
15
16    /** @inheritdoc */
17    public function connectTo($mode)
18    {
19        // Word boundaries?
20        $this->Lexer->addSpecialPattern("\{\{(?:[^\}]|(?:\}[^\}]))+\}\}", $mode, 'media');
21    }
22
23    /** @inheritdoc */
24    public function handle($match, $state, $pos, Handler $handler)
25    {
26        $p = self::parseMedia($match);
27
28        $handler->addCall(
29            $p['type'],
30            [$p['src'], $p['title'], $p['align'], $p['width'], $p['height'], $p['cache'], $p['linking']],
31            $pos
32        );
33        return true;
34    }
35
36    /**
37     * Parse media syntax into its components
38     *
39     * @param string $match The full media syntax (e.g. {{image.png?200|title}})
40     * @return array Parsed media parameters (type, src, title, align, width, height, cache, linking)
41     */
42    public static function parseMedia($match)
43    {
44        // Strip the opening and closing markup
45        $link = preg_replace(['/^\{\{/', '/\}\}$/u'], '', $match);
46
47        // Split title from URL
48        $link = sexplode('|', $link, 2);
49
50        // Check alignment
51        $ralign = (bool)preg_match('/^ /', $link[0]);
52        $lalign = (bool)preg_match('/ $/', $link[0]);
53
54        // Logic = what's that ;)...
55        if ($lalign & $ralign) {
56            $align = 'center';
57        } elseif ($ralign) {
58            $align = 'right';
59        } elseif ($lalign) {
60            $align = 'left';
61        } else {
62            $align = null;
63        }
64
65        // The title...
66        if (!isset($link[1])) {
67            $link[1] = null;
68        }
69
70        //remove aligning spaces
71        $link[0] = trim($link[0]);
72
73        $p = MediaHelper::parseParameters($link[0]);
74
75        // Explicit param-derived alignment (?left/?right/?center) beats
76        // the whitespace-derived one — it's unambiguous and visible, and
77        // is the only form GfmMedia can express.
78        if ($p['align'] !== null) {
79            $align = $p['align'];
80        }
81
82        if (media_isexternal($p['src']) || link_isinterwiki($p['src'])) {
83            $call = 'externalmedia';
84        } else {
85            $call = 'internalmedia';
86        }
87
88        return [
89            'type' => $call,
90            'src' => $p['src'],
91            'title' => $link[1],
92            'align' => $align,
93            'width' => $p['width'],
94            'height' => $p['height'],
95            'cache' => $p['cache'],
96            'linking' => $p['linking']
97        ];
98    }
99}
100