1<?php
2/**
3 * DokuWiki Plugin imapmarkers (Syntax Component)
4 *
5 * @license MIT https://en.wikipedia.org/wiki/MIT_License
6 * @author  Kai Thoene <k.git.thoene@gmx.net>
7 */
8class syntax_plugin_imapmarkers_reference extends \dokuwiki\Extension\SyntaxPlugin {
9  private const MATCH_IS_UNKNOWN = 0;
10  private const MATCH_IS_AREA = 1;
11  private const MATCH_IS_CONFIG = 2;
12  private const MATCH_IS_LOCATION = 3;
13
14  private bool $is_debug;
15  private string $component;
16
17  function __construct() {
18    $this->is_debug = false;
19    global $ID;
20    $this->component = sprintf("plugin_%s_%s", $this->getPluginName(), $this->getPluginComponent());
21    if ($this->is_debug) {
22      dbglog(sprintf("syntax_plugin_imapmarkers_reference.__construct ID='%s' COMPONENT='%s'", cleanID($ID), $this->getPluginComponent()));
23    }
24  }
25
26  //function getType(){ return 'substition';}
27  function getType() {
28    return 'formatting';
29  }
30  function getAllowedTypes() {
31    return array('formatting', 'substition', 'disabled');
32  }
33  function getPType() {
34    return 'normal';
35  }
36  function getSort() {
37    return 184;
38  }
39  // override default accepts() method to allow nesting - ie, to get the plugin accepts its own entry syntax
40  function accepts($mode) {
41    if ($mode == substr(get_class($this), 7))
42      return true;
43    return parent::accepts($mode);
44  }
45
46  /**
47   * Connect pattern to lexer
48   */
49  function connectTo($mode) {
50    $this->Lexer->addSpecialPattern('\{{2}(?i)IMAPMLOC>.+?\}{2}', $mode, $this->component);
51  }
52
53  /**
54   * Handle the match
55   */
56  function handle($match, $state, $pos, Doku_Handler $handler) {
57    $args = array($state);
58    switch ($state) {
59      case DOKU_LEXER_SPECIAL:
60        // check for marker location:
61        $is_correct = false;
62        $err_msg = "";
63        $matches = array();
64        $match = trim($match);
65        if ($this->is_debug) {
66          dbglog(sprintf("syntax_plugin_imapmarkers_reference.handle MATCH='%s' COMPONENT='%s'", $match, $this->getPluginComponent()));
67        }
68        if (preg_match("/\{{2}(?i)IMAPMLOC>\s*(.+?)\s*\|\s*(.+?)\s*\}{2}/", $match, $matches)) {
69          $loc_id = $matches[1];
70          $loc_title = $matches[2];
71          $is_correct = true;
72          $args = array($state, self::MATCH_IS_LOCATION, $is_correct, $err_msg, $loc_id, $loc_title);
73        } else {
74          $err_msg = sprintf("Malformed location! LOCATION='%s'", $match);
75          $args = array($state, self::MATCH_IS_UNKNOWN, $is_correct, $err_msg);
76        }
77        if ($this->is_debug) {
78          dbglog(sprintf("syntax_plugin_imapmarkers_reference.handle::DOKU_LEXER_SPECIAL: [%d] MATCH='%s'", $this->nr_imagemap_handler, $match));
79        }
80        break;
81      case DOKU_LEXER_UNMATCHED:
82        $handler->_addCall('cdata', array($match), $pos);
83        return false;
84    }
85    return $args;
86  }
87
88  /**
89   * Create output
90   */
91  function render($mode, Doku_Renderer $renderer, $data) {
92    if ($mode == 'xhtml') {
93      $state = $data[0];
94      static $has_content = false;
95      switch ($state) {
96        case DOKU_LEXER_SPECIAL:
97          if ($this->is_debug) {
98            dbglog(sprintf("syntax_plugin_imapmarkers.render::DOKU_LEXER_SPECIAL: [%d] DATA='%s'", $this->nr_imagemap_render, implode(", ", $data)));
99          }
100          $match_type = self::MATCH_IS_UNKNOWN;
101          $is_correct = false;
102          $err_msg = "";
103          list($state, $match_type, $is_correct, $err_msg) = $data;
104          if ($is_correct) {
105            switch ($match_type) {
106              case self::MATCH_IS_LOCATION:
107                list($state, $match_type, $is_correct, $err_msg, $loc_id, $loc_title) = $data;
108                $renderer->doc .= sprintf('<span class="imapmarkers imapmarkers-location" location_id="%s">%s</span>', $loc_id, $loc_title);
109                break;
110            }
111          } else {
112            $renderer->doc .= sprintf('  <br /><span style="color:white; background-color:red;">ERROR -- %s</span>%s', $err_msg, DOKU_LF);
113          }
114          break;
115      }
116    }
117    return true;
118  } // public function render
119}