xref: /plugin/aichat/renderer.php (revision f93272b94193ec28961da5757db7f0fa6ecf2c22)
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
92    /** @inheritdoc */
93    public function header($text, $level, $pos, $returnonly = false)
94    {
95        $this->doc .= str_repeat("#", $level) . ' ' . $text . DOKU_LF;
96    }
97
98    /** @inheritdoc */
99    public function section_open($level)
100    {
101        $this->doc .= DOKU_LF;
102    }
103
104    /** @inheritdoc */
105    public function section_close()
106    {
107        $this->doc .= DOKU_LF;
108    }
109
110    /** @inheritdoc */
111    public function cdata($text)
112    {
113        $this->doc .= $text;
114    }
115
116    /** @inheritdoc */
117    public function p_open()
118    {
119        $this->doc .= DOKU_LF;
120    }
121
122    /** @inheritdoc */
123    public function p_close()
124    {
125        $this->doc .= DOKU_LF;
126    }
127
128    /** @inheritdoc */
129    public function linebreak()
130    {
131        $this->doc .= DOKU_LF . DOKU_LF;
132    }
133
134    /** @inheritdoc */
135    public function hr()
136    {
137        $this->doc .= '----' . DOKU_LF;
138    }
139
140    /** @inheritdoc */
141    public function strong_open()
142    {
143    }
144
145    /** @inheritdoc */
146    public function strong_close()
147    {
148    }
149
150    /** @inheritdoc */
151    public function emphasis_open()
152    {
153    }
154
155    /** @inheritdoc */
156    public function emphasis_close()
157    {
158    }
159
160    /** @inheritdoc */
161    public function underline_open()
162    {
163    }
164
165    /** @inheritdoc */
166    public function underline_close()
167    {
168    }
169
170    /** @inheritdoc */
171    public function monospace_open()
172    {
173    }
174
175    /** @inheritdoc */
176    public function monospace_close()
177    {
178    }
179
180    /** @inheritdoc */
181    public function subscript_open()
182    {
183    }
184
185    /** @inheritdoc */
186    public function subscript_close()
187    {
188    }
189
190    /** @inheritdoc */
191    public function superscript_open()
192    {
193    }
194
195    /** @inheritdoc */
196    public function superscript_close()
197    {
198    }
199
200    /** @inheritdoc */
201    public function deleted_open()
202    {
203    }
204
205    /** @inheritdoc */
206    public function deleted_close()
207    {
208    }
209
210    /** @inheritdoc */
211    public function footnote_open()
212    {
213        $this->doc .= ' ((';
214    }
215
216    /** @inheritdoc */
217    public function footnote_close()
218    {
219        $this->doc .= '))';
220    }
221
222    /** @inheritdoc */
223    public function listu_open($classes = null)
224    {
225        if ($this->listMode === []) {
226            $this->doc .= DOKU_LF;
227        }
228        $this->listMode[] = '*';
229    }
230
231    /** @inheritdoc */
232    public function listu_close()
233    {
234        array_pop($this->listMode);
235        if ($this->listMode === []) {
236            $this->doc .= DOKU_LF;
237        }
238    }
239
240    /** @inheritdoc */
241    public function listo_open($classes = null)
242    {
243        if ($this->listMode === []) {
244            $this->doc .= DOKU_LF;
245        }
246        $this->listMode[] = '1.';
247    }
248
249    /** @inheritdoc */
250    public function listo_close()
251    {
252        array_pop($this->listMode);
253        if ($this->listMode === []) {
254            $this->doc .= DOKU_LF;
255        }
256    }
257
258    /** @inheritdoc */
259    public function listitem_open($level, $node = false)
260    {
261        $this->doc .= str_repeat(' ', $level * 2) . $this->listMode[count($this->listMode) - 1];
262    }
263
264    /** @inheritdoc */
265    public function listitem_close()
266    {
267    }
268
269
270    /** @inheritdoc */
271    public function listcontent_open()
272    {
273    }
274
275    /** @inheritdoc */
276    public function listcontent_close()
277    {
278        $this->doc .= DOKU_LF;
279    }
280
281    /** @inheritdoc */
282    public function unformatted($text)
283    {
284        $this->doc .= $text;
285    }
286
287    /** @inheritdoc */
288    public function quote_open()
289    {
290        $this->doc .= '>>>';
291    }
292
293    /** @inheritdoc */
294    public function quote_close()
295    {
296        $this->doc .= '<<<' . DOKU_LF;
297    }
298
299    /** @inheritdoc */
300    public function preformatted($text)
301    {
302        $this->code($text);
303    }
304
305    /** @inheritdoc */
306    public function file($text, $language = null, $filename = null, $options = null)
307    {
308        $this->code($text, $language, $filename, $options);
309    }
310
311    /** @inheritdoc */
312    public function code($text, $language = null, $filename = null, $options = null)
313    {
314        $this->doc .= DOKU_LF . '```' . ($language ?? '') . DOKU_LF . trim($text) . DOKU_LF . '```' . DOKU_LF;
315    }
316
317    /** @inheritdoc */
318    public function acronym($acronym)
319    {
320        if (array_key_exists($acronym, $this->acronyms)) {
321            $title = $this->acronyms[$acronym];
322            $this->doc .= $acronym . ' (' . $title . ')';
323        } else {
324            $this->doc .= $acronym;
325        }
326    }
327
328    /** @inheritdoc */
329    public function smiley($smiley)
330    {
331        $this->doc .= $smiley;
332    }
333
334    /** @inheritdoc */
335    public function entity($entity)
336    {
337        if (array_key_exists($entity, $this->entities)) {
338            $this->doc .= $this->entities[$entity];
339        } else {
340            $this->doc .= $entity;
341        }
342    }
343
344    /** @inheritdoc */
345    public function multiplyentity($x, $y)
346    {
347        $this->doc .= $x . 'x' . $y;
348    }
349
350    /** @inheritdoc */
351    public function singlequoteopening()
352    {
353        global $lang;
354        $this->doc .= $lang['singlequoteopening'];
355    }
356
357    /** @inheritdoc */
358    public function singlequoteclosing()
359    {
360        global $lang;
361        $this->doc .= $lang['singlequoteclosing'];
362    }
363
364    /** @inheritdoc */
365    public function apostrophe()
366    {
367        global $lang;
368        $this->doc .= $lang['apostrophe'];
369    }
370
371    /** @inheritdoc */
372    public function doublequoteopening()
373    {
374        global $lang;
375        $this->doc .= $lang['doublequoteopening'];
376    }
377
378    /** @inheritdoc */
379    public function doublequoteclosing()
380    {
381        global $lang;
382        $this->doc .= $lang['doublequoteclosing'];
383    }
384
385    /** @inheritdoc */
386    public function camelcaselink($link, $returnonly = false)
387    {
388        $this->internallink($link, $link);
389    }
390
391    /** @inheritdoc */
392    public function locallink($hash, $name = null, $returnonly = false)
393    {
394        $name = $this->_getLinkTitle($name, $hash, $isImage);
395        $this->doc .= $name;
396    }
397
398    /** @inheritdoc */
399    public function internallink($id, $name = null, $search = null, $returnonly = false, $linktype = 'content')
400    {
401        global $ID;
402        // default name is based on $id as given
403        $default = $this->_simpleTitle($id);
404        $resolver = new PageResolver($ID);
405        $id = $resolver->resolveId($id);
406
407        $name = $this->_getLinkTitle($name, $default, $isImage, $id, $linktype);
408        if ($returnonly) {
409            return $name;
410        }
411        $this->doc .= $name;
412        return null;
413    }
414
415    /** @inheritdoc */
416    public function externallink($url, $name = null, $returnonly = false)
417    {
418        $title = $this->_getLinkTitle($name, $url, $isImage);
419        if ($title != $url) {
420            $this->doc .= "[$title]($url)";
421        } else {
422            $this->doc .= $title;
423        }
424    }
425
426    /** @inheritdoc */
427    public function interwikilink($match, $name, $wikiName, $wikiUri, $returnonly = false)
428    {
429        $this->doc .= $this->_getLinkTitle($name, $wikiUri, $isImage);
430    }
431
432    /** @inheritdoc */
433    public function windowssharelink($url, $name = null, $returnonly = false)
434    {
435        $this->doc .= $this->_getLinkTitle($name, $url, $isImage);
436    }
437
438    /** @inheritdoc */
439    public function emaillink($address, $name = null, $returnonly = false)
440    {
441        $name = $this->_getLinkTitle($name, '', $isImage);
442        $address = html_entity_decode(obfuscate($address), ENT_QUOTES, 'UTF-8');
443        if (empty($name)) {
444            $name = $address;
445        }
446        $this->doc .= $name;
447    }
448
449    /** @inheritdoc */
450    public function internalmedia(
451        $src,
452        $title = null,
453        $align = null,
454        $width = null,
455        $height = null,
456        $cache = null,
457        $linking = null,
458        $return = false
459    ) {
460        $this->doc .= $title;
461    }
462
463    /** @inheritdoc */
464    public function externalmedia(
465        $src,
466        $title = null,
467        $align = null,
468        $width = null,
469        $height = null,
470        $cache = null,
471        $linking = null,
472        $return = false
473    ) {
474        $this->doc .= $title;
475    }
476
477    /** @inheritdoc */
478    public function rss($url, $params)
479    {
480    }
481
482    /** @inheritdoc */
483    public function table_open($maxcols = null, $numrows = null, $pos = null, $classes = null)
484    {
485    }
486
487    /** @inheritdoc */
488    public function table_close($pos = null)
489    {
490        $this->doc .= DOKU_LF;
491    }
492
493    /** @inheritdoc */
494    public function tablethead_open()
495    {
496        $this->tableColumns = 0;
497        $this->doc .= DOKU_LF; // . '|';
498    }
499
500    /** @inheritdoc */
501    public function tablethead_close()
502    {
503        $this->doc .= '|' . str_repeat('---|', $this->tableColumns) . DOKU_LF;
504    }
505
506    /** @inheritdoc */
507    public function tabletbody_open()
508    {
509    }
510
511    /** @inheritdoc */
512    public function tabletbody_close()
513    {
514    }
515
516    /** @inheritdoc */
517    public function tabletfoot_open()
518    {
519    }
520
521    /** @inheritdoc */
522    public function tabletfoot_close()
523    {
524    }
525
526    /** @inheritdoc */
527    public function tablerow_open($classes = null)
528    {
529    }
530
531    /** @inheritdoc */
532    public function tablerow_close()
533    {
534        $this->doc .= '|' . DOKU_LF;
535    }
536
537    /** @inheritdoc */
538    public function tableheader_open($colspan = 1, $align = null, $rowspan = 1, $classes = null)
539    {
540        $this->doc .= str_repeat('|', $colspan);
541        $this->tableColumns += $colspan;
542    }
543
544    /** @inheritdoc */
545    public function tableheader_close()
546    {
547    }
548
549    /** @inheritdoc */
550    public function tablecell_open($colspan = 1, $align = null, $rowspan = 1, $classes = null)
551    {
552        $this->doc .= str_repeat('|', $colspan);
553    }
554
555    /** @inheritdoc */
556    public function tablecell_close()
557    {
558    }
559
560    /** @inheritdoc */
561    public function _getLinkTitle($title, $default, &$isImage, $id = null, $linktype = 'content')
562    {
563        $isImage = false;
564        if (is_array($title)) {
565            $isImage = true;
566            if (!is_null($default) && ($default != $title['title']))
567                return $default . " " . $title['title'];
568            else return $title['title'];
569        } elseif (is_null($title) || trim($title) == '') {
570            if (useHeading($linktype) && $id) {
571                $heading = p_get_first_heading($id);
572                if ($heading) {
573                    return $this->_xmlEntities($heading);
574                }
575            }
576            return $this->_xmlEntities($default);
577        } else {
578            return $this->_xmlEntities($title);
579        }
580    }
581
582    /** @inheritdoc */
583    public function _xmlEntities($string)
584    {
585        return $string; // nothing to do for text
586    }
587
588    /** @inheritdoc */
589    public function _formatLink($link)
590    {
591        if (!empty($link['name'])) {
592            return $link['name'];
593        } elseif (!empty($link['title'])) {
594            return $link['title'];
595        }
596        return $link['url'];
597    }
598}
599