1<?php
2/**
3 * DokuWiki Plugin mermaid (Action Component)
4 *
5 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
6 * @author  Robert Weinmeister <develop@weinmeister.org>
7 */
8
9class action_plugin_mermaid extends \dokuwiki\Extension\ActionPlugin
10{
11    /** @inheritDoc */
12    public function register(Doku_Event_Handler $controller)
13    {
14        $controller->register_hook('TPL_METAHEADER_OUTPUT', 'BEFORE', $this, 'load');
15    }
16
17    public function load(Doku_Event $event, $param)
18    {
19        // Can be changed for debugging Mermaid
20        // https://mermaid.js.org/config/directives.html#changing-loglevel-via-directive
21        define("MERMAIDLOGLEVEL", "error");
22
23        $theme = $this->getConf('theme');
24        $init = "mermaid.initialize({startOnLoad: true, logLevel: '".MERMAIDLOGLEVEL."', theme: '".$theme."'});";
25        $location = $this->getConf('location');
26
27        switch ($location) {
28            case 'local':
29                $event->data['script'][] = array
30                (
31                    'type'    => 'text/javascript',
32                    'charset' => 'utf-8',
33                    'src' => DOKU_BASE.'lib/plugins/mermaid/mermaid.min.js'
34                );
35                break;
36            case 'latest':
37            case 'remote108':
38            case 'remote106':
39            case 'remote104':
40            case 'remote103':
41            case 'remote102':
42            case 'remote101':
43            case 'remote100':
44                $versions = array(
45                    'latest' => '',
46                    'remote108' => '@10.8.0',
47                    'remote106' => '@10.6.1',
48                    'remote104' => '@10.4.0',
49                    'remote103' => '@10.3.1',
50                    'remote102' => '@10.2.4',
51                    'remote101' => '@10.1.0',
52                    'remote100' => '@10.0.2'
53                );
54                $data = "import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid".$versions[$location]."/dist/mermaid.esm.min.mjs';".$init;
55                $event->data['script'][] = array
56                (
57                    'type'    => 'module',
58                    'charset' => 'utf-8',
59                    '_data' => $data
60                );
61                break;
62            case 'remote94':
63                $event->data['script'][] = array
64                (
65                    'type'    => 'text/javascript',
66                    'charset' => 'utf-8',
67                    'src' => 'https://cdn.jsdelivr.net/npm/mermaid@9.4.3/dist/mermaid.min.js'
68                );
69                break;
70            case 'remote93':
71                $event->data['script'][] = array
72                (
73                    'type'    => 'text/javascript',
74                    'charset' => 'utf-8',
75                    'src' => 'https://cdn.jsdelivr.net/npm/mermaid@9.3.0/dist/mermaid.min.js'
76                );
77                break;
78            default:
79        }
80
81        $event->data['link'][] = array
82        (
83            'rel'     => 'stylesheet',
84            'type'    => 'text/css',
85            'href'    => DOKU_BASE."lib/plugins/mermaid/mermaid.css",
86        );
87
88        switch ($location) {
89            case 'local':
90            case 'remote94':
91            case 'remote93':
92                $event->data['script'][] = array
93                (
94                    'type'    => 'text/javascript',
95                    'charset' => 'utf-8',
96                    '_data'   => $init
97                );
98                break;
99            default:
100        }
101
102        // remove the search highlight from DokuWiki as it interferes with the Mermaid parsing/rendering
103        $event->data['script'][] = array
104        (
105            'type'    => 'text/javascript',
106            'charset' => 'utf-8',
107            '_data' => "document.addEventListener('DOMContentLoaded', function() {
108                            jQuery('.mermaid').each(function() {
109                                var modifiedContent = jQuery(this).html().replace(/<span class=\"search_hit\">(.+?)<\/span>/g, '$1');
110                                jQuery(this).html(modifiedContent);
111                             })
112                        });"
113        );
114    }
115}