1<?php 2 3/** 4 * DokuWiki Plugin KaTeX (Action Component: setup) 5 * 6 * handle the data that has to be written into JSINFO, e.g. KaTeX options 7 * 8 * @license GPLv3 https://www.gnu.org/licenses/gpl-3.0.html 9 * @author H.-H. PENG (Hsins) <hsinspeng@gmail.com> 10 */ 11 12// must be run within Dokuwiki 13if ( !defined( 'DOKU_INC' ) ) { 14 die(); 15} 16 17use dokuwiki\Logger; 18 19class action_plugin_katex_setup extends DokuWiki_Action_Plugin 20{ 21 // Registers the handlers with DokuWiki's event controller 22 public function register( Doku_Event_Handler $controller ) 23 { 24 $controller->register_hook( 'DOKUWIKI_STARTED', 'BEFORE', $this, 'setup_options' ); 25 } 26 27 public function setup_options() 28 { 29 global $JSINFO; 30 31 $JSINFO['plugins']['katex']['options']['output'] = $this->_get_option_output(); 32 $JSINFO['plugins']['katex']['options']['delimiters'] = $this->_get_option_delimiters(); 33 $JSINFO['plugins']['katex']['options']['ignored-tags'] = $this->_get_option_ignored_tags(); 34 $JSINFO['plugins']['katex']['options']['ignored-classes'] = $this->_get_option_ignored_classes(); 35 $JSINFO['plugins']['katex']['options']['throwonerror'] = $this->_get_option_throwonerror(); 36 $JSINFO['plugins']['katex']['options']['error-color'] = $this->_get_option_error_color(); 37 $JSINFO['plugins']['katex']['options']['macros'] = $this->_get_option_macros(); 38 } 39 40 private function _get_option_output() 41 { 42 $conf_option_output = $this->getConf( 'option-output' ); 43 $value_option_output = $conf_option_output; 44 45 return $value_option_output; 46 } 47 48 private function _get_option_delimiters() 49 { 50 $DEFAULT_OPTION_DELIMITERS = array( 51 array( "left" => "$$", "right" => "$$", "display" => true ), 52 array( "left" => "$", "right" => "$", "display" => false ), 53 array( "left" => "\\[", "right" => "\\]", "display" => true ), 54 array( "left" => "\\(", "right" => "\\)", "display" => false ), 55 ); 56 $conf_option_delimiters = $this->getConf( 'option-delimiters' ); 57 58 try { 59 $value_option_delimiters = array_map( fn( $line ): array=> json_decode( str_replace( "\\", "\\\\", trim( $line ) ), true ), explode( "\n", trim( $conf_option_delimiters ) ) ); 60 if ( !$value_option_delimiters ) { 61 throw new Exception( 'Parsing Result is null' ); 62 } 63 } catch ( Throwable $e ) { 64 $log_title = '[KaTeX] Invalid Configuration Value ("option-delimiters")'; 65 $log_messages = "The configuration value shown below is invalid: 66 67 --- 68 {$conf_option_delimiters} 69 --- 70 71 The value of \"option-delimiters\" option should be mutiple lines of string in '{ \"left\": \"<LEFT_PATTERN>\", \"right\": \"<RIGHT_PATTERN>\", \"display\": \"<BOOLEAN>\" }'. 72 KaTeX plugin will fallback to the default value."; 73 Logger::error( $log_title, $log_messages, __FILE__, __LINE__ ); 74 75 $value_option_delimiters = $DEFAULT_OPTION_DELIMITERS; 76 } 77 78 return $value_option_delimiters; 79 } 80 81 private function _get_option_ignored_tags() 82 { 83 $DEFAULT_OPTION_IGNORED_TAGS = array( "script", "noscript", "style", "textarea", "pre", "code", "option" ); 84 $conf_option_ignored_tags = $this->getConf( 'option-ignored-tags' ); 85 86 try { 87 $value_option_ignored_tags = array_map( fn( $text ): string => trim( $text ), explode( ',', $conf_option_ignored_tags ) ); 88 if ( !$value_option_ignored_tags ) { 89 throw new Exception( 'Parsing Result is null' ); 90 } 91 } catch ( Throwable $e ) { 92 $log_title = '[KaTeX] Invalid Configuration Value ("option-ignored-tags")'; 93 $log_messages = "The configuration value shown below is invalid: 94 95 --- 96 {$conf_option_ignored_tags} 97 --- 98 99 The value of \"option-ignored-tags\" option should be a string containing tags separated by comma. e.g. \"script, style, textarea, pre, code\" 100 KaTeX plugin will fallback to the default value."; 101 Logger::error( $log_title, $log_messages, __FILE__, __LINE__ ); 102 103 $value_option_ignored_tags = $DEFAULT_OPTION_IGNORED_TAGS; 104 } 105 106 return $value_option_ignored_tags; 107 } 108 109 private function _get_option_ignored_classes() 110 { 111 $DEFAULT_OPTION_IGNORED_CLASSES = array( "" ); 112 $conf_option_ignored_classes = $this->getConf( 'option-ignored-classes' ); 113 114 try { 115 $value_option_ignored_classes = array_map( fn( $text ): string => trim( $text ), explode( ',', $conf_option_ignored_classes ) ); 116 if ( !$value_option_ignored_classes ) { 117 throw new Exception( 'Parsing Result is null' ); 118 } 119 } catch ( Throwable $e ) { 120 $log_title = '[KaTeX] Invalid Configuration Value ("option-ignored-tags")'; 121 $log_messages = "The configuration value shown below is invalid: 122 123 --- 124 {$conf_option_ignored_classes} 125 --- 126 127 The value of \"option-ignored-classes\" option should be a string containing tags separated by comma. e.g. \"code-mirror, annotation-box\" 128 KaTeX plugin will fallback to the default value."; 129 Logger::error( $log_title, $log_messages, __FILE__, __LINE__ ); 130 131 $value_option_ignored_classes = $DEFAULT_OPTION_IGNORED_CLASSES; 132 } 133 134 return $value_option_ignored_classes; 135 } 136 137 private function _get_option_throwonerror() 138 { 139 $conf_option_throwonerror = $this->getConf( 'option-throwonerror' ); 140 $value_option_throwonerror = boolval( $conf_option_throwonerror ); 141 142 return $value_option_throwonerror; 143 } 144 145 private function _get_option_error_color() 146 { 147 $DEFAULT_OPTION_ERROR_COLOR = '#CC0000'; 148 149 $conf_option_error_color = $this->getConf( 'option-error-color' ); 150 $value_option_error_color = trim( $conf_option_error_color ); 151 152 if ( !preg_match( '/^#(?:[0-9a-fA-F]{3}){1,2}$/i', $value_option_error_color ) ) { 153 $log_title = '[KaTeX] Invalid Configuration Value ("option-error-color")'; 154 $log_messages = "The configuration value shown below is invalid: 155 156 --- 157 {$conf_option_error_color} 158 --- 159 160 The value of \"option-error-color\" option should be in HEX3/HEX6 color code format. e.g. \"#04aa6d\" or \"#FFF\" 161 KaTeX plugin will fallback to the default value."; 162 Logger::error( $log_title, $log_messages, __FILE__, __LINE__ ); 163 164 $value_option_error_color = $DEFAULT_OPTION_ERROR_COLOR; 165 } 166 167 return $value_option_error_color; 168 } 169 170 private function _get_option_macros() 171 { 172 $DEFAULT_OPTION_MACROS = array( 173 "\\NN" => "\\mathbb{N}", 174 "\\ZZ" => "\\mathbb{Z}", 175 "\\QQ" => "\\mathbb{Q}", 176 "\\RR" => "\\mathbb{R}", 177 "\\CC" => "\\mathbb{C}", 178 ); 179 180 $conf_option_macros = $this->getConf( 'option-macros' ); 181 182 try { 183 $value_option_macros = array_column( array_map( fn( $line ): array=> json_decode( str_replace( "\\", "\\\\", trim( $line ) ), true ), explode( "\n", trim( $conf_option_macros ) ) ), 'expansion', 'command' ); 184 if ( !$value_option_macros ) { 185 throw new Exception( 'Parsing Result is null' ); 186 } 187 } catch ( Throwable $e ) { 188 $log_title = '[KaTeX] Invalid Configuration Value ("option-macros")'; 189 $log_messages = "The configuration value shown below is invalid: 190 191 --- 192 {$conf_option_macros} 193 --- 194 195 The value of \"option-macros\" option should be mutiple lines of string in '{ \"command\": \"<COMMAND>\", \"expansion\": \"<EXPANSION>\" }' format. 196 KaTeX plugin will fallback to the default value."; 197 Logger::error( $log_title, $log_messages, __FILE__, __LINE__ ); 198 199 $value_option_macros = $DEFAULT_OPTION_MACROS; 200 } 201 202 return $value_option_macros; 203 } 204} 205