18c8c7007SAndreas Gohr<?php 28c8c7007SAndreas Gohr 359e7180eSAndreas Gohruse dokuwiki\plugin\diagrams\Diagrams; 459e7180eSAndreas Gohr 58c8c7007SAndreas Gohr/** 68c8c7007SAndreas Gohr * Class syntax_plugin_diagrams 78c8c7007SAndreas Gohr */ 8fa6a636cSAndreas Gohrclass syntax_plugin_diagrams_mediafile extends DokuWiki_Syntax_Plugin 9fa6a636cSAndreas Gohr{ 108c8c7007SAndreas Gohr 118c8c7007SAndreas Gohr /** 128c8c7007SAndreas Gohr * @inheritdoc 138c8c7007SAndreas Gohr */ 148c8c7007SAndreas Gohr public function getType() 158c8c7007SAndreas Gohr { 168c8c7007SAndreas Gohr return 'substition'; 178c8c7007SAndreas Gohr } 188c8c7007SAndreas Gohr 198c8c7007SAndreas Gohr /** 208c8c7007SAndreas Gohr * @inheritdoc 218c8c7007SAndreas Gohr */ 228c8c7007SAndreas Gohr public function getSort() 238c8c7007SAndreas Gohr { 248c8c7007SAndreas Gohr return 319; 258c8c7007SAndreas Gohr } 268c8c7007SAndreas Gohr 278c8c7007SAndreas Gohr /** 288c8c7007SAndreas Gohr * @inheritdoc 298c8c7007SAndreas Gohr */ 308c8c7007SAndreas Gohr public function connectTo($mode) 318c8c7007SAndreas Gohr { 3259e7180eSAndreas Gohr // only register if mediafile mode is enabled 3359e7180eSAndreas Gohr if (!($this->getConf('mode') & Diagrams::MODE_MEDIA)) return; 3459e7180eSAndreas Gohr 35fa6a636cSAndreas Gohr // grab all SVG images 368c8c7007SAndreas Gohr $this->Lexer->addSpecialPattern('\{\{[^\}]+(?:\.svg)[^\}]*?\}\}', $mode, 'plugin_diagrams_mediafile'); 378c8c7007SAndreas Gohr } 388c8c7007SAndreas Gohr 398c8c7007SAndreas Gohr /** 408c8c7007SAndreas Gohr * Parse SVG syntax into media data 418c8c7007SAndreas Gohr * 428c8c7007SAndreas Gohr * @param string $match 438c8c7007SAndreas Gohr * @param int $state 448c8c7007SAndreas Gohr * @param int $pos 458c8c7007SAndreas Gohr * @param Doku_Handler $handler 468c8c7007SAndreas Gohr * @return array|bool 478c8c7007SAndreas Gohr */ 488c8c7007SAndreas Gohr public function handle($match, $state, $pos, Doku_Handler $handler) 498c8c7007SAndreas Gohr { 50046ca144SAndreas Gohr $data = Doku_Handler_Parse_Media($match); 51fa6a636cSAndreas Gohr 52fa6a636cSAndreas Gohr /** @var helper_plugin_diagrams $helper */ 53fa6a636cSAndreas Gohr $helper = plugin_load('helper', 'diagrams'); 54fa6a636cSAndreas Gohr if (!$data['type'] == 'internalmedia' || !$helper->isDiagramFile(mediaFN($data['src']))) { 55fa6a636cSAndreas Gohr // This is not a local diagrams file, but some other SVG media file 56e831c5ccSAnna Dabrowska $handler->media($match, $state, $pos); 57e831c5ccSAnna Dabrowska return false; 58fa6a636cSAndreas Gohr } 59fa6a636cSAndreas Gohr 60046ca144SAndreas Gohr $data['url'] = ml($data['src'], ['cache' => 'nocache'], true, '&'); 61046ca144SAndreas Gohr return $data; 628c8c7007SAndreas Gohr } 638c8c7007SAndreas Gohr 648c8c7007SAndreas Gohr /** 65ddc20d75SAnna Dabrowska * Handle rewrites made by the move plugin 66ddc20d75SAnna Dabrowska * 67ddc20d75SAnna Dabrowska * @param string $match 68ddc20d75SAnna Dabrowska * @param int $state 69ddc20d75SAnna Dabrowska * @param int $pos 70ddc20d75SAnna Dabrowska * @param string $plugin 71ddc20d75SAnna Dabrowska * @param helper_plugin_move_handler $handler 72ddc20d75SAnna Dabrowska * @return void 73ddc20d75SAnna Dabrowska */ 74ddc20d75SAnna Dabrowska public function handleMove($match, $state, $pos, $plugin, $handler) 75ddc20d75SAnna Dabrowska { 76ddc20d75SAnna Dabrowska if ($plugin !== 'diagrams_mediafile') return; 77ddc20d75SAnna Dabrowska 78ddc20d75SAnna Dabrowska $handler->media($match, $state, $pos); 79ddc20d75SAnna Dabrowska } 80ddc20d75SAnna Dabrowska 81ddc20d75SAnna Dabrowska /** 828c8c7007SAndreas Gohr * Render the diagram SVG as <object> instead of <img> to allow links, 838c8c7007SAndreas Gohr * except when rendering to a PDF 848c8c7007SAndreas Gohr * 858c8c7007SAndreas Gohr * @param string $format 868c8c7007SAndreas Gohr * @param Doku_Renderer $renderer 878c8c7007SAndreas Gohr * @param array $data 888c8c7007SAndreas Gohr * @return bool 898c8c7007SAndreas Gohr */ 908c8c7007SAndreas Gohr public function render($format, Doku_Renderer $renderer, $data) 918c8c7007SAndreas Gohr { 92ddc20d75SAnna Dabrowska if ($format === 'metadata') { 93ddc20d75SAnna Dabrowska $renderer->internalmedia($data['src']); 94ddc20d75SAnna Dabrowska return true; 95ddc20d75SAnna Dabrowska } 96ddc20d75SAnna Dabrowska if ($format !== 'xhtml') { 97ddc20d75SAnna Dabrowska return false; 98ddc20d75SAnna Dabrowska } 998c8c7007SAndreas Gohr 100*baaaacc0SAnna Dabrowska // check for cached PNG 101*baaaacc0SAnna Dabrowska $cachefile = $this->getCachedPNG($data); 102*baaaacc0SAnna Dabrowska 103c3c3f4cfSAndreas Gohr if (is_a($renderer, 'renderer_plugin_dw2pdf')) { 104c3c3f4cfSAndreas Gohr $imageAttributes = [ 1058c8c7007SAndreas Gohr 'class' => 'media', 10691ed8429SAndreas Gohr 'width' => empty($data['width']) ? '' : $data['width'], 10791ed8429SAndreas Gohr 'height' => empty($data['height']) ? '' : $data['height'], 10891ed8429SAndreas Gohr 'title' => $data['title'] ?? '', 109c3c3f4cfSAndreas Gohr 'align' => $data['align'], 110c3c3f4cfSAndreas Gohr 'src' => $data['url'], 111dce55f69SAndreas Gohr ]; 1125f757686SAndreas Gohr 113c3c3f4cfSAndreas Gohr // if a PNG cache exists, use it instead of the real URL 114*baaaacc0SAnna Dabrowska if ($cachefile) { 115*baaaacc0SAnna Dabrowska $imageAttributes['src'] = 'dw2pdf://' . $cachefile; 1163039104bSAndreas Gohr } 1172bec1a22SAndreas Gohr 1188c8c7007SAndreas Gohr $renderer->doc .= '<img ' . buildAttributes($imageAttributes) . '/>'; 1198c8c7007SAndreas Gohr } else { 120c3c3f4cfSAndreas Gohr $wrapperAttributes = []; 12179809d5dSAndreas Gohr $wrapperAttributes['title'] = $data['title'] ?? ''; 122c3c3f4cfSAndreas Gohr $wrapperAttributes['class'] = 'media diagrams-svg-wrapper media' . $data['align']; 123dce55f69SAndreas Gohr 124dce55f69SAndreas Gohr $imageAttributes = []; 125dce55f69SAndreas Gohr $imageAttributes['class'] = 'diagrams-svg'; 126046ca144SAndreas Gohr $imageAttributes['data'] = $data['url']; 12779809d5dSAndreas Gohr $imageAttributes['data-id'] = cleanID($data['src'] ?? ''); 128046ca144SAndreas Gohr $imageAttributes['type'] = 'image/svg+xml'; 12991ed8429SAndreas Gohr $imageAttributes['data-pos'] = $data['pos'] ?? ''; 13091ed8429SAndreas Gohr $imageAttributes['data-len'] = $data['len'] ?? ''; 13191ed8429SAndreas Gohr $imageAttributes['width'] = empty($data['width']) ? '' : $data['width']; 13291ed8429SAndreas Gohr $imageAttributes['height'] = empty($data['height']) ? '' : $data['height']; 1335f757686SAndreas Gohr 134*baaaacc0SAnna Dabrowska if ($cachefile) { 135*baaaacc0SAnna Dabrowska $imageAttributes['data-cached'] = str_replace(DOKU_INC, DOKU_URL, $cachefile); 136*baaaacc0SAnna Dabrowska } 137dce55f69SAndreas Gohr $image = sprintf('<object %s></object>', buildAttributes($imageAttributes, true)); 1380d9707b1SAnna Dabrowska $actionButtons = '<div class="diagrams-buttons"></div>'; 1390d9707b1SAnna Dabrowska $wrapper = sprintf('<div %s>%s%s</div>', buildAttributes($wrapperAttributes, true), $image, $actionButtons); 140dce55f69SAndreas Gohr $renderer->doc .= $wrapper; 1418c8c7007SAndreas Gohr } 1428c8c7007SAndreas Gohr 1438c8c7007SAndreas Gohr return true; 1448c8c7007SAndreas Gohr } 145*baaaacc0SAnna Dabrowska 146*baaaacc0SAnna Dabrowska /** 147*baaaacc0SAnna Dabrowska * PNG cache file, if caching is enabled and file exists 148*baaaacc0SAnna Dabrowska * 149*baaaacc0SAnna Dabrowska * @param array $data 150*baaaacc0SAnna Dabrowska * @return string 151*baaaacc0SAnna Dabrowska */ 152*baaaacc0SAnna Dabrowska protected function getCachedPNG($data) 153*baaaacc0SAnna Dabrowska { 154*baaaacc0SAnna Dabrowska if (!$this->getConf('pngcache')) return ''; 155*baaaacc0SAnna Dabrowska 156*baaaacc0SAnna Dabrowska if (!$data['svg']) $data['svg'] = file_get_contents(mediaFN($data['src'])); 157*baaaacc0SAnna Dabrowska $cachefile = getCacheName($data['svg'], '.diagrams.png'); 158*baaaacc0SAnna Dabrowska if (file_exists($cachefile)) return $cachefile; 159*baaaacc0SAnna Dabrowska 160*baaaacc0SAnna Dabrowska return ''; 161*baaaacc0SAnna Dabrowska } 1628c8c7007SAndreas Gohr} 163