xref: /plugin/diagrams/syntax/embed.php (revision a561c5b18fa1bef7343a9999f88e1f2e9f88fcd8)
1<?php
2
3use dokuwiki\Logger;
4use dokuwiki\plugin\diagrams\Diagrams;
5use enshrined\svgSanitize\Sanitizer;
6
7/**
8 * DokuWiki Plugin diagrams (Syntax Component)
9 *
10 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
11 * @author  Innovakom + CosmoCode <dokuwiki@cosmocode.de>
12 */
13class syntax_plugin_diagrams_embed extends \dokuwiki\Extension\SyntaxPlugin
14{
15    /** @inheritDoc */
16    public function getType()
17    {
18        return 'substition';
19    }
20
21    /** @inheritDoc */
22    public function getPType()
23    {
24        return 'block';
25    }
26
27    /** @inheritDoc */
28    public function getSort()
29    {
30        return 319;
31    }
32
33    /** @inheritDoc */
34    public function connectTo($mode)
35    {
36        // only register if embed mode is enabled
37        if(!($this->getConf('mode') & Diagrams::MODE_EMBED)) return;
38
39        // auto load sanitizer
40        require_once __DIR__ . '/../vendor/autoload.php';
41        $this->Lexer->addSpecialPattern('<diagram(?: .*)?>.*?(?:</diagram>)', $mode, 'plugin_diagrams_embed');
42    }
43
44    /** @inheritDoc */
45    public function handle($match, $state, $pos, Doku_Handler $handler)
46    {
47        [$open, $rest] = sexplode('>', $match, 2);
48        $params = substr($open, 9);
49        $svg = substr($rest, 0, -10);
50
51        // embed positions
52        $svglen = strlen($svg);
53        $svgpos = $pos + strpos($match, '>');
54
55        /** @var helper_plugin_diagrams $helper */
56        $helper = plugin_load('helper', 'diagrams');
57        if(!$helper->isDiagram($svg)) return false;
58
59        // sanitize svg
60        $sanitizer = new Sanitizer();
61        $svg = $sanitizer->sanitize($svg);
62
63        if(!$svg) {
64            global $ID;
65            Logger::debug('diagrams: invalid SVG on '.$ID, $sanitizer->getXmlIssues());
66            return false;
67        }
68
69        $data = [
70            'svg' => $svg,
71            'align' => '',
72            'width' => '',
73            'height' => '',
74            'pos' => $svgpos,
75            'len' => $svglen,
76        ];
77
78        if (preg_match('/\b(left|right|center)\b/', $params, $matches)) {
79            $data['align'] = $matches[1];
80        }
81        if (preg_match('/\b(\d+)x(\d+)\b/', $params, $matches)) {
82            $data['width'] = (int)$matches[1];
83            $data['height'] = (int)$matches[2];
84        }
85
86        return $data;
87    }
88
89    /** @inheritDoc */
90    public function render($format, Doku_Renderer $renderer, $data)
91    {
92        if ($format !== 'xhtml') return false;
93        if(!$data) return false;
94
95        $style = '';
96        if($data['width'] && $data['height']) {
97            $style .= 'width: ' . $data['width'] . 'px; ';
98            $style .= 'height: ' . $data['height'] . 'px; ';
99            $class = 'fixedSize';
100        } else {
101            $class = 'autoSize';
102        }
103
104        $attr = [
105            'class' => "plugin_diagrams_embed $class media" . $data['align'],
106            'style' => $style,
107            'data-pos' => $data['pos'],
108            'data-len' => $data['len'],
109        ];
110
111        $tag = '<div %s>%s</div>';
112        $renderer->doc .= sprintf($tag, buildAttributes($attr), $data['svg']);
113
114        return true;
115    }
116}
117
118