"> //
// ... base64 encoded xml //
//
//
... rendered herein
//
// class syntax_plugin_bpmnio_bpmnio extends SyntaxPlugin { protected string $type = ''; // 'bpmn' or 'dmn' protected string $src = ''; // media file protected string $zoom = ''; // optional scaling factor private function loadLinkProcessor(): void { require_once __DIR__ . '/../inc/link_processor.php'; } public function getPType(): string { return 'block'; } public function getType(): string { return 'protected'; } public function getSort(): int { return 0; } public function connectTo($mode): void { $this->Lexer->addEntryPattern('(?=.*?)', $mode, 'plugin_bpmnio_bpmnio'); } public function postConnect(): void { $this->Lexer->addExitPattern('', 'plugin_bpmnio_bpmnio'); } public function handle($match, $state, $pos, Doku_Handler $handler): array { switch ($state) { case DOKU_LEXER_ENTER: $matched = []; preg_match('/]+)>/', $match, $matched); $attrs = []; if (!empty($matched[1])) { $attrs = $this->buildAttributes($matched[1]); } $this->type = $attrs['type'] ?? 'bpmn'; $this->src = $attrs['src'] ?? ''; $this->zoom = $this->normalizeZoom($attrs['zoom'] ?? null) ?? ''; return [$state, $this->type, '', $pos, '', false, $this->zoom]; case DOKU_LEXER_UNMATCHED: $posStart = $pos; $posEnd = $pos + strlen($match); $inline = empty($this->src); if (!$inline) { $match = $this->getMedia($this->src); } return [$state, $this->type, base64_encode($match), $posStart, $posEnd, $inline, $this->zoom]; case DOKU_LEXER_EXIT: $this->type = ''; $this->src = ''; $this->zoom = ''; return [$state, '', '', '', '', '', false, '']; } return []; } private function buildAttributes($string) { $attrs = []; preg_match_all('/(\w+)=["\'](.*?)["\']/', $string, $matches, PREG_SET_ORDER); foreach ($matches as $match) { $attrs[$match[1]] = $match[2]; } return $attrs; } private function normalizeZoom($zoom): ?string { if ($zoom === null || $zoom === '') { return null; } if (!is_numeric($zoom)) { return null; } $zoom = (float) $zoom; if ($zoom <= 0) { return null; } return rtrim(rtrim(number_format($zoom, 4, '.', ''), '0'), '.'); } private function getMedia($src) { global $ID; $id = (new MediaResolver($ID))->resolveId($src); if (auth_quickaclcheck($id) < AUTH_READ) { return "Error: Access denied for file $src"; } $file = mediaFN($id); if (!file_exists($file) || !is_readable($file)) { return "Error: Cannot load file $src"; } return file_get_contents($file); } public function render($mode, Doku_Renderer $renderer, $data): bool { [$state, $type, $match, $posStart, $posEnd, $inline, $zoom] = array_pad($data, 7, ''); if (is_a($renderer, 'renderer_plugin_dw2pdf')) { if ($state == DOKU_LEXER_EXIT) { $renderer->doc .= << DW2PDF support missing: Help wanted HTML; } return true; } if ($mode == 'xhtml' || $mode == 'odt') { switch ($state) { case DOKU_LEXER_ENTER: $bpmnid = "__{$type}_js_{$posStart}"; $renderer->doc .= << HTML; break; case DOKU_LEXER_UNMATCHED: $xml = base64_decode($match, true); if ($xml === false) { $xml = $match; } $this->loadLinkProcessor(); $payload = plugin_bpmnio_link_processor::buildPayload($xml); $encodedXml = base64_encode($payload['xml']); $encodedLinks = base64_encode(json_encode($payload['links'])); $renderer->doc .= << {$encodedXml} HTML; if ($inline) { $target = "plugin_bpmnio_{$type}"; $sectionEditData = ['target' => $target]; $class = $renderer->startSectionEdit($posStart, $sectionEditData); } else { $class = ''; } $zoomAttr = $zoom !== '' ? " data-zoom=\"{$zoom}\"" : ''; $renderer->doc .= <<
HTML; if ($inline) { $renderer->finishSectionEdit($posEnd); } break; case DOKU_LEXER_EXIT: $renderer->doc .= << HTML; break; } return true; } return false; } }