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 { 92a5199261SAnna Dabrowska global $conf; 93a5199261SAnna Dabrowska 94ddc20d75SAnna Dabrowska if ($format === 'metadata') { 95ddc20d75SAnna Dabrowska $renderer->internalmedia($data['src']); 96ddc20d75SAnna Dabrowska return true; 97ddc20d75SAnna Dabrowska } 98ddc20d75SAnna Dabrowska if ($format !== 'xhtml') { 99ddc20d75SAnna Dabrowska return false; 100ddc20d75SAnna Dabrowska } 1018c8c7007SAndreas Gohr 102baaaacc0SAnna Dabrowska // check for cached PNG 103baaaacc0SAnna Dabrowska $cachefile = $this->getCachedPNG($data); 104baaaacc0SAnna Dabrowska 105c3c3f4cfSAndreas Gohr if (is_a($renderer, 'renderer_plugin_dw2pdf')) { 106c3c3f4cfSAndreas Gohr $imageAttributes = [ 1078c8c7007SAndreas Gohr 'class' => 'media', 10891ed8429SAndreas Gohr 'width' => empty($data['width']) ? '' : $data['width'], 10991ed8429SAndreas Gohr 'height' => empty($data['height']) ? '' : $data['height'], 11091ed8429SAndreas Gohr 'title' => $data['title'] ?? '', 11144b3af04SAnna Dabrowska 'alt' => $data['title'] ?? '', 112c3c3f4cfSAndreas Gohr 'align' => $data['align'], 113c3c3f4cfSAndreas Gohr 'src' => $data['url'], 114dce55f69SAndreas Gohr ]; 1155f757686SAndreas Gohr 116c3c3f4cfSAndreas Gohr // if a PNG cache exists, use it instead of the real URL 117*37a5d411SAnna Dabrowska // or display error if PNG of embedded diagram is missing 118baaaacc0SAnna Dabrowska if ($cachefile) { 119baaaacc0SAnna Dabrowska $imageAttributes['src'] = 'dw2pdf://' . $cachefile; 120*37a5d411SAnna Dabrowska } elseif ($this->getConf('pngcache') && is_a($this, 'syntax_plugin_diagrams_embed')) { 121*37a5d411SAnna Dabrowska $renderer->doc .= $this->getLang('errorMissingPNG'); 122*37a5d411SAnna Dabrowska return false; 1233039104bSAndreas Gohr } 1242bec1a22SAndreas Gohr 1258c8c7007SAndreas Gohr $renderer->doc .= '<img ' . buildAttributes($imageAttributes) . '/>'; 1268c8c7007SAndreas Gohr } else { 127c3c3f4cfSAndreas Gohr $wrapperAttributes = []; 12879809d5dSAndreas Gohr $wrapperAttributes['title'] = $data['title'] ?? ''; 129c3c3f4cfSAndreas Gohr $wrapperAttributes['class'] = 'media diagrams-svg-wrapper media' . $data['align']; 130dce55f69SAndreas Gohr 131dce55f69SAndreas Gohr $imageAttributes = []; 132dce55f69SAndreas Gohr $imageAttributes['class'] = 'diagrams-svg'; 133046ca144SAndreas Gohr $imageAttributes['data'] = $data['url']; 13479809d5dSAndreas Gohr $imageAttributes['data-id'] = cleanID($data['src'] ?? ''); 135046ca144SAndreas Gohr $imageAttributes['type'] = 'image/svg+xml'; 13691ed8429SAndreas Gohr $imageAttributes['data-pos'] = $data['pos'] ?? ''; 13791ed8429SAndreas Gohr $imageAttributes['data-len'] = $data['len'] ?? ''; 13891ed8429SAndreas Gohr $imageAttributes['width'] = empty($data['width']) ? '' : $data['width']; 13991ed8429SAndreas Gohr $imageAttributes['height'] = empty($data['height']) ? '' : $data['height']; 1405f757686SAndreas Gohr 141baaaacc0SAnna Dabrowska if ($cachefile) { 142e0dfc516SAnna Dabrowska // strip cache dir and our cache extension from data attribute 143e0dfc516SAnna Dabrowska $imageAttributes['data-pngcache'] = str_replace([$conf['cachedir'], Diagrams::CACHE_EXT], '', $cachefile); 144baaaacc0SAnna Dabrowska } 145a5199261SAnna Dabrowska 14620761fcfSAnna Dabrowska $image = sprintf('<object %s><span class="diagrams-alt">' . hsc($wrapperAttributes['title']) . '</span></object>', buildAttributes($imageAttributes, true)); 147a5199261SAnna Dabrowska // wrapper for action buttons 1480d9707b1SAnna Dabrowska $actionButtons = '<div class="diagrams-buttons"></div>'; 1490d9707b1SAnna Dabrowska $wrapper = sprintf('<div %s>%s%s</div>', buildAttributes($wrapperAttributes, true), $image, $actionButtons); 150dce55f69SAndreas Gohr $renderer->doc .= $wrapper; 1518c8c7007SAndreas Gohr } 1528c8c7007SAndreas Gohr 1538c8c7007SAndreas Gohr return true; 1548c8c7007SAndreas Gohr } 155baaaacc0SAnna Dabrowska 156baaaacc0SAnna Dabrowska /** 157e0dfc516SAnna Dabrowska * PNG cache file without extension, if caching is enabled and file exists. 1588893185bSAnna Dabrowska * Returns an empty string on older revisions (checking $REV), because 1598893185bSAnna Dabrowska * PNG caching does not support versioning. 160baaaacc0SAnna Dabrowska * 161baaaacc0SAnna Dabrowska * @param array $data 162baaaacc0SAnna Dabrowska * @return string 163baaaacc0SAnna Dabrowska */ 164baaaacc0SAnna Dabrowska protected function getCachedPNG($data) 165baaaacc0SAnna Dabrowska { 1668893185bSAnna Dabrowska global $REV; 1678893185bSAnna Dabrowska 1688893185bSAnna Dabrowska if (!$this->getConf('pngcache') || $REV) return ''; 169baaaacc0SAnna Dabrowska 17050de7869SAnna Dabrowska if (empty($data['svg'])) { 17150de7869SAnna Dabrowska $data['svg'] = file_get_contents(mediaFN($data['src'])); 17250de7869SAnna Dabrowska } 173e0dfc516SAnna Dabrowska $cachefile = getCacheName($data['svg'], Diagrams::CACHE_EXT); 174baaaacc0SAnna Dabrowska if (file_exists($cachefile)) return $cachefile; 175baaaacc0SAnna Dabrowska 176baaaacc0SAnna Dabrowska return ''; 177baaaacc0SAnna Dabrowska } 1788c8c7007SAndreas Gohr} 179