Lexer->addSpecialPattern('\{\{comment>.+?\}\}', $mode, 'plugin_comment'); // Syntax for list of all comments $this->Lexer->addSpecialPattern('\{\{comments-list\}\}', $mode, 'plugin_comment'); } public function handle($match, $state, $pos, Doku_Handler $handler) { // Detect syntax type if ($match === '{{comments-list}}') { return array('type' => 'list'); } // Process comment $match = substr($match, 10, -2); // Remove {{comment> and }} // Split into parts by | $parts = explode('|', $match); $text = isset($parts[0]) ? trim($parts[0]) : ''; $comment = isset($parts[1]) ? trim($parts[1]) : ''; $status = 'open'; // Check status in third part if (isset($parts[2])) { $statusPart = trim($parts[2]); if (preg_match('/^status=(open|resolved|closed)$/i', $statusPart, $matches)) { $status = strtolower($matches[1]); } } return array( 'type' => 'comment', 'text' => $text, 'comment' => $comment, 'status' => $status ); } public function render($mode, Doku_Renderer $renderer, $data) { if ($mode !== 'xhtml') return false; // Render comments list if ($data['type'] === 'list') { $this->renderCommentsList($renderer); return true; } // Render individual comment self::$commentCounter++; $commentNum = self::$commentCounter; // Save comment for end-of-page list self::$comments[] = array( 'num' => $commentNum, 'text' => $data['text'], 'comment' => $data['comment'], 'status' => $data['status'] ); // CSS classes by status $statusClass = 'comment-' . $data['status']; // Emoji for status $statusEmoji = array( 'open' => '📬', 'resolved' => '✅', 'closed' => '❌' ); $emoji = isset($statusEmoji[$data['status']]) ? $statusEmoji[$data['status']] : '📬'; // Render highlighted text with comment number $renderer->doc .= ''; $renderer->doc .= hsc($data['text']); $renderer->doc .= '[💬' . $commentNum . ']'; $renderer->doc .= ''; // Side bubble with comment $renderer->doc .= ''; $renderer->doc .= '[' . $commentNum . '] '; $renderer->doc .= '' . $emoji . '
'; $renderer->doc .= hsc($data['comment']); $renderer->doc .= '
'; return true; } /** * Render list of all comments on the page */ protected function renderCommentsList($renderer) { if (empty(self::$comments)) { $renderer->doc .= '

There are no comments on this page.

'; return; } $renderer->doc .= '
'; $renderer->doc .= '

Comments on this page

'; foreach (self::$comments as $comment) { $statusClass = 'comment-' . $comment['status']; $renderer->doc .= ' '; } $renderer->doc .= '
'; } }