1<?php 2/** 3 * Automatically highlights configured keywords. 4 * Reads the keywords and their colors from a table on a user-defined wiki page. 5 * 6 * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 7 * @author Klaus Keusch <dev@klauskeusch.de> 8 */ 9 10if (!defined('DOKU_INC')) die(); 11 12class syntax_plugin_autocolor extends DokuWiki_Syntax_Plugin { 13 14 private $colorMap = null; 15 16 // DokuWiki core mispelling 17 public function getType() { return 'substition'; } 18 public function getSort() { return 300; } 19 20 public function connectTo($mode) { 21 $map = $this->getKeywordMap(); 22 if (empty($map)) return; 23 24 foreach (array_keys($map) as $word) { 25 $pattern = '\b' . preg_quote($word, '/') . '\b'; 26 $this->Lexer->addSpecialPattern($pattern, $mode, 'plugin_autocolor'); 27 } 28 } 29 30 public function handle($match, $state, $pos, Doku_Handler $handler) { 31 return array($match); 32 } 33 34 public function render($mode, Doku_Renderer $renderer, $data) { 35 if ($mode !== 'xhtml') return false; 36 37 $word = $data[0]; 38 $map = $this->getKeywordMap(); 39 40 $color = isset($map[$word]) ? $map[$word] : ''; 41 42 if ($color !== '') { 43 $renderer->doc .= '<span style="color: ' . htmlspecialchars($color, ENT_QUOTES, 'UTF-8') . ';">'; 44 $renderer->doc .= htmlspecialchars($word, ENT_QUOTES, 'UTF-8'); 45 $renderer->doc .= '</span>'; 46 } else { 47 $renderer->doc .= htmlspecialchars($word, ENT_QUOTES, 'UTF-8'); 48 } 49 return true; 50 } 51 52 /** 53 * Reads the DokuWiki table and creates the keyword mapping. 54 * The table should be defined on the page specified in the plugin configuration. 55 */ 56 private function getKeywordMap() { 57 if ($this->colorMap !== null) { 58 return $this->colorMap; 59 } 60 61 $this->colorMap = []; 62 $pageId = $this->getConf('config_page'); 63 64 if (!page_exists($pageId)) { 65 // Fallback 66 return [ 67 'DokuWiki' => '#0055b3', 68 'Fehler' => 'red' 69 ]; 70 } 71 72 $rawWikiText = rawWiki($pageId); 73 $lines = explode("\n", $rawWikiText); 74 75 foreach ($lines as $line) { 76 $line = trim($line); 77 78 // We ignore empty lines and header lines (those that start with ^) 79 // A valid data line in DokuWiki always starts with | for tables. 80 if ($line === '' || strpos($line, '|') !== 0) { 81 continue; 82 } 83 84 // Split based on |. 85 // Example: "| Keyword1, Keyword2 | #ff0000 |" 86 // Array index 0 is empty (before the first |), index 1 contains keywords, and index 2 contains the color. 87 $cells = explode('|', $line); 88 89 if (count($cells) >= 3) { 90 $keywordsRaw = $cells[1]; 91 $color = trim($cells[2]); 92 93 if ($color === '') continue; 94 95 // Split the comma-separated keywords in this table cell 96 $keywordsList = explode(',', $keywordsRaw); 97 foreach ($keywordsList as $keyword) { 98 $keyword = trim($keyword); 99 if ($keyword !== '') { 100 $this->colorMap[$keyword] = $color; 101 } 102 } 103 } 104 } 105 106 return $this->colorMap; 107 } 108}