xref: /plugin/combo/ComboStrap/Prism.php (revision 4cadd4f8c541149bdda95f080e38a6d4e3a640ca)
137748cd8SNickeau<?php
237748cd8SNickeau
337748cd8SNickeaunamespace ComboStrap;
437748cd8SNickeau
537748cd8SNickeau
637748cd8SNickeauuse Doku_Renderer_xhtml;
737748cd8SNickeauuse syntax_plugin_combo_code;
837748cd8SNickeau
937748cd8SNickeauclass Prism
1037748cd8SNickeau{
1137748cd8SNickeau
1237748cd8SNickeau    const SNIPPET_NAME = 'prism';
1337748cd8SNickeau    /**
1437748cd8SNickeau     * The class used to mark the added prism code
1537748cd8SNickeau     */
161fa8c418SNickeau    const BASE_PRISM_CDN = "https://cdnjs.cloudflare.com/ajax/libs/prism/1.25.0";
1737748cd8SNickeau    /**
1837748cd8SNickeau     * The default prompt for bash
1937748cd8SNickeau     */
2037748cd8SNickeau    const CONF_BASH_PROMPT = "bashPrompt";
2137748cd8SNickeau    /**
2237748cd8SNickeau     * The default prompt for batch (dos)
2337748cd8SNickeau     */
2437748cd8SNickeau    const CONF_BATCH_PROMPT = "batchPrompt";
2537748cd8SNickeau    /**
2637748cd8SNickeau     * The default prompt for powershell
2737748cd8SNickeau     */
2837748cd8SNickeau    const CONF_POWERSHELL_PROMPT = "powershellPrompt";
2937748cd8SNickeau
3037748cd8SNickeau    /**
3137748cd8SNickeau     * The default name of prism
3237748cd8SNickeau     * It does not follow the naming of the theming
3337748cd8SNickeau     */
3437748cd8SNickeau    const PRISM_THEME = "prism";
3537748cd8SNickeau
3637748cd8SNickeau    /**
371fa8c418SNickeau     * @var string[] https://cdnjs.cloudflare.com/ajax/libs/prism/1.25.0/themes/prism-{theme}.min.css
3837748cd8SNickeau     *
3937748cd8SNickeau     * or default
4037748cd8SNickeau     *
411fa8c418SNickeau     * https://cdnjs.cloudflare.com/ajax/libs/prism/1.25.0/themes/prism.min.css
4237748cd8SNickeau     *
4337748cd8SNickeau     * or
4437748cd8SNickeau     *
4537748cd8SNickeau     * https://github.com/PrismJS/prism-themes
4637748cd8SNickeau     *
4737748cd8SNickeau     * from https://cdnjs.com/libraries/prism
4837748cd8SNickeau     */
4937748cd8SNickeau    const THEMES_INTEGRITY = [
501fa8c418SNickeau        Prism::PRISM_THEME => "sha256-ko4j5rn874LF8dHwW29/xabhh8YBleWfvxb8nQce4Fc=",
51cb4149a8Sgerardnico        "coy" => "sha256-gkHLZLptZZHaBY+jqrRkAVzOGfMa4HBhSCJteem8wy8=",
52cb4149a8Sgerardnico        "dark" => "sha256-l+VX6V333ll/PXrjqG1W6DyZvDEw+50M7aAP6dcD7Qc=",
53cb4149a8Sgerardnico        "funky" => "sha256-l9GTgvTMmAvPQ6IlNCd/I2FQwXVlJCLbGId7z6QlOpo=",
54cb4149a8Sgerardnico        "okaidia" => "sha256-zzHVEO0xOoVm0I6bT9v5SgpRs1cYNyvEvHXW/1yCgqU=",
55cb4149a8Sgerardnico        "solarizedlight" => "sha256-Lr49DyE+/KstnLdBxqZBoDYgNi6ONfZyAZw3LDhxB9I=",
56cb4149a8Sgerardnico        "tomorrow" => "sha256-GxX+KXGZigSK67YPJvbu12EiBx257zuZWr0AMiT1Kpg=",
57cb4149a8Sgerardnico        "twilight" => "sha256-R7PF7y9XAuz19FB93NgH/WQUVGk30iytl7EwtETrypo="
5837748cd8SNickeau    ];
5937748cd8SNickeau
6037748cd8SNickeau    /**
6137748cd8SNickeau     * The theme
6237748cd8SNickeau     */
6337748cd8SNickeau    const CONF_PRISM_THEME = "prismTheme";
6437748cd8SNickeau    const PRISM_THEME_DEFAULT = "tomorrow";
6537748cd8SNickeau    const SNIPPET_ID_AUTOLOADER = self::SNIPPET_NAME . "-autoloader";
6637748cd8SNickeau
6737748cd8SNickeau
6837748cd8SNickeau    /**
6937748cd8SNickeau     *
7037748cd8SNickeau     * @param $theme
7137748cd8SNickeau     *
7237748cd8SNickeau     * Ter info: The theme of the default wiki is in the print.css file (search for code blocks)
7337748cd8SNickeau     */
7437748cd8SNickeau    public static function addSnippet($theme)
7537748cd8SNickeau    {
7637748cd8SNickeau        $BASE_PRISM_CDN = self::BASE_PRISM_CDN;
7737748cd8SNickeau
7837748cd8SNickeau        if ($theme == self::PRISM_THEME) {
7937748cd8SNickeau            $themeStyleSheet = "prism.min.css";
8037748cd8SNickeau        } else {
8137748cd8SNickeau            $themeStyleSheet = "prism-$theme.min.css";
8237748cd8SNickeau        }
8337748cd8SNickeau        $themeIntegrity = self::THEMES_INTEGRITY[$theme];
8437748cd8SNickeau
8537748cd8SNickeau        /**
8637748cd8SNickeau         * We miss a bottom margin
8737748cd8SNickeau         * as a paragraph
8837748cd8SNickeau         */
89*4cadd4f8SNickeau        $snippetManager = PluginUtility::getSnippetManager();
90*4cadd4f8SNickeau        $snippetManager->attachCssInternalStyleSheetForSlot(self::SNIPPET_NAME);
9137748cd8SNickeau
9237748cd8SNickeau        /**
9337748cd8SNickeau         * Javascript
9437748cd8SNickeau         */
95*4cadd4f8SNickeau        $snippetManager->attachJavascriptLibraryForSlot(
96*4cadd4f8SNickeau            self::SNIPPET_NAME,
97*4cadd4f8SNickeau            "$BASE_PRISM_CDN/components/prism-core.min.js",
98*4cadd4f8SNickeau            "sha256-vlRYHThwdq55dA+n1BKQRzzLwFtH9VINdSI68+5JhpU=");
99*4cadd4f8SNickeau        $snippetManager->attachJavascriptLibraryForSlot(
100*4cadd4f8SNickeau            self::SNIPPET_NAME,
101*4cadd4f8SNickeau            "$BASE_PRISM_CDN/plugins/toolbar/prism-toolbar.min.js",
102*4cadd4f8SNickeau            "sha256-FyIVdIHL0+ppj4Q4Ft05K3wyCsYikpHIDGI7dcaBalU="
1031fa8c418SNickeau        );
10437748cd8SNickeau        // https://prismjs.com/plugins/normalize-whitespace/
105*4cadd4f8SNickeau        $snippetManager->attachJavascriptLibraryForSlot(
106*4cadd4f8SNickeau            self::SNIPPET_NAME,
107*4cadd4f8SNickeau            "$BASE_PRISM_CDN/plugins/normalize-whitespace/prism-normalize-whitespace.min.js",
108*4cadd4f8SNickeau            "sha256-gBzABGbXfQYYnyr8xmDFjx6KGO9dBYuypG1QBjO76pY=");
10937748cd8SNickeau
110*4cadd4f8SNickeau        // https://prismjs.com/plugins/show-language/
111*4cadd4f8SNickeau        $snippetManager->attachJavascriptLibraryForSlot(
112*4cadd4f8SNickeau            self::SNIPPET_NAME,
113*4cadd4f8SNickeau            "$BASE_PRISM_CDN/plugins/show-language/prism-show-language.min.js",
114*4cadd4f8SNickeau            "sha256-Z3GTw2RIadLG7KyP/OYB+aAxVYzvg2PByKzYrJlA1EM=");
115*4cadd4f8SNickeau        // https://prismjs.com/plugins/command-line/
116*4cadd4f8SNickeau        $snippetManager->attachJavascriptLibraryForSlot(
117*4cadd4f8SNickeau            self::SNIPPET_NAME,
118*4cadd4f8SNickeau            "$BASE_PRISM_CDN/plugins/command-line/prism-command-line.min.js",
119*4cadd4f8SNickeau            "sha256-9WlakH0Upf3N8DDteHlbeKCHxSsljby+G9ucUCQNiU0=");
120*4cadd4f8SNickeau
121*4cadd4f8SNickeau        //https://prismjs.com/plugins/line-numbers/
122*4cadd4f8SNickeau        $snippetManager->attachJavascriptLibraryForSlot(
123*4cadd4f8SNickeau            self::SNIPPET_NAME,
124*4cadd4f8SNickeau            "$BASE_PRISM_CDN/plugins/line-numbers/prism-line-numbers.min.js",
125*4cadd4f8SNickeau            "sha256-K837BwIyiXo5k/9fCYgqUyA14bN4/Ve9P2SIT0KmZD0=");
126*4cadd4f8SNickeau
127*4cadd4f8SNickeau        // https://prismjs.com/plugins/download-button/-->
128*4cadd4f8SNickeau        $snippetManager->attachJavascriptLibraryForSlot(
129*4cadd4f8SNickeau            self::SNIPPET_NAME,
130*4cadd4f8SNickeau            "$BASE_PRISM_CDN/plugins/download-button/prism-download-button.min.js",
131*4cadd4f8SNickeau            "sha256-CQyVQ5ejeTshlzOS/eCiry40br9f4fQ9jb5e4qPl7ZA=");
132*4cadd4f8SNickeau
13337748cd8SNickeau
13437748cd8SNickeau        $javascriptCode = <<<EOD
135*4cadd4f8SNickeauwindow.addEventListener('load', (event) => {
13637748cd8SNickeau
13737748cd8SNickeau    if (typeof self === 'undefined' || !self.Prism || !self.document) {
13837748cd8SNickeau        return;
13937748cd8SNickeau    }
14037748cd8SNickeau
14137748cd8SNickeau    // Loading the css from https://cdnjs.com/libraries/prism
14237748cd8SNickeau    const head = document.querySelector('head');
14337748cd8SNickeau    const baseCdn = "$BASE_PRISM_CDN";
14437748cd8SNickeau    const stylesheets = [
14537748cd8SNickeau        ["themes/$themeStyleSheet", "$themeIntegrity"],
1461fa8c418SNickeau        ["plugins/toolbar/prism-toolbar.css","sha256-kK4/JIYJUKI4Zdg9ZQ7FYyRIqeWPfYKi5QZHO2n/lJI="],
14737748cd8SNickeau        /*https://prismjs.com/plugins/command-line/*/
1481fa8c418SNickeau        ["plugins/command-line/prism-command-line.css","sha256-UvoA9bIYCYQkCMTYG5p2LM8ZpJmnC4G8k0oIc89nuQA="],
14937748cd8SNickeau        /*https://prismjs.com/plugins/line-numbers/*/
1501fa8c418SNickeau        ["plugins/line-numbers/prism-line-numbers.css","sha256-ye8BkHf2lHXUtqZ18U0KI3xjJ1Yv7P8lvdKBt9xmVJM="]
15137748cd8SNickeau    ];
15237748cd8SNickeau
15337748cd8SNickeau    stylesheets.forEach(stylesheet => {
15437748cd8SNickeau            let link = document.createElement('link');
15537748cd8SNickeau            link.rel="stylesheet"
15637748cd8SNickeau            link.href=baseCdn+"/"+stylesheet[0];
15737748cd8SNickeau            link.integrity=stylesheet[1];
15837748cd8SNickeau            link.crossOrigin="anonymous";
15937748cd8SNickeau            head.append(link);
16037748cd8SNickeau        }
16137748cd8SNickeau    )
16237748cd8SNickeau
16337748cd8SNickeau
16437748cd8SNickeau    Prism.plugins.NormalizeWhitespace.setDefaults({
16537748cd8SNickeau        'remove-trailing': true,
16637748cd8SNickeau        'remove-indent': true,
16737748cd8SNickeau        'left-trim': true,
16837748cd8SNickeau        'right-trim': true,
16937748cd8SNickeau    });
17037748cd8SNickeau
17137748cd8SNickeau    if (!Prism.plugins.toolbar) {
17237748cd8SNickeau        console.warn('Copy to Clipboard plugin loaded before Toolbar plugin.');
17337748cd8SNickeau
17437748cd8SNickeau        return;
17537748cd8SNickeau    }
17637748cd8SNickeau
17737748cd8SNickeau    let ClipboardJS = window.ClipboardJS || undefined;
17837748cd8SNickeau
17937748cd8SNickeau    if (!ClipboardJS && typeof require === 'function') {
18037748cd8SNickeau        ClipboardJS = require('clipboard');
18137748cd8SNickeau    }
18237748cd8SNickeau
18337748cd8SNickeau    const callbacks = [];
18437748cd8SNickeau
18537748cd8SNickeau    if (!ClipboardJS) {
18637748cd8SNickeau        const script = document.createElement('script');
18737748cd8SNickeau        const head = document.querySelector('head');
18837748cd8SNickeau
18937748cd8SNickeau        script.onload = function() {
19037748cd8SNickeau            ClipboardJS = window.ClipboardJS;
19137748cd8SNickeau
19237748cd8SNickeau            if (ClipboardJS) {
19337748cd8SNickeau                while (callbacks.length) {
19437748cd8SNickeau                    callbacks.pop()();
19537748cd8SNickeau                }
19637748cd8SNickeau            }
19737748cd8SNickeau        };
19837748cd8SNickeau
19937748cd8SNickeau        script.src = 'https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/2.0.0/clipboard.min.js';
20037748cd8SNickeau        head.appendChild(script);
20137748cd8SNickeau    }
20237748cd8SNickeau
20337748cd8SNickeau    Prism.plugins.toolbar.registerButton('copy-to-clipboard', function (env) {
20437748cd8SNickeau        var linkCopy = document.createElement('button');
20537748cd8SNickeau        linkCopy.textContent = 'Copy';
20637748cd8SNickeau        linkCopy.setAttribute('type', 'button');
20737748cd8SNickeau
20837748cd8SNickeau        var element = env.element;
20937748cd8SNickeau
21037748cd8SNickeau        if (!ClipboardJS) {
21137748cd8SNickeau            callbacks.push(registerClipboard);
21237748cd8SNickeau        } else {
21337748cd8SNickeau            registerClipboard();
21437748cd8SNickeau        }
21537748cd8SNickeau
21637748cd8SNickeau        return linkCopy;
21737748cd8SNickeau
21837748cd8SNickeau        function registerClipboard() {
21937748cd8SNickeau            var clip = new ClipboardJS(linkCopy, {
22037748cd8SNickeau                'text': function () {
22137748cd8SNickeau                    return element.textContent;
22237748cd8SNickeau                }
22337748cd8SNickeau            });
22437748cd8SNickeau
22537748cd8SNickeau            clip.on('success', function() {
22637748cd8SNickeau                linkCopy.textContent = 'Copied!';
22737748cd8SNickeau
22837748cd8SNickeau                resetText();
22937748cd8SNickeau            });
23037748cd8SNickeau            clip.on('error', function () {
23137748cd8SNickeau                linkCopy.textContent = 'Press Ctrl+C to copy';
23237748cd8SNickeau
23337748cd8SNickeau                resetText();
23437748cd8SNickeau            });
23537748cd8SNickeau        }
23637748cd8SNickeau
23737748cd8SNickeau        function resetText() {
23837748cd8SNickeau            setTimeout(function () {
23937748cd8SNickeau                linkCopy.textContent = 'Copy';
24037748cd8SNickeau            }, 5000);
24137748cd8SNickeau        }
24237748cd8SNickeau    });
24337748cd8SNickeau
24437748cd8SNickeau});
24537748cd8SNickeauEOD;
246*4cadd4f8SNickeau        $snippetManager->attachInternalJavascriptForSlot(self::SNIPPET_NAME, $javascriptCode);
24737748cd8SNickeau
24837748cd8SNickeau    }
24937748cd8SNickeau
25037748cd8SNickeau    /**
25137748cd8SNickeau     * Add the first block of prism
25237748cd8SNickeau     * @param \Doku_Renderer_xhtml $renderer
25337748cd8SNickeau     * @param TagAttributes $attributes
25437748cd8SNickeau     * @param \DokuWiki_Syntax_Plugin $plugin
25537748cd8SNickeau     */
25637748cd8SNickeau    public static function htmlEnter(\Doku_Renderer_xhtml $renderer, \DokuWiki_Syntax_Plugin $plugin, $attributes = null)
25737748cd8SNickeau    {
25837748cd8SNickeau
25937748cd8SNickeau        if ($attributes == null) {
26037748cd8SNickeau            $attributes = TagAttributes::createEmpty();
26137748cd8SNickeau        }
26237748cd8SNickeau
26337748cd8SNickeau        /**
26437748cd8SNickeau         * Display none, no rendering
26537748cd8SNickeau         */
26637748cd8SNickeau        $display = $attributes->getValueAndRemove("display");
26737748cd8SNickeau        if ($display != null) {
26837748cd8SNickeau            if ($display == "none") {
26937748cd8SNickeau                return;
27037748cd8SNickeau            }
27137748cd8SNickeau        }
27237748cd8SNickeau
27337748cd8SNickeau
27437748cd8SNickeau        /**
27537748cd8SNickeau         * Add prism theme
27637748cd8SNickeau         */
27737748cd8SNickeau        $theme = $plugin->getConf(Prism::CONF_PRISM_THEME);
27837748cd8SNickeau        Prism::addSnippet($theme);
27937748cd8SNickeau
28037748cd8SNickeau        /**
28137748cd8SNickeau         * Logical tag
28237748cd8SNickeau         */
28337748cd8SNickeau        $logicalTag = $plugin->getPluginComponent();
28437748cd8SNickeau        if ($attributes->getLogicalTag() != null) {
28537748cd8SNickeau            $logicalTag = $attributes->getLogicalTag();
28637748cd8SNickeau        }
28737748cd8SNickeau        // for the https://combostrap.com/styling/userstyle
28837748cd8SNickeau        $attributes->setLogicalTag($logicalTag . "-container");
28937748cd8SNickeau
29037748cd8SNickeau        /**
29137748cd8SNickeau         * The child element (code) of the `pre` element
29237748cd8SNickeau         * The container is the passed `attributes`
29337748cd8SNickeau         * We can then constrained in height ...
29437748cd8SNickeau         * It contains the language
29537748cd8SNickeau         */
29637748cd8SNickeau        $codeAttributes = TagAttributes::createEmpty($logicalTag);
29737748cd8SNickeau        $codeAttributes->setType($attributes->getType());
29837748cd8SNickeau        $language = $attributes->getValue(TagAttributes::TYPE_KEY);
29937748cd8SNickeau        if ($language == null) {
30037748cd8SNickeau            // Prism does not have any default language
30137748cd8SNickeau            // There is a bug has it tried to download the txt javascript
30237748cd8SNickeau            // but without language, there is no styling
30337748cd8SNickeau            $language = "txt";
30437748cd8SNickeau        } else {
30537748cd8SNickeau            $language = strtolower($language);
30637748cd8SNickeau            Prism::addAutoloaderSnippet();
30737748cd8SNickeau        }
30837748cd8SNickeau
30937748cd8SNickeau        if (in_array($language, \syntax_plugin_combo_webcode::MARKIS)) {
31037748cd8SNickeau            // Marki is not fully markdown
31137748cd8SNickeau            // because it accepts space in super set html container and
31237748cd8SNickeau            // prism will highlight them as indented code
31337748cd8SNickeau            $language = "html";
31437748cd8SNickeau        }
31537748cd8SNickeau        /**
31637748cd8SNickeau         * Language name mapping between the dokuwiki default
31737748cd8SNickeau         * and prism
31837748cd8SNickeau         */
319c3437056SNickeau        switch ($language) {
320c3437056SNickeau            case "rsplus":
32137748cd8SNickeau                $language = "r";
322c3437056SNickeau                break;
323c3437056SNickeau            case "dos":
32437748cd8SNickeau                $language = "batch";
325c3437056SNickeau                break;
326c3437056SNickeau            case "apache":
32737748cd8SNickeau                $language = "apacheconf";
328c3437056SNickeau                break;
329c3437056SNickeau            case "babel":
330c3437056SNickeau                $language = "jsx";
331c3437056SNickeau                break;
332c3437056SNickeau            case "antlr":
333c3437056SNickeau                $language = "g4";
334c3437056SNickeau                break;
33537748cd8SNickeau        }
33637748cd8SNickeau
33737748cd8SNickeau        StringUtility::addEolCharacterIfNotPresent($renderer->doc);
33837748cd8SNickeau        $codeAttributes->addClassName('language-' . $language);
33937748cd8SNickeau        /**
34037748cd8SNickeau         * Code element
34137748cd8SNickeau         * Don't put a fucking EOL after it
34237748cd8SNickeau         * Otherwise it fucked up the output as the text below a code tag is printed
34337748cd8SNickeau         */
34437748cd8SNickeau        $codeHtml = $codeAttributes->toHtmlEnterTag('code');
34537748cd8SNickeau        $attributes->addHtmlAfterEnterTag($codeHtml);
34637748cd8SNickeau
34737748cd8SNickeau
34837748cd8SNickeau        /**
34937748cd8SNickeau         * Pre Element
35037748cd8SNickeau         * Line numbers
35137748cd8SNickeau         */
35237748cd8SNickeau        if ($attributes->hasComponentAttribute("line-numbers")) {
35337748cd8SNickeau            $attributes->removeComponentAttribute("line-numbers");
35437748cd8SNickeau            $attributes->addClassName('line-numbers');
35537748cd8SNickeau        }
35637748cd8SNickeau
35737748cd8SNickeau
35837748cd8SNickeau        // Command line
35937748cd8SNickeau        if ($attributes->hasComponentAttribute("prompt")) {
36037748cd8SNickeau            $attributes->addClassName("command-line");
361*4cadd4f8SNickeau            $attributes->addOutputAttributeValue("data-prompt", $attributes->getValueAndRemove("prompt"));
36237748cd8SNickeau        } else {
36337748cd8SNickeau            switch ($language) {
36437748cd8SNickeau                case "bash":
36537748cd8SNickeau                    $attributes->addClassName("command-line");
366*4cadd4f8SNickeau                    $attributes->addOutputAttributeValue("data-prompt", $plugin->getConf(self::CONF_BASH_PROMPT));
36737748cd8SNickeau                    break;
36837748cd8SNickeau                case "batch":
36937748cd8SNickeau                    $attributes->addClassName("command-line");
37037748cd8SNickeau                    $batch = trim($plugin->getConf(self::CONF_BATCH_PROMPT));
37137748cd8SNickeau                    if (!empty($batch)) {
37237748cd8SNickeau                        if (!strpos($batch, -1) == ">") {
37337748cd8SNickeau                            $batch .= ">";
37437748cd8SNickeau                        }
37537748cd8SNickeau                    }
376*4cadd4f8SNickeau                    $attributes->addOutputAttributeValue("data-prompt", $batch);
37737748cd8SNickeau                    break;
37837748cd8SNickeau                case "powershell":
37937748cd8SNickeau                    $attributes->addClassName("command-line");
38037748cd8SNickeau                    $powerShell = trim($plugin->getConf(self::CONF_POWERSHELL_PROMPT));
38137748cd8SNickeau                    if (!empty($powerShell)) {
38237748cd8SNickeau                        if (!strpos($powerShell, -1) == ">") {
38337748cd8SNickeau                            $powerShell .= ">";
38437748cd8SNickeau                        }
38537748cd8SNickeau                    }
386*4cadd4f8SNickeau                    $attributes->addOutputAttributeValue("data-prompt", $powerShell);
38737748cd8SNickeau                    break;
38837748cd8SNickeau            }
38937748cd8SNickeau        }
39037748cd8SNickeau
39137748cd8SNickeau        // Download
392*4cadd4f8SNickeau        $attributes->addOutputAttributeValue('data-download-link', true);
39337748cd8SNickeau        if ($attributes->hasComponentAttribute(syntax_plugin_combo_code::FILE_PATH_KEY)) {
39437748cd8SNickeau            $fileSrc = $attributes->getValueAndRemove(syntax_plugin_combo_code::FILE_PATH_KEY);
395*4cadd4f8SNickeau            $attributes->addOutputAttributeValue('data-src', $fileSrc);
396*4cadd4f8SNickeau            $attributes->addOutputAttributeValue('data-download-link-label', "Download " . $fileSrc);
39737748cd8SNickeau        } else {
39837748cd8SNickeau            $fileName = "file." . $language;
399*4cadd4f8SNickeau            $attributes->addOutputAttributeValue('data-src', $fileName);
40037748cd8SNickeau        }
40137748cd8SNickeau        /**
40237748cd8SNickeau         * No end of line after the pre, please, otherwise we get a new line
40337748cd8SNickeau         * in the code output
40437748cd8SNickeau         */
40537748cd8SNickeau        $htmlCode = $attributes->toHtmlEnterTag("pre");
40637748cd8SNickeau
40737748cd8SNickeau
40837748cd8SNickeau        /**
40937748cd8SNickeau         * Return
41037748cd8SNickeau         */
41137748cd8SNickeau        $renderer->doc .= $htmlCode;
41237748cd8SNickeau
41337748cd8SNickeau    }
41437748cd8SNickeau
41537748cd8SNickeau    /**
41637748cd8SNickeau     * @param Doku_Renderer_xhtml $renderer
41737748cd8SNickeau     * @param TagAttributes $attributes
41837748cd8SNickeau     */
41937748cd8SNickeau    public static function htmlExit(\Doku_Renderer_xhtml $renderer, $attributes = null)
42037748cd8SNickeau    {
42137748cd8SNickeau
42237748cd8SNickeau        if ($attributes != null) {
42337748cd8SNickeau            /**
42437748cd8SNickeau             * Display none, no rendering
42537748cd8SNickeau             */
42637748cd8SNickeau            $display = $attributes->getValueAndRemove("display");
42737748cd8SNickeau            if ($display != null) {
42837748cd8SNickeau                if ($display == "none") {
42937748cd8SNickeau                    return;
43037748cd8SNickeau                }
43137748cd8SNickeau            }
43237748cd8SNickeau        }
43337748cd8SNickeau        $renderer->doc .= '</code>' . DOKU_LF . '</pre>' . DOKU_LF;
43437748cd8SNickeau    }
43537748cd8SNickeau
43637748cd8SNickeau    /**
43737748cd8SNickeau     * The autoloader try to download all language
43837748cd8SNickeau     * Even the one such as txt that does not exist
43937748cd8SNickeau     * This function was created to add it conditionally
44037748cd8SNickeau     */
44137748cd8SNickeau    private static function addAutoloaderSnippet()
44237748cd8SNickeau    {
443*4cadd4f8SNickeau        PluginUtility::getSnippetManager()
444*4cadd4f8SNickeau            ->attachJavascriptLibraryForSlot(
445*4cadd4f8SNickeau                self::SNIPPET_ID_AUTOLOADER,
446*4cadd4f8SNickeau                self::BASE_PRISM_CDN . "/plugins/autoloader/prism-autoloader.min.js"
447*4cadd4f8SNickeau            );
44837748cd8SNickeau    }
44937748cd8SNickeau
45037748cd8SNickeau
45137748cd8SNickeau}
452