xref: /plugin/diagrams/syntax/embed.php (revision 59e7180efcc3e125683f24f98a466ef29145cfce)
18a822cc1SAndreas Gohr<?php
28a822cc1SAndreas Gohr
3100ff2a5SAndreas Gohruse dokuwiki\Logger;
4bc39777fSAndreas Gohruse dokuwiki\plugin\diagrams\Diagrams;
5100ff2a5SAndreas Gohruse enshrined\svgSanitize\Sanitizer;
6bc39777fSAndreas Gohr
78a822cc1SAndreas Gohr/**
88c8c7007SAndreas Gohr * DokuWiki Plugin diagrams (Syntax Component)
98c8c7007SAndreas Gohr *
108c8c7007SAndreas Gohr * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
118c8c7007SAndreas Gohr * @author  Innovakom + CosmoCode <dokuwiki@cosmocode.de>
128a822cc1SAndreas Gohr */
138c8c7007SAndreas Gohrclass syntax_plugin_diagrams_embed extends \dokuwiki\Extension\SyntaxPlugin
148c8c7007SAndreas Gohr{
158c8c7007SAndreas Gohr    /** @inheritDoc */
168a822cc1SAndreas Gohr    public function getType()
178a822cc1SAndreas Gohr    {
188a822cc1SAndreas Gohr        return 'substition';
198a822cc1SAndreas Gohr    }
208a822cc1SAndreas Gohr
218c8c7007SAndreas Gohr    /** @inheritDoc */
228c8c7007SAndreas Gohr    public function getPType()
238c8c7007SAndreas Gohr    {
248c8c7007SAndreas Gohr        return 'block';
258c8c7007SAndreas Gohr    }
268c8c7007SAndreas Gohr
278c8c7007SAndreas Gohr    /** @inheritDoc */
288a822cc1SAndreas Gohr    public function getSort()
298a822cc1SAndreas Gohr    {
308a822cc1SAndreas Gohr        return 319;
318a822cc1SAndreas Gohr    }
328a822cc1SAndreas Gohr
338c8c7007SAndreas Gohr    /** @inheritDoc */
348a822cc1SAndreas Gohr    public function connectTo($mode)
358a822cc1SAndreas Gohr    {
36bc39777fSAndreas Gohr        // only register if embed mode is enabled
37*59e7180eSAndreas Gohr        if(!($this->getConf('mode') & Diagrams::MODE_EMBED)) return;
38bc39777fSAndreas Gohr
39100ff2a5SAndreas Gohr        // auto load sanitizer
40100ff2a5SAndreas Gohr        require_once __DIR__ . '/../vendor/autoload.php';
418c8c7007SAndreas Gohr        $this->Lexer->addSpecialPattern('<diagram(?: .*)?>.*?(?:</diagram>)', $mode, 'plugin_diagrams_embed');
428a822cc1SAndreas Gohr    }
438a822cc1SAndreas Gohr
448c8c7007SAndreas Gohr    /** @inheritDoc */
458a822cc1SAndreas Gohr    public function handle($match, $state, $pos, Doku_Handler $handler)
468a822cc1SAndreas Gohr    {
478c8c7007SAndreas Gohr        [$open, $rest] = sexplode('>', $match, 2);
488c8c7007SAndreas Gohr        $params = substr($open, 9);
498c8c7007SAndreas Gohr        $svg = substr($rest, 0, -10);
508c8c7007SAndreas Gohr
51317bdfc2SAndreas Gohr        // embed positions
52317bdfc2SAndreas Gohr        $svglen = strlen($svg);
53317bdfc2SAndreas Gohr        $svgpos = $pos + strpos($match, '>');
54317bdfc2SAndreas Gohr
5595ed8ca0SAndreas Gohr        /** @var helper_plugin_diagrams $helper */
5695ed8ca0SAndreas Gohr        $helper = plugin_load('helper', 'diagrams');
5795ed8ca0SAndreas Gohr        if(!$helper->isDiagram($svg)) return false;
5895ed8ca0SAndreas Gohr
59100ff2a5SAndreas Gohr        // sanitize svg
60100ff2a5SAndreas Gohr        $sanitizer = new Sanitizer();
61100ff2a5SAndreas Gohr        $svg = $sanitizer->sanitize($svg);
62100ff2a5SAndreas Gohr
63100ff2a5SAndreas Gohr        if(!$svg) {
64100ff2a5SAndreas Gohr            global $ID;
65100ff2a5SAndreas Gohr            Logger::debug('diagrams: invalid SVG on '.$ID, $sanitizer->getXmlIssues());
66100ff2a5SAndreas Gohr            return false;
67100ff2a5SAndreas Gohr        }
68100ff2a5SAndreas Gohr
698c8c7007SAndreas Gohr        $data = [
708c8c7007SAndreas Gohr            'svg' => $svg,
718c8c7007SAndreas Gohr            'align' => '',
728c8c7007SAndreas Gohr            'width' => '',
738c8c7007SAndreas Gohr            'height' => '',
74317bdfc2SAndreas Gohr            'pos' => $svgpos,
75317bdfc2SAndreas Gohr            'len' => $svglen,
768c8c7007SAndreas Gohr        ];
778c8c7007SAndreas Gohr
788c8c7007SAndreas Gohr        if (preg_match('/\b(left|right|center)\b/', $params, $matches)) {
798c8c7007SAndreas Gohr            $data['align'] = $matches[1];
808c8c7007SAndreas Gohr        }
818c8c7007SAndreas Gohr        if (preg_match('/\b(\d+)x(\d+)\b/', $params, $matches)) {
828c8c7007SAndreas Gohr            $data['width'] = (int)$matches[1];
838c8c7007SAndreas Gohr            $data['height'] = (int)$matches[2];
848a822cc1SAndreas Gohr        }
858a822cc1SAndreas Gohr
868c8c7007SAndreas Gohr        return $data;
878c8c7007SAndreas Gohr    }
888c8c7007SAndreas Gohr
898c8c7007SAndreas Gohr    /** @inheritDoc */
908a822cc1SAndreas Gohr    public function render($format, Doku_Renderer $renderer, $data)
918a822cc1SAndreas Gohr    {
928a822cc1SAndreas Gohr        if ($format !== 'xhtml') return false;
93100ff2a5SAndreas Gohr        if(!$data) return false;
948c8c7007SAndreas Gohr
958c8c7007SAndreas Gohr        $style = '';
96100ff2a5SAndreas Gohr        if($data['width'] && $data['height']) {
97100ff2a5SAndreas Gohr            $style .= 'width: ' . $data['width'] . 'px; ';
98100ff2a5SAndreas Gohr            $style .= 'height: ' . $data['height'] . 'px; ';
99100ff2a5SAndreas Gohr            $class = 'fixedSize';
100100ff2a5SAndreas Gohr        } else {
101100ff2a5SAndreas Gohr            $class = 'autoSize';
102100ff2a5SAndreas Gohr        }
1038c8c7007SAndreas Gohr
104100ff2a5SAndreas Gohr        $attr = [
105100ff2a5SAndreas Gohr            'class' => "plugin_diagrams_embed $class media" . $data['align'],
106100ff2a5SAndreas Gohr            'style' => $style,
107100ff2a5SAndreas Gohr            'data-pos' => $data['pos'],
108100ff2a5SAndreas Gohr            'data-len' => $data['len'],
109100ff2a5SAndreas Gohr        ];
110100ff2a5SAndreas Gohr
111100ff2a5SAndreas Gohr        $tag = '<div %s>%s</div>';
112100ff2a5SAndreas Gohr        $renderer->doc .= sprintf($tag, buildAttributes($attr), $data['svg']);
1138a822cc1SAndreas Gohr
1148a822cc1SAndreas Gohr        return true;
1158a822cc1SAndreas Gohr    }
1168a822cc1SAndreas Gohr}
1178c8c7007SAndreas Gohr
118