1<?php 2 3// phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps 4// phpcs:disable PSR2.Methods.MethodDeclaration.Underscore 5 6use dokuwiki\Extension\SyntaxPlugin; 7use dokuwiki\File\PageResolver; 8 9/** 10 * Renderer for preparing data for embedding 11 * 12 * Based on the text and markdown renderers 13 * 14 * @todo table handling is not perfect 15 * @author Michael Hamann <michael@content-space.de> 16 * @author Todd Augsburger <todd@rollerorgans.com> 17 * @author i-net software <tools@inetsoftware.de> 18 * @link https://www.dokuwiki.org/plugin:text 19 * @link https://www.dokuwiki.org/plugin:dw2markdown 20 */ 21class renderer_plugin_aichat extends Doku_Renderer_xhtml 22{ 23 /** @var array The stack of list types */ 24 private $listMode = []; 25 26 /** @var int Number of table columns */ 27 private $tableColumns = 0; 28 29 /** @inheritdoc */ 30 public function getFormat() 31 { 32 return 'aichat'; 33 } 34 35 /** @inheritdoc */ 36 public function startSectionEdit($start, $data, $title = null) 37 { 38 } 39 40 /** @inheritdoc */ 41 public function finishSectionEdit($end = null, $hid = null) 42 { 43 } 44 45 /** 46 * @inheritdoc 47 * Use specific text support if available, otherwise use xhtml renderer and strip tags 48 */ 49 public function plugin($name, $data, $state = '', $match = '') 50 { 51 /** @var SyntaxPlugin $plugin */ 52 $plugin = plugin_load('syntax', $name); 53 if ($plugin === null) return; 54 55 if ( 56 !$plugin->render($this->getFormat(), $this, $data) && 57 !$plugin->render('text', $this, $data) && 58 !$plugin->render('markdown', $this, $data) 59 ) { 60 // plugin does not support any of the text formats, so use stripped-down xhtml 61 $tmpData = $this->doc; 62 $this->doc = ''; 63 if ($plugin->render('xhtml', $this, $data) && ($this->doc !== '')) { 64 $pluginoutput = $this->doc; 65 $this->doc = $tmpData . DOKU_LF . trim(strip_tags($pluginoutput)) . DOKU_LF; 66 } else { 67 $this->doc = $tmpData; 68 } 69 } 70 } 71 72 /** @inheritdoc */ 73 public function document_start() 74 { 75 global $ID; 76 77 $this->doc = ''; 78 $metaheader = []; 79 $metaheader['Content-Type'] = 'text/plain; charset=utf-8'; 80 $meta = []; 81 $meta['format']['aichat'] = $metaheader; 82 p_set_metadata($ID, $meta); 83 } 84 85 /** @inheritdoc */ 86 public function document_end() 87 { 88 $this->doc = preg_replace("/(\r?\n){3,}/", "\n\n", $this->doc); 89 $this->doc = ltrim($this->doc); // remove leading space and empty lines 90 91 // remove ignored parts 92 $regex = $this->getConf('ignoreRegex'); 93 if($regex) { 94 $this->doc = preg_replace('/' . $regex . '/i', '', $this->doc); 95 } 96 } 97 98 /** @inheritdoc */ 99 public function header($text, $level, $pos, $returnonly = false) 100 { 101 $this->doc .= str_repeat("#", $level) . ' ' . $text . DOKU_LF; 102 } 103 104 /** @inheritdoc */ 105 public function section_open($level) 106 { 107 $this->doc .= DOKU_LF; 108 } 109 110 /** @inheritdoc */ 111 public function section_close() 112 { 113 $this->doc .= DOKU_LF; 114 } 115 116 /** @inheritdoc */ 117 public function cdata($text) 118 { 119 $this->doc .= $text; 120 } 121 122 /** @inheritdoc */ 123 public function p_open() 124 { 125 $this->doc .= DOKU_LF; 126 } 127 128 /** @inheritdoc */ 129 public function p_close() 130 { 131 $this->doc .= DOKU_LF; 132 } 133 134 /** @inheritdoc */ 135 public function linebreak() 136 { 137 $this->doc .= DOKU_LF . DOKU_LF; 138 } 139 140 /** @inheritdoc */ 141 public function hr() 142 { 143 $this->doc .= '----' . DOKU_LF; 144 } 145 146 /** @inheritdoc */ 147 public function strong_open() 148 { 149 } 150 151 /** @inheritdoc */ 152 public function strong_close() 153 { 154 } 155 156 /** @inheritdoc */ 157 public function emphasis_open() 158 { 159 } 160 161 /** @inheritdoc */ 162 public function emphasis_close() 163 { 164 } 165 166 /** @inheritdoc */ 167 public function underline_open() 168 { 169 } 170 171 /** @inheritdoc */ 172 public function underline_close() 173 { 174 } 175 176 /** @inheritdoc */ 177 public function monospace_open() 178 { 179 } 180 181 /** @inheritdoc */ 182 public function monospace_close() 183 { 184 } 185 186 /** @inheritdoc */ 187 public function subscript_open() 188 { 189 } 190 191 /** @inheritdoc */ 192 public function subscript_close() 193 { 194 } 195 196 /** @inheritdoc */ 197 public function superscript_open() 198 { 199 } 200 201 /** @inheritdoc */ 202 public function superscript_close() 203 { 204 } 205 206 /** @inheritdoc */ 207 public function deleted_open() 208 { 209 } 210 211 /** @inheritdoc */ 212 public function deleted_close() 213 { 214 } 215 216 /** @inheritdoc */ 217 public function footnote_open() 218 { 219 $this->doc .= ' (('; 220 } 221 222 /** @inheritdoc */ 223 public function footnote_close() 224 { 225 $this->doc .= '))'; 226 } 227 228 /** @inheritdoc */ 229 public function listu_open($classes = null) 230 { 231 if ($this->listMode === []) { 232 $this->doc .= DOKU_LF; 233 } 234 $this->listMode[] = '*'; 235 } 236 237 /** @inheritdoc */ 238 public function listu_close() 239 { 240 array_pop($this->listMode); 241 if ($this->listMode === []) { 242 $this->doc .= DOKU_LF; 243 } 244 } 245 246 /** @inheritdoc */ 247 public function listo_open($classes = null) 248 { 249 if ($this->listMode === []) { 250 $this->doc .= DOKU_LF; 251 } 252 $this->listMode[] = '1.'; 253 } 254 255 /** @inheritdoc */ 256 public function listo_close() 257 { 258 array_pop($this->listMode); 259 if ($this->listMode === []) { 260 $this->doc .= DOKU_LF; 261 } 262 } 263 264 /** @inheritdoc */ 265 public function listitem_open($level, $node = false) 266 { 267 $this->doc .= str_repeat(' ', $level * 2) . $this->listMode[count($this->listMode) - 1]; 268 } 269 270 /** @inheritdoc */ 271 public function listitem_close() 272 { 273 } 274 275 276 /** @inheritdoc */ 277 public function listcontent_open() 278 { 279 } 280 281 /** @inheritdoc */ 282 public function listcontent_close() 283 { 284 $this->doc .= DOKU_LF; 285 } 286 287 /** @inheritdoc */ 288 public function unformatted($text) 289 { 290 $this->doc .= $text; 291 } 292 293 /** @inheritdoc */ 294 public function quote_open() 295 { 296 $this->doc .= '>>>'; 297 } 298 299 /** @inheritdoc */ 300 public function quote_close() 301 { 302 $this->doc .= '<<<' . DOKU_LF; 303 } 304 305 /** @inheritdoc */ 306 public function preformatted($text) 307 { 308 $this->code($text); 309 } 310 311 /** @inheritdoc */ 312 public function file($text, $language = null, $filename = null, $options = null) 313 { 314 $this->code($text, $language, $filename, $options); 315 } 316 317 /** @inheritdoc */ 318 public function code($text, $language = null, $filename = null, $options = null) 319 { 320 $this->doc .= DOKU_LF . '```' . ($language ?? '') . DOKU_LF . trim($text) . DOKU_LF . '```' . DOKU_LF; 321 } 322 323 /** @inheritdoc */ 324 public function acronym($acronym) 325 { 326 if (array_key_exists($acronym, $this->acronyms)) { 327 $title = $this->acronyms[$acronym]; 328 $this->doc .= $acronym . ' (' . $title . ')'; 329 } else { 330 $this->doc .= $acronym; 331 } 332 } 333 334 /** @inheritdoc */ 335 public function smiley($smiley) 336 { 337 $this->doc .= $smiley; 338 } 339 340 /** @inheritdoc */ 341 public function entity($entity) 342 { 343 if (array_key_exists($entity, $this->entities)) { 344 $this->doc .= $this->entities[$entity]; 345 } else { 346 $this->doc .= $entity; 347 } 348 } 349 350 /** @inheritdoc */ 351 public function multiplyentity($x, $y) 352 { 353 $this->doc .= $x . 'x' . $y; 354 } 355 356 /** @inheritdoc */ 357 public function singlequoteopening() 358 { 359 global $lang; 360 $this->doc .= $lang['singlequoteopening']; 361 } 362 363 /** @inheritdoc */ 364 public function singlequoteclosing() 365 { 366 global $lang; 367 $this->doc .= $lang['singlequoteclosing']; 368 } 369 370 /** @inheritdoc */ 371 public function apostrophe() 372 { 373 global $lang; 374 $this->doc .= $lang['apostrophe']; 375 } 376 377 /** @inheritdoc */ 378 public function doublequoteopening() 379 { 380 global $lang; 381 $this->doc .= $lang['doublequoteopening']; 382 } 383 384 /** @inheritdoc */ 385 public function doublequoteclosing() 386 { 387 global $lang; 388 $this->doc .= $lang['doublequoteclosing']; 389 } 390 391 /** @inheritdoc */ 392 public function camelcaselink($link, $returnonly = false) 393 { 394 $this->internallink($link, $link); 395 } 396 397 /** @inheritdoc */ 398 public function locallink($hash, $name = null, $returnonly = false) 399 { 400 $name = $this->_getLinkTitle($name, $hash, $isImage); 401 $this->doc .= $name; 402 } 403 404 /** @inheritdoc */ 405 public function internallink($id, $name = null, $search = null, $returnonly = false, $linktype = 'content') 406 { 407 global $ID; 408 // default name is based on $id as given 409 $default = $this->_simpleTitle($id); 410 $resolver = new PageResolver($ID); 411 $id = $resolver->resolveId($id); 412 413 $name = $this->_getLinkTitle($name, $default, $isImage, $id, $linktype); 414 if ($returnonly) { 415 return $name; 416 } 417 $this->doc .= $name; 418 return null; 419 } 420 421 /** @inheritdoc */ 422 public function externallink($url, $name = null, $returnonly = false) 423 { 424 $title = $this->_getLinkTitle($name, $url, $isImage); 425 if ($title != $url) { 426 $this->doc .= "[$title]($url)"; 427 } else { 428 $this->doc .= $title; 429 } 430 } 431 432 /** @inheritdoc */ 433 public function interwikilink($match, $name, $wikiName, $wikiUri, $returnonly = false) 434 { 435 $this->doc .= $this->_getLinkTitle($name, $wikiUri, $isImage); 436 } 437 438 /** @inheritdoc */ 439 public function windowssharelink($url, $name = null, $returnonly = false) 440 { 441 $this->doc .= $this->_getLinkTitle($name, $url, $isImage); 442 } 443 444 /** @inheritdoc */ 445 public function emaillink($address, $name = null, $returnonly = false) 446 { 447 $name = $this->_getLinkTitle($name, '', $isImage); 448 $address = html_entity_decode(obfuscate($address), ENT_QUOTES, 'UTF-8'); 449 if (empty($name)) { 450 $name = $address; 451 } 452 $this->doc .= $name; 453 } 454 455 /** @inheritdoc */ 456 public function internalmedia( 457 $src, 458 $title = null, 459 $align = null, 460 $width = null, 461 $height = null, 462 $cache = null, 463 $linking = null, 464 $return = false 465 ) { 466 $this->doc .= $title; 467 } 468 469 /** @inheritdoc */ 470 public function externalmedia( 471 $src, 472 $title = null, 473 $align = null, 474 $width = null, 475 $height = null, 476 $cache = null, 477 $linking = null, 478 $return = false 479 ) { 480 $this->doc .= $title; 481 } 482 483 /** @inheritdoc */ 484 public function rss($url, $params) 485 { 486 } 487 488 /** @inheritdoc */ 489 public function table_open($maxcols = null, $numrows = null, $pos = null, $classes = null) 490 { 491 } 492 493 /** @inheritdoc */ 494 public function table_close($pos = null) 495 { 496 $this->doc .= DOKU_LF; 497 } 498 499 /** @inheritdoc */ 500 public function tablethead_open() 501 { 502 $this->tableColumns = 0; 503 $this->doc .= DOKU_LF; // . '|'; 504 } 505 506 /** @inheritdoc */ 507 public function tablethead_close() 508 { 509 $this->doc .= '|' . str_repeat('---|', $this->tableColumns) . DOKU_LF; 510 } 511 512 /** @inheritdoc */ 513 public function tabletbody_open() 514 { 515 } 516 517 /** @inheritdoc */ 518 public function tabletbody_close() 519 { 520 } 521 522 /** @inheritdoc */ 523 public function tabletfoot_open() 524 { 525 } 526 527 /** @inheritdoc */ 528 public function tabletfoot_close() 529 { 530 } 531 532 /** @inheritdoc */ 533 public function tablerow_open($classes = null) 534 { 535 } 536 537 /** @inheritdoc */ 538 public function tablerow_close() 539 { 540 $this->doc .= '|' . DOKU_LF; 541 } 542 543 /** @inheritdoc */ 544 public function tableheader_open($colspan = 1, $align = null, $rowspan = 1, $classes = null) 545 { 546 $this->doc .= str_repeat('|', $colspan); 547 $this->tableColumns += $colspan; 548 } 549 550 /** @inheritdoc */ 551 public function tableheader_close() 552 { 553 } 554 555 /** @inheritdoc */ 556 public function tablecell_open($colspan = 1, $align = null, $rowspan = 1, $classes = null) 557 { 558 $this->doc .= str_repeat('|', $colspan); 559 } 560 561 /** @inheritdoc */ 562 public function tablecell_close() 563 { 564 } 565 566 /** @inheritdoc */ 567 public function _getLinkTitle($title, $default, &$isImage, $id = null, $linktype = 'content') 568 { 569 $isImage = false; 570 if (is_array($title)) { 571 $isImage = true; 572 if (!is_null($default) && ($default != $title['title'])) 573 return $default . " " . $title['title']; 574 else return $title['title']; 575 } elseif (is_null($title) || trim($title) == '') { 576 if (useHeading($linktype) && $id) { 577 $heading = p_get_first_heading($id); 578 if ($heading) { 579 return $this->_xmlEntities($heading); 580 } 581 } 582 return $this->_xmlEntities($default); 583 } else { 584 return $this->_xmlEntities($title); 585 } 586 } 587 588 /** @inheritdoc */ 589 public function _xmlEntities($string) 590 { 591 return $string; // nothing to do for text 592 } 593 594 /** @inheritdoc */ 595 public function _formatLink($link) 596 { 597 if (!empty($link['name'])) { 598 return $link['name']; 599 } elseif (!empty($link['title'])) { 600 return $link['title']; 601 } 602 return $link['url']; 603 } 604} 605