*/ if (!defined('DOKU_INC')) { die(); } #declare(strict_types=1); use dokuwiki\Extension\SyntaxPlugin; use dokuwiki\Logger; include(dirname(__FILE__) . "/imapmarkers_simple_html_dom.php"); class syntax_plugin_imapmarkers_map extends \dokuwiki\Extension\SyntaxPlugin { private const MATCH_IS_UNKNOWN = 0; private const MATCH_IS_AREA = 1; private const MATCH_IS_CONFIG = 2; private const MATCH_IS_LOCATION = 3; private int $nr_imagemap_handler; private int $nr_imagemap_render; private array $a_areas; private array $a_cfg; private bool $is_debug; private string $component; function __construct() { $this->is_debug = false; global $ID; if ($this->is_debug) { dbglog(sprintf("syntax_plugin_imapmarkers_map.__construct ID='%s' PLUGIN='%s'", cleanID($ID), $this->getPluginName())); } $this->nr_imagemap_handler = -1; $this->nr_imagemap_render = -1; $this->a_areas = array(); $this->a_cfg = array(); $this->component = sprintf("plugin_%s_%s", $this->getPluginName(), $this->getPluginComponent()); } public function getType() { return 'container'; } public function getPType() { return 'block'; } public function getSort() { return 185; } public function getAllowedTypes() { return array('formatting', 'substition', 'disabled', 'protected', 'container', 'paragraphs'); } /** * Connect pattern to lexer */ public function connectTo($mode) { if ($mode == "base") { $this->Lexer->addEntryPattern('\{{2}(?i)IMAPMARKERS>[^\}]+\}{2}', $mode, $this->component); $this->Lexer->addPattern('\s*\{{2}(?i)CFG>\}{2}.*?\{{2}component); $this->Lexer->addPattern('\s*\[{2}.+?\]{2}\s*', $this->component); } } /** * Connect exit pattern to lexer */ public function postConnect() { $this->Lexer->addExitPattern('\{{2}<(?i)IMAPMARKERS\}{2}', $this->component); } /** * Handle the match */ public function handle($match, $state, $pos, Doku_Handler $handler) { global $conf; global $ID; $args = array($state); switch ($state) { case DOKU_LEXER_ENTER: $this->nr_imagemap_handler++; if ($this->is_debug) { dbglog(sprintf("syntax_plugin_imapmarkers_map.handle::DOKU_LEXER_ENTER: [%d] MATCH='%s' HANDLER='%s'", $this->nr_imagemap_handler, $match, substr($match, 14, -2))); } $img = Doku_Handler_Parse_Media(substr($match, 14, -2)); if ($this->is_debug) { dbglog(sprintf("syntax_plugin_imapmarkers_map.handle::DOKU_LEXER_ENTER: [%d] IMG='%s'", $this->nr_imagemap_handler, $img)); } $args = array($state, $img['type'], $img['src'], $img['title'], $img['align'], $img['width'], $img['height'], $img['cache']); if ($this->is_debug) { dbglog(sprintf("syntax_plugin_imapmarkers_map.handle::DOKU_LEXER_ENTER: ARGS=[ %s ]"), implode(", ", $args)); } break; case DOKU_LEXER_MATCHED: $is_correct = false; $is_match_ok = false; $err_msg = ""; $matches = array(); $match = trim($match); if ($this->is_debug) { dbglog(sprintf("syntax_plugin_imapmarkers_map.handle::DOKU_LEXER_MATCHED: [%d] MATCH='%s' POS=%s", $this->nr_imagemap_handler, $match, $pos)); } //---------- // check for area with or without identifier: if (preg_match("/\[{2}\s*([^|]*?)\s*\|\s*([^|]*?)\s*\|\s*([^|]*?)\s*@\s*([\d,\s]+)\s*\]{2}/", $match, $matches) or preg_match("/\[{2}\s*([^|]*?)\s*\|\s*([^|]*?)\s*@\s*([\d,\s]+)\s*\]{2}/", $match, $matches)) { switch (count($matches)) { case 5: // with identifier. $link = $matches[1]; $loc_id = $matches[2]; $text = $matches[3]; $coordinates = $matches[4]; $is_match_ok = true; break; case 4: // without identifier. $link = $matches[1]; $loc_id = ""; $text = $matches[2]; $coordinates = $matches[3]; $is_match_ok = true; break; default: $err_msg = sprintf("Invalid area! AREA='%s'", $match); } if ($is_match_ok) { $a_coords = explode(",", trim(strval($coordinates))); foreach ($a_coords as $key => $value) { $a_coords[$key] = intval(trim(strval($value))); } $num_coords = count($a_coords); switch ($num_coords) { case 3: case 4: case 6: $is_correct = true; break; default: if ((count($a_coords) >= 6) and ((count($a_coords) % 2) == 0)) { $is_correct = true; break; } $err_msg = sprintf("Invalid number of coordinates! COUNT=%d", count($a_coords)); } $a_coords_s = $is_correct ? implode(",", $a_coords) : "0,0,0,0,0,0"; $num_coords = $is_correct ? $num_coords : 6; $uri = $link; $classes = ""; if ($link != "") { // analyse link. $dokuwiki_link = sprintf("[[%s|%s]]", $link, $text); $rendered_result = $this->render_text($dokuwiki_link); $dom = imapmarkers\str_get_html($rendered_result); $a = $dom->find('a', 0); $uri = $a->href; $classes = $a->class; } if ($this->is_debug) { dbglog(sprintf("syntax_plugin_imapmarkers_map.handle::DOKU_LEXER_MATCHED: URL='%s' CLASS='%s'", $uri, $classes)); } $args = array($state, self::MATCH_IS_AREA, $is_correct, $err_msg, $link, $loc_id, $text, $num_coords, $a_coords_s, $uri, $classes); } break; } else { if (preg_match("/^\{{2}(?i)CFG>\}{2}\s*(.*?)\s*\{{2}nr_imagemap_render++; if ($this->is_debug) { dbglog(sprintf("syntax_plugin_imapmarkers_map.render::DOKU_LEXER_ENTER: [%d] DATA='%s'", $this->nr_imagemap_render, implode(", ", $data))); } list($state, $type, $src, $title, $align, $width, $height, $cache) = $data; if ($type == 'internalmedia') { $exists = null; resolve_mediaid(getNS($ID), $src, $exists); } $renderer->doc .= sprintf('

%s', $this->nr_imagemap_render, DOKU_LF); $src = ml($src, array('w' => $width, 'h' => $height, 'cache' => $cache)); $renderer->doc .= sprintf(' nr_imagemap_render, $align, $this->nr_imagemap_render); if ($align == 'right' || $align == 'left') $renderer->doc .= sprintf(' align="%s"', $align); if (!is_null($title)) { $title = $renderer->_xmlEntities($title); $renderer->doc .= sprintf(' title="%s" alt="%s"', $title, $title); } else { $renderer->doc .= ' alt=""'; } if (!is_null($width)) $renderer->doc .= sprintf(' width="%s"', $renderer->_xmlEntities($width)); if (!is_null($height)) $renderer->doc .= sprintf(' height="%s"', $renderer->_xmlEntities($height)); $renderer->doc .= sprintf(' />%s', DOKU_LF); $renderer->doc .= sprintf('

%s', DOKU_LF); break; case DOKU_LEXER_MATCHED: $match_type = self::MATCH_IS_UNKNOWN; $is_correct = false; $err_msg = ""; list($state, $match_type, $is_correct, $err_msg) = $data; if ($is_correct) { switch ($match_type) { case self::MATCH_IS_AREA: if (!array_key_exists($this->nr_imagemap_render, $this->a_areas)) { $this->a_areas[$this->nr_imagemap_render] = array(); } array_push($this->a_areas[$this->nr_imagemap_render], $data); break; case self::MATCH_IS_CONFIG: if (!array_key_exists($this->nr_imagemap_render, $this->a_cfg)) { $this->a_cfg[$this->nr_imagemap_render] = array(); } array_push($this->a_cfg[$this->nr_imagemap_render], $data); break; } if ($this->is_debug) { dbglog(sprintf("syntax_plugin_imapmarkers_map.render::DOKU_LEXER_MATCHED: [%d] DATA='%s'", $this->nr_imagemap_render, implode(", ", $data))); } } else { $renderer->doc .= sprintf('
ERROR -- %s%s', $err_msg, DOKU_LF); } break; case DOKU_LEXER_UNMATCHED: if ($this->is_debug) { dbglog(sprintf("syntax_plugin_imapmarkers_map.render::DOKU_LEXER_UNMATCHED: [%d] DATA='%s'", $this->nr_imagemap_render, implode(", ", $data))); } break; case DOKU_LEXER_EXIT: $is_all_ok = true; $err_msg = ""; $nr_areas = 0; $nr_cfgs = 0; if (array_key_exists($this->nr_imagemap_render, $this->a_areas)) { $nr_areas = count($this->a_areas[$this->nr_imagemap_render]); } if (array_key_exists($this->nr_imagemap_render, $this->a_cfg)) { $nr_cfgs = 1; } if ($this->is_debug) { dbglog(sprintf("syntax_plugin_imapmarkers_map.render::DOKU_LEXER_EXIT: [%d] DATA='%s' #AREAS=%d #CFGS=%d", $this->nr_imagemap_render, implode(", ", $data), $nr_areas, $nr_cfgs)); } if ($nr_areas > 0) { foreach ($this->a_areas[$this->nr_imagemap_render] as $value) { list($state, $match_type, $is_correct, $err_msg) = $value; if (!$is_correct) { $renderer->doc .= sprintf('
ERROR -- %s%s', $err_msg, DOKU_LF); $is_all_ok = false; } } if ($is_all_ok) { $renderer->doc .= sprintf(' %s', $this->nr_imagemap_render, DOKU_LF); foreach ($this->a_areas[$this->nr_imagemap_render] as $key => $value) { list($state, $match_type, $is_correct, $err_msg, $link, $loc_id, $text, $num_coords, $a_coords_s, $uri, $classes) = $value; $link = ($link == "") ? "#" : $link; $shape = ""; switch ($num_coords) { case 3: $shape = "circle"; break; case 4: $shape = "rect"; break; default: $shape = "poly"; } $renderer->doc .= sprintf(' %s%s', $this->nr_imagemap_render, $key, $loc_id, $shape, $a_coords_s, $text, $text, $uri, DOKU_LF); } $renderer->doc .= sprintf(' %s', DOKU_LF); $renderer->doc .= sprintf(' %s', DOKU_LF); } } if ($nr_cfgs == 1) { foreach ($this->a_cfg[$this->nr_imagemap_render] as $value) { list($state, $match_type, $is_correct, $err_msg) = $value; if (!$is_correct) { $renderer->doc .= sprintf('
ERROR -- %s%s', $err_msg, DOKU_LF); $is_all_ok = false; } } if ($is_all_ok) { foreach ($this->a_cfg[$this->nr_imagemap_render] as $key => $value) { list($state, $match_type, $is_correct, $err_msg, $cfg) = $value; $renderer->doc .= sprintf(' %s', $this->nr_imagemap_render, $cfg, DOKU_LF); } } } break; } } return true; } // public function render } // class syntax_plugin_imapmarkers_map