1<?php 2 3class syntax_plugin_codeprism_codeprism extends DokuWiki_Syntax_Plugin 4{ 5 protected $entry_pattern = '<codeprism\b.*?>(?=.*?</codeprism>)'; 6 protected $exit_pattern = '</codeprism>'; 7 protected $match_pattern = '/<codeprism (.+?)( \[(.+?)\])* *>/'; 8 9 public function gettype() 10 { 11 return 'substition'; 12 } 13 14 public function getSort() 15 { 16 return 190; 17 } 18 19 public function connectTo($mode) 20 { 21 $this->Lexer->addEntryPattern($this->entry_pattern, $mode, 'plugin_codeprism_codeprism'); 22 } 23 24 public function postConnect() 25 { 26 $this->Lexer->addExitPattern($this->exit_pattern, 'plugin_codeprism_codeprism'); 27 } 28 29 public function handle($match, $state, $pos, Doku_Handler $handler) 30 { 31 if (isset($_REQUEST['comment'])) return false; 32 33 $pre_opt_arr['css'] = 'dft'; 34 35 if ($state == DOKU_LEXER_ENTER) { 36 /** Default attributes. */ 37 if ($this->getConf('hl-brace')) { 38 $code_opt_arr['match-braces'] = 'match-braces'; 39 } 40 41 if ($this->getConf('user')) { 42 $pre_opt_arr['data-user'] = $this->getConf('user'); 43 } 44 45 if ($this->getConf('host')) { 46 $pre_opt_arr['data-host'] = $this->getConf('host'); 47 } 48 49 preg_match_all($this->match_pattern, "{$match}", $chunks, PREG_SET_ORDER); 50 51 if (!empty($chunks)) { 52 $chunk = $chunks[0]; 53 54 $basic_option = preg_split('/\s+/', trim($chunk[1])); 55 56 /**chunk[1]: php title sl=* el=* ... */ 57 /** Fit <code> syntax */ 58 if ($basic_option[0] && false == strpos($basic_option[0], '=')) { 59 if ($basic_option[0] != '.') { 60 $pre_opt_arr['data-language'] = $basic_option[0]; 61 $code_opt_arr['lang'] = $basic_option[0]; 62 } 63 64 unset($basic_option[0]); 65 } 66 67 if ($basic_option[1] && false == strpos($basic_option[1], '=')) { 68 if ($basic_option[1] != '.') { 69 $pre_opt_arr['data-label'] = $key_val[1]; 70 } 71 72 unset($basic_option[1]); 73 } 74 75 foreach($basic_option as $opt) { 76 $key_val = preg_split('/=/', $opt); 77 78 switch ($key_val[0]) { 79 /** Parse <codeprism> syntax. */ 80 case 'sl': 81 $pre_opt_arr['data-start'] = $key_val[1]; 82 $pre_opt_arr['data-line-offset'] = $key_val[1]; 83 break; 84 85 case 'hl': 86 $pre_opt_arr['data-line'] = $key_val[1]; 87 break; 88 89 case 'el': 90 $pre_opt_arr['line-numbers'] = 'line-numbers'; 91 break; 92 93 case 'lang': 94 $pre_opt_arr['data-language'] = $key_val[1]; 95 $code_opt_arr['lang'] = $key_val[1]; 96 break; 97 98 case 'cmd': 99 $pre_opt_arr['command-line'] = 'command-line'; 100 break; 101 102 case 'cmdout': 103 $pre_opt_arr['data-output'] = $key_val[1]; 104 $pre_opt_arr['command-line'] = 'command-line'; 105 break; 106 107 case 'user': 108 $pre_opt_arr['data-user'] = $key_val[1]; 109 break; 110 111 case 'host': 112 $pre_opt_arr['data-host'] = $key_val[1]; 113 break; 114 115 case 'css': 116 $pre_opt_arr['css'] = $key_val[1]; 117 break; 118 119 /** Parse <fileprism> syntax. */ 120 case 'src': 121 $pre_opt_arr['data-src'] = DOKU_BASE. 'lib/exe/fetch.php?media=' . $key_val[1]; 122 break; 123 124 case 'range': 125 $pre_opt_arr['data-range'] = $key_val[1]; 126 break; 127 128 case 'title': 129 $pre_opt_arr['data-label'] = $key_val[1]; 130 break; 131 } 132 } 133 134 /**chunk[2]: [attr0="val0", attr1="val1", ...] */ 135 $extend_option = trim($chunk[2]); 136 137 preg_match_all('/([\w-]+?)="(.*?)"/', "$extend_option", $extend_arr, PREG_SET_ORDER); 138 139 foreach ($extend_arr as $key_val) { 140 switch ($key_val[1]) { 141 case 'start_line_numbers_at': 142 $pre_opt_arr['data-start'] = $key_val[2]; 143 $pre_opt_arr['data-line-offset'] = $key_val[2]; 144 break; 145 146 case 'enable_line_numbers': 147 $pre_opt_arr['line-numbers'] = 'line-numbers'; 148 break; 149 150 case 'highlight_lines_extra': 151 $pre_opt_arr['data-line'] = $key_val[2]; 152 break; 153 154 default: 155 $pre_opt_arr[$key_val[1]] = $key_val[2]; 156 break; 157 } 158 } 159 } 160 161 /* `data-user` & `data-host` should be only used in command line. */ 162 if (!$pre_opt_arr['command-line']) { 163 unset($pre_opt_arr['data-user']); 164 unset($pre_opt_arr['data-host']); 165 } 166 167 return array($state, $pre_opt_arr, $code_opt_arr); 168 } 169 170 return array($state, $match); 171 } 172 173 public function render($mode, Doku_Renderer $renderer, $data) 174 { 175 if ($mode != 'xhtml') return false; 176 177 list($state) = $data; 178 179 switch ($state) { 180 case DOKU_LEXER_ENTER: 181 list(, $pre_opt_arr, $code_opt_arr) = $data; 182 183 $renderer->doc .= '<pre class="dokuwiki-plugin-codeprism-'.$pre_opt_arr['css'].' '.$pre_opt_arr['line-numbers'].' '.$pre_opt_arr['command-line'] . '"'; 184 unset($pre_opt_arr['line-numbers']); 185 unset($pre_opt_arr['command-line']); 186 unset($pre_opt_arr['css']); 187 188 foreach($pre_opt_arr as $key => $val) { 189 $renderer->doc .= ' ' . $key . '="' . $val . '"'; 190 } 191 192 $renderer->doc .='>'; 193 $renderer->doc .='<code class="language-'. $code_opt_arr['lang'] . ' ' . $code_opt_arr['match-braces'] . '">'; 194 break; 195 196 case DOKU_LEXER_UNMATCHED: 197 list(, $code) = $data; 198 $code = ltrim($code); 199 $renderer->doc .= $renderer->_xmlEntities($code); 200 break; 201 202 case DOKU_LEXER_EXIT: 203 $renderer->doc .= '</code>'; 204 $renderer->doc .= '</pre>'; 205 break; 206 } 207 208 return false; 209 } 210} 211