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