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