xref: /plugin/combo/ComboStrap/Prism.php (revision bd8dd2718c84c3e0bb8754cbb93e0911b79c8ace)
137748cd8SNickeau<?php
237748cd8SNickeau
337748cd8SNickeaunamespace ComboStrap;
437748cd8SNickeau
537748cd8SNickeau
637748cd8SNickeauuse Doku_Renderer_xhtml;
737748cd8SNickeauuse syntax_plugin_combo_code;
837748cd8SNickeau
904fd306cSNickeau/**
1004fd306cSNickeau * Concurrent: https://highlightjs.org/ used by remark powerpoint
1104fd306cSNickeau */
1237748cd8SNickeauclass Prism
1337748cd8SNickeau{
1437748cd8SNickeau
1537748cd8SNickeau    const SNIPPET_NAME = 'prism';
1637748cd8SNickeau    /**
1737748cd8SNickeau     * The class used to mark the added prism code
1804fd306cSNickeau     * See: https://cdnjs.com/libraries/prism/
1937748cd8SNickeau     */
201fa8c418SNickeau    const BASE_PRISM_CDN = "https://cdnjs.cloudflare.com/ajax/libs/prism/1.25.0";
2137748cd8SNickeau    /**
2237748cd8SNickeau     * The default prompt for bash
2337748cd8SNickeau     */
2437748cd8SNickeau    const CONF_BASH_PROMPT = "bashPrompt";
2537748cd8SNickeau    /**
2637748cd8SNickeau     * The default prompt for batch (dos)
2737748cd8SNickeau     */
2837748cd8SNickeau    const CONF_BATCH_PROMPT = "batchPrompt";
2937748cd8SNickeau    /**
3037748cd8SNickeau     * The default prompt for powershell
3137748cd8SNickeau     */
3237748cd8SNickeau    const CONF_POWERSHELL_PROMPT = "powershellPrompt";
3337748cd8SNickeau
3437748cd8SNickeau    /**
3537748cd8SNickeau     * The default name of prism
3637748cd8SNickeau     * It does not follow the naming of the theming
3737748cd8SNickeau     */
3837748cd8SNickeau    const PRISM_THEME = "prism";
3937748cd8SNickeau
4037748cd8SNickeau    /**
411fa8c418SNickeau     * @var string[] https://cdnjs.cloudflare.com/ajax/libs/prism/1.25.0/themes/prism-{theme}.min.css
4237748cd8SNickeau     *
4337748cd8SNickeau     * or default
4437748cd8SNickeau     *
451fa8c418SNickeau     * https://cdnjs.cloudflare.com/ajax/libs/prism/1.25.0/themes/prism.min.css
4637748cd8SNickeau     *
4737748cd8SNickeau     * or
4837748cd8SNickeau     *
4937748cd8SNickeau     * https://github.com/PrismJS/prism-themes
5037748cd8SNickeau     *
5137748cd8SNickeau     * from https://cdnjs.com/libraries/prism
5237748cd8SNickeau     */
5337748cd8SNickeau    const THEMES_INTEGRITY = [
541fa8c418SNickeau        Prism::PRISM_THEME => "sha256-ko4j5rn874LF8dHwW29/xabhh8YBleWfvxb8nQce4Fc=",
55cb4149a8Sgerardnico        "coy" => "sha256-gkHLZLptZZHaBY+jqrRkAVzOGfMa4HBhSCJteem8wy8=",
56cb4149a8Sgerardnico        "dark" => "sha256-l+VX6V333ll/PXrjqG1W6DyZvDEw+50M7aAP6dcD7Qc=",
57cb4149a8Sgerardnico        "funky" => "sha256-l9GTgvTMmAvPQ6IlNCd/I2FQwXVlJCLbGId7z6QlOpo=",
58cb4149a8Sgerardnico        "okaidia" => "sha256-zzHVEO0xOoVm0I6bT9v5SgpRs1cYNyvEvHXW/1yCgqU=",
59cb4149a8Sgerardnico        "solarizedlight" => "sha256-Lr49DyE+/KstnLdBxqZBoDYgNi6ONfZyAZw3LDhxB9I=",
60cb4149a8Sgerardnico        "tomorrow" => "sha256-GxX+KXGZigSK67YPJvbu12EiBx257zuZWr0AMiT1Kpg=",
61cb4149a8Sgerardnico        "twilight" => "sha256-R7PF7y9XAuz19FB93NgH/WQUVGk30iytl7EwtETrypo="
6237748cd8SNickeau    ];
6337748cd8SNickeau
6437748cd8SNickeau    /**
6537748cd8SNickeau     * The theme
6637748cd8SNickeau     */
6737748cd8SNickeau    const CONF_PRISM_THEME = "prismTheme";
6837748cd8SNickeau    const PRISM_THEME_DEFAULT = "tomorrow";
6937748cd8SNickeau    const SNIPPET_ID_AUTOLOADER = self::SNIPPET_NAME . "-autoloader";
70*bd8dd271Sgerardnico    const LINE_NUMBERS_ATTR = "line-numbers";
7137748cd8SNickeau
7237748cd8SNickeau
7337748cd8SNickeau    /**
7437748cd8SNickeau     *
7537748cd8SNickeau     * @param $theme
7637748cd8SNickeau     *
7737748cd8SNickeau     * Ter info: The theme of the default wiki is in the print.css file (search for code blocks)
7837748cd8SNickeau     */
7937748cd8SNickeau    public static function addSnippet($theme)
8037748cd8SNickeau    {
8137748cd8SNickeau        $BASE_PRISM_CDN = self::BASE_PRISM_CDN;
8237748cd8SNickeau
8337748cd8SNickeau        if ($theme == self::PRISM_THEME) {
8437748cd8SNickeau            $themeStyleSheet = "prism.min.css";
8537748cd8SNickeau        } else {
8637748cd8SNickeau            $themeStyleSheet = "prism-$theme.min.css";
8737748cd8SNickeau        }
8837748cd8SNickeau        $themeIntegrity = self::THEMES_INTEGRITY[$theme];
8937748cd8SNickeau
9037748cd8SNickeau        /**
9137748cd8SNickeau         * We miss a bottom margin
9237748cd8SNickeau         * as a paragraph
9337748cd8SNickeau         */
944cadd4f8SNickeau        $snippetManager = PluginUtility::getSnippetManager();
9504fd306cSNickeau        $snippetManager->attachCssInternalStyleSheet(self::SNIPPET_NAME);
9637748cd8SNickeau
9737748cd8SNickeau        /**
9837748cd8SNickeau         * Javascript
9937748cd8SNickeau         */
1005cb7c87dSgerardnico        $snippetManager->attachRemoteJavascriptLibraryFromLiteral(
1014cadd4f8SNickeau            self::SNIPPET_NAME,
1024cadd4f8SNickeau            "$BASE_PRISM_CDN/components/prism-core.min.js",
1034cadd4f8SNickeau            "sha256-vlRYHThwdq55dA+n1BKQRzzLwFtH9VINdSI68+5JhpU=");
1045cb7c87dSgerardnico        $snippetManager->attachRemoteJavascriptLibraryFromLiteral(
1054cadd4f8SNickeau            self::SNIPPET_NAME,
1064cadd4f8SNickeau            "$BASE_PRISM_CDN/plugins/toolbar/prism-toolbar.min.js",
1074cadd4f8SNickeau            "sha256-FyIVdIHL0+ppj4Q4Ft05K3wyCsYikpHIDGI7dcaBalU="
1081fa8c418SNickeau        );
1095cb7c87dSgerardnico        $snippetManager->attachRemoteCssStyleSheetFromLiteral(
110d4d4add3Sgerardnico            self::SNIPPET_NAME,
111d4d4add3Sgerardnico            "$BASE_PRISM_CDN/plugins/toolbar/prism-toolbar.css",
112d4d4add3Sgerardnico            "sha256-kK4/JIYJUKI4Zdg9ZQ7FYyRIqeWPfYKi5QZHO2n/lJI="
113d4d4add3Sgerardnico        );
11437748cd8SNickeau        // https://prismjs.com/plugins/normalize-whitespace/
1155cb7c87dSgerardnico        $snippetManager->attachRemoteJavascriptLibraryFromLiteral(
1164cadd4f8SNickeau            self::SNIPPET_NAME,
1174cadd4f8SNickeau            "$BASE_PRISM_CDN/plugins/normalize-whitespace/prism-normalize-whitespace.min.js",
1184cadd4f8SNickeau            "sha256-gBzABGbXfQYYnyr8xmDFjx6KGO9dBYuypG1QBjO76pY=");
119d4d4add3Sgerardnico        // https://prismjs.com/plugins/copy-to-clipboard/
1205cb7c87dSgerardnico        $snippetManager->attachRemoteJavascriptLibraryFromLiteral(
121d4d4add3Sgerardnico            self::SNIPPET_NAME,
122d4d4add3Sgerardnico            "$BASE_PRISM_CDN/plugins/copy-to-clipboard/prism-copy-to-clipboard.min.js",
123d4d4add3Sgerardnico            "sha512-pUNGXbOrc+Y3dm5z2ZN7JYQ/2Tq0jppMDOUsN4sQHVJ9AUQpaeERCUfYYBAnaRB9r8d4gtPKMWICNhm3tRr4Fg==");
1244cadd4f8SNickeau        // https://prismjs.com/plugins/show-language/
1255cb7c87dSgerardnico        $snippetManager->attachRemoteJavascriptLibraryFromLiteral(
1264cadd4f8SNickeau            self::SNIPPET_NAME,
1274cadd4f8SNickeau            "$BASE_PRISM_CDN/plugins/show-language/prism-show-language.min.js",
1284cadd4f8SNickeau            "sha256-Z3GTw2RIadLG7KyP/OYB+aAxVYzvg2PByKzYrJlA1EM=");
1294cadd4f8SNickeau        // https://prismjs.com/plugins/command-line/
1305cb7c87dSgerardnico        $snippetManager->attachRemoteJavascriptLibraryFromLiteral(
1314cadd4f8SNickeau            self::SNIPPET_NAME,
1324cadd4f8SNickeau            "$BASE_PRISM_CDN/plugins/command-line/prism-command-line.min.js",
1334cadd4f8SNickeau            "sha256-9WlakH0Upf3N8DDteHlbeKCHxSsljby+G9ucUCQNiU0=");
1345cb7c87dSgerardnico        $snippetManager->attachRemoteCssStyleSheetFromLiteral(
135d4d4add3Sgerardnico            self::SNIPPET_NAME,
136d4d4add3Sgerardnico            "$BASE_PRISM_CDN/plugins/command-line/prism-command-line.css",
137d4d4add3Sgerardnico            "sha256-UvoA9bIYCYQkCMTYG5p2LM8ZpJmnC4G8k0oIc89nuQA="
138d4d4add3Sgerardnico        );
139*bd8dd271Sgerardnico        // https://prismjs.com/plugins/line-highlight/
140*bd8dd271Sgerardnico        $snippetManager->attachRemoteJavascriptLibraryFromLiteral(
141*bd8dd271Sgerardnico            self::SNIPPET_NAME,
142*bd8dd271Sgerardnico            "$BASE_PRISM_CDN/plugins/line-highlight/prism-line-highlight.min.js",
143*bd8dd271Sgerardnico            "sha512-O5GVPBZIURR9MuNiCjSa1wNTL3w91tojKlgCXmOjWDT5a3+9Ms+wGsTkBO93PI3anfdajkJD0sJiS6qdQq7jRA==");
144*bd8dd271Sgerardnico        $snippetManager->attachRemoteCssStyleSheetFromLiteral(
145*bd8dd271Sgerardnico            self::SNIPPET_NAME,
146*bd8dd271Sgerardnico            "$BASE_PRISM_CDN/plugins/line-highlight/prism-line-highlight.min.css",
147*bd8dd271Sgerardnico            "sha512-nXlJLUeqPMp1Q3+Bd8Qds8tXeRVQscMscwysJm821C++9w6WtsFbJjPenZ8cQVMXyqSAismveQJc0C1splFDCA=="
148*bd8dd271Sgerardnico        );
1494cadd4f8SNickeau        //https://prismjs.com/plugins/line-numbers/
1505cb7c87dSgerardnico        $snippetManager->attachRemoteJavascriptLibraryFromLiteral(
1514cadd4f8SNickeau            self::SNIPPET_NAME,
1524cadd4f8SNickeau            "$BASE_PRISM_CDN/plugins/line-numbers/prism-line-numbers.min.js",
1534cadd4f8SNickeau            "sha256-K837BwIyiXo5k/9fCYgqUyA14bN4/Ve9P2SIT0KmZD0=");
1545cb7c87dSgerardnico        $snippetManager->attachRemoteJavascriptLibraryFromLiteral(
155d4d4add3Sgerardnico            self::SNIPPET_NAME,
156d4d4add3Sgerardnico            "$BASE_PRISM_CDN/plugins/line-numbers/prism-line-numbers.css",
157d4d4add3Sgerardnico            "sha256-ye8BkHf2lHXUtqZ18U0KI3xjJ1Yv7P8lvdKBt9xmVJM="
158d4d4add3Sgerardnico        );
1594cadd4f8SNickeau
1604cadd4f8SNickeau        // https://prismjs.com/plugins/download-button/-->
1615cb7c87dSgerardnico        $snippetManager->attachRemoteJavascriptLibraryFromLiteral(
1624cadd4f8SNickeau            self::SNIPPET_NAME,
1634cadd4f8SNickeau            "$BASE_PRISM_CDN/plugins/download-button/prism-download-button.min.js",
1644cadd4f8SNickeau            "sha256-CQyVQ5ejeTshlzOS/eCiry40br9f4fQ9jb5e4qPl7ZA=");
1654cadd4f8SNickeau
166d4d4add3Sgerardnico        // Loading the theme
1675cb7c87dSgerardnico        $snippetManager->attachRemoteCssStyleSheetFromLiteral(
168d4d4add3Sgerardnico            self::SNIPPET_NAME,
169d4d4add3Sgerardnico            "$BASE_PRISM_CDN/themes/$themeStyleSheet",
170d4d4add3Sgerardnico            $themeIntegrity
171d4d4add3Sgerardnico        );
17237748cd8SNickeau
17337748cd8SNickeau        $javascriptCode = <<<EOD
1744cadd4f8SNickeauwindow.addEventListener('load', (event) => {
17537748cd8SNickeau
17637748cd8SNickeau    Prism.plugins.NormalizeWhitespace.setDefaults({
17737748cd8SNickeau        'remove-trailing': true,
17837748cd8SNickeau        'remove-indent': true,
17937748cd8SNickeau        'left-trim': true,
18037748cd8SNickeau        'right-trim': true,
18137748cd8SNickeau    });
18237748cd8SNickeau
18337748cd8SNickeau});
18437748cd8SNickeauEOD;
18504fd306cSNickeau        $snippetManager->attachJavascriptFromComponentId(self::SNIPPET_NAME, $javascriptCode);
18637748cd8SNickeau
18737748cd8SNickeau    }
18837748cd8SNickeau
18937748cd8SNickeau    /**
19037748cd8SNickeau     * Add the first block of prism
19137748cd8SNickeau     * @param \Doku_Renderer_xhtml $renderer
19237748cd8SNickeau     * @param TagAttributes $attributes
19337748cd8SNickeau     * @param \DokuWiki_Syntax_Plugin $plugin
19437748cd8SNickeau     */
19537748cd8SNickeau    public static function htmlEnter(\Doku_Renderer_xhtml $renderer, \DokuWiki_Syntax_Plugin $plugin, $attributes = null)
19637748cd8SNickeau    {
19737748cd8SNickeau
19837748cd8SNickeau        if ($attributes == null) {
19937748cd8SNickeau            $attributes = TagAttributes::createEmpty();
20037748cd8SNickeau        }
20137748cd8SNickeau
20237748cd8SNickeau        /**
20337748cd8SNickeau         * Display none, no rendering
20437748cd8SNickeau         */
20537748cd8SNickeau        $display = $attributes->getValueAndRemove("display");
20637748cd8SNickeau        if ($display != null) {
20737748cd8SNickeau            if ($display == "none") {
20837748cd8SNickeau                return;
20937748cd8SNickeau            }
21037748cd8SNickeau        }
21137748cd8SNickeau
21237748cd8SNickeau
21337748cd8SNickeau        /**
21437748cd8SNickeau         * Add prism theme
21537748cd8SNickeau         */
21604fd306cSNickeau        $theme = $plugin->getConf(Prism::CONF_PRISM_THEME, Prism::PRISM_THEME_DEFAULT);
21737748cd8SNickeau        Prism::addSnippet($theme);
21837748cd8SNickeau
21937748cd8SNickeau        /**
22037748cd8SNickeau         * Logical tag
22137748cd8SNickeau         */
22237748cd8SNickeau        $logicalTag = $plugin->getPluginComponent();
22337748cd8SNickeau        if ($attributes->getLogicalTag() != null) {
22437748cd8SNickeau            $logicalTag = $attributes->getLogicalTag();
22537748cd8SNickeau        }
22637748cd8SNickeau        // for the https://combostrap.com/styling/userstyle
22737748cd8SNickeau        $attributes->setLogicalTag($logicalTag . "-container");
22837748cd8SNickeau
22937748cd8SNickeau        /**
23037748cd8SNickeau         * The child element (code) of the `pre` element
23137748cd8SNickeau         * The container is the passed `attributes`
23237748cd8SNickeau         * We can then constrained in height ...
23337748cd8SNickeau         * It contains the language
23437748cd8SNickeau         */
23537748cd8SNickeau        $codeAttributes = TagAttributes::createEmpty($logicalTag);
23637748cd8SNickeau        $codeAttributes->setType($attributes->getType());
23737748cd8SNickeau        $language = $attributes->getValue(TagAttributes::TYPE_KEY);
23837748cd8SNickeau        if ($language == null) {
23937748cd8SNickeau            // Prism does not have any default language
24037748cd8SNickeau            // There is a bug has it tried to download the txt javascript
24137748cd8SNickeau            // but without language, there is no styling
24237748cd8SNickeau            $language = "txt";
24337748cd8SNickeau        } else {
24437748cd8SNickeau            $language = strtolower($language);
24537748cd8SNickeau            Prism::addAutoloaderSnippet();
24637748cd8SNickeau        }
24737748cd8SNickeau
24804fd306cSNickeau        if (in_array($language, Tag\WebCodeTag::MARKIS)) {
24937748cd8SNickeau            // Marki is not fully markdown
25037748cd8SNickeau            // because it accepts space in super set html container and
25137748cd8SNickeau            // prism will highlight them as indented code
25237748cd8SNickeau            $language = "html";
25337748cd8SNickeau        }
25437748cd8SNickeau        /**
25504fd306cSNickeau         * Language name mapping between the syntax name and prism
25637748cd8SNickeau         */
257c3437056SNickeau        switch ($language) {
258c3437056SNickeau            case "rsplus":
25937748cd8SNickeau                $language = "r";
260c3437056SNickeau                break;
261c3437056SNickeau            case "dos":
2622f24f7a8Sgerardnico            case "bat":
26337748cd8SNickeau                $language = "batch";
264c3437056SNickeau                break;
26504fd306cSNickeau            case "grok":
26604fd306cSNickeau                $language = "regex";
26704fd306cSNickeau                break;
26804fd306cSNickeau            case "jinja":
26904fd306cSNickeau                // https://github.com/PrismJS/prism/issues/759
27004fd306cSNickeau                $language = "twig";
27104fd306cSNickeau                break;
272c3437056SNickeau            case "apache":
27337748cd8SNickeau                $language = "apacheconf";
274c3437056SNickeau                break;
275c3437056SNickeau            case "babel":
276c3437056SNickeau                $language = "jsx";
277c3437056SNickeau                break;
278c3437056SNickeau            case "antlr":
279c3437056SNickeau                $language = "g4";
280c3437056SNickeau                break;
2812f24f7a8Sgerardnico
28237748cd8SNickeau        }
28337748cd8SNickeau
28437748cd8SNickeau        StringUtility::addEolCharacterIfNotPresent($renderer->doc);
28537748cd8SNickeau        $codeAttributes->addClassName('language-' . $language);
28637748cd8SNickeau        /**
28737748cd8SNickeau         * Code element
28837748cd8SNickeau         * Don't put a fucking EOL after it
28937748cd8SNickeau         * Otherwise it fucked up the output as the text below a code tag is printed
29037748cd8SNickeau         */
29137748cd8SNickeau        $codeHtml = $codeAttributes->toHtmlEnterTag('code');
29237748cd8SNickeau        $attributes->addHtmlAfterEnterTag($codeHtml);
29337748cd8SNickeau
29437748cd8SNickeau
29537748cd8SNickeau        /**
29637748cd8SNickeau         * Pre Element
29737748cd8SNickeau         * Line numbers
29837748cd8SNickeau         */
29956a2f80cSgerardnico        $lineNumberEnabled = false;
300*bd8dd271Sgerardnico        if ($attributes->hasComponentAttribute(self::LINE_NUMBERS_ATTR)) {
301*bd8dd271Sgerardnico            $attributes->removeComponentAttribute(self::LINE_NUMBERS_ATTR);
302*bd8dd271Sgerardnico            $attributes->addClassName("line-numbers");
30356a2f80cSgerardnico            $lineNumberEnabled = true;
30437748cd8SNickeau        }
30537748cd8SNickeau
30637748cd8SNickeau
3075cb7c87dSgerardnico        /**
3085cb7c87dSgerardnico         * Command line prompt
3095cb7c87dSgerardnico         * (Line element and prompt cannot be chosen together
3105cb7c87dSgerardnico         * otherwise they endup on top of each other)
3115cb7c87dSgerardnico         */
31256a2f80cSgerardnico        if (!$lineNumberEnabled) {
31337748cd8SNickeau            if ($attributes->hasComponentAttribute("prompt")) {
3145cb7c87dSgerardnico                $promptValue = $attributes->getValueAndRemove("prompt");
3155cb7c87dSgerardnico                // prompt may be the empty string
3165cb7c87dSgerardnico                if (!empty($promptValue)) {
31737748cd8SNickeau                    $attributes->addClassName("command-line");
3185cb7c87dSgerardnico                    $attributes->addOutputAttributeValue("data-prompt", $promptValue);
3195cb7c87dSgerardnico                }
32037748cd8SNickeau            } else {
3215cb7c87dSgerardnico                /**
3225cb7c87dSgerardnico                 * Default prompt
3235cb7c87dSgerardnico                 */
32437748cd8SNickeau                switch ($language) {
32537748cd8SNickeau                    case "bash":
3265cb7c87dSgerardnico                        $prompt = $plugin->getConf(self::CONF_BASH_PROMPT);
32737748cd8SNickeau                        break;
32837748cd8SNickeau                    case "batch":
3295cb7c87dSgerardnico                        $prompt = trim($plugin->getConf(self::CONF_BATCH_PROMPT));
3305cb7c87dSgerardnico                        if (!empty($prompt)) {
3315cb7c87dSgerardnico                            if (!strpos($prompt, -1) == ">") {
3325cb7c87dSgerardnico                                $prompt .= ">";
33337748cd8SNickeau                            }
33437748cd8SNickeau                        }
33537748cd8SNickeau                        break;
33637748cd8SNickeau                    case "powershell":
3375cb7c87dSgerardnico                        $prompt = trim($plugin->getConf(self::CONF_POWERSHELL_PROMPT));
3385cb7c87dSgerardnico                        if (!empty($prompt)) {
3395cb7c87dSgerardnico                            if (!strpos($prompt, -1) == ">") {
3405cb7c87dSgerardnico                                $prompt .= ">";
34137748cd8SNickeau                            }
34237748cd8SNickeau                        }
34337748cd8SNickeau                        break;
34437748cd8SNickeau                }
3455cb7c87dSgerardnico                if(!empty($prompt)) {
3465cb7c87dSgerardnico                    $attributes->addClassName("command-line");
3475cb7c87dSgerardnico                    $attributes->addOutputAttributeValue("data-prompt", $prompt);
3485cb7c87dSgerardnico                }
3495cb7c87dSgerardnico            }
35037748cd8SNickeau        }
35137748cd8SNickeau
352*bd8dd271Sgerardnico        /**
353*bd8dd271Sgerardnico         * Line highlight
354*bd8dd271Sgerardnico         */
355*bd8dd271Sgerardnico        if ($attributes->hasComponentAttribute("line-highlight")) {
356*bd8dd271Sgerardnico            $lineHiglight = $attributes->getValueAndRemove("line-highlight");
357*bd8dd271Sgerardnico            if(!empty($lineHiglight)) {
358*bd8dd271Sgerardnico                $attributes->addOutputAttributeValue('data-line', $lineHiglight);
359*bd8dd271Sgerardnico            }
360*bd8dd271Sgerardnico        }
361*bd8dd271Sgerardnico
36237748cd8SNickeau        // Download
3634cadd4f8SNickeau        $attributes->addOutputAttributeValue('data-download-link', true);
36437748cd8SNickeau        if ($attributes->hasComponentAttribute(syntax_plugin_combo_code::FILE_PATH_KEY)) {
36537748cd8SNickeau            $fileSrc = $attributes->getValueAndRemove(syntax_plugin_combo_code::FILE_PATH_KEY);
3664cadd4f8SNickeau            $attributes->addOutputAttributeValue('data-src', $fileSrc);
3674cadd4f8SNickeau            $attributes->addOutputAttributeValue('data-download-link-label', "Download " . $fileSrc);
36837748cd8SNickeau        } else {
36937748cd8SNickeau            $fileName = "file." . $language;
3704cadd4f8SNickeau            $attributes->addOutputAttributeValue('data-src', $fileName);
37137748cd8SNickeau        }
37237748cd8SNickeau        /**
37337748cd8SNickeau         * No end of line after the pre, please, otherwise we get a new line
37437748cd8SNickeau         * in the code output
37537748cd8SNickeau         */
37637748cd8SNickeau        $htmlCode = $attributes->toHtmlEnterTag("pre");
37737748cd8SNickeau
37837748cd8SNickeau
37937748cd8SNickeau        /**
38037748cd8SNickeau         * Return
38137748cd8SNickeau         */
38237748cd8SNickeau        $renderer->doc .= $htmlCode;
38337748cd8SNickeau
38437748cd8SNickeau    }
38537748cd8SNickeau
38637748cd8SNickeau    /**
38737748cd8SNickeau     * @param Doku_Renderer_xhtml $renderer
38837748cd8SNickeau     * @param TagAttributes $attributes
38937748cd8SNickeau     */
39037748cd8SNickeau    public static function htmlExit(\Doku_Renderer_xhtml $renderer, $attributes = null)
39137748cd8SNickeau    {
39237748cd8SNickeau
39337748cd8SNickeau        if ($attributes != null) {
39437748cd8SNickeau            /**
39537748cd8SNickeau             * Display none, no rendering
39637748cd8SNickeau             */
39737748cd8SNickeau            $display = $attributes->getValueAndRemove("display");
39837748cd8SNickeau            if ($display != null) {
39937748cd8SNickeau                if ($display == "none") {
40037748cd8SNickeau                    return;
40137748cd8SNickeau                }
40237748cd8SNickeau            }
40337748cd8SNickeau        }
40437748cd8SNickeau        $renderer->doc .= '</code>' . DOKU_LF . '</pre>' . DOKU_LF;
40537748cd8SNickeau    }
40637748cd8SNickeau
40737748cd8SNickeau    /**
40837748cd8SNickeau     * The autoloader try to download all language
40937748cd8SNickeau     * Even the one such as txt that does not exist
41037748cd8SNickeau     * This function was created to add it conditionally
41137748cd8SNickeau     */
41237748cd8SNickeau    private static function addAutoloaderSnippet()
41337748cd8SNickeau    {
4144cadd4f8SNickeau        PluginUtility::getSnippetManager()
41504fd306cSNickeau            ->attachRemoteJavascriptLibrary(
4164cadd4f8SNickeau                self::SNIPPET_ID_AUTOLOADER,
4174cadd4f8SNickeau                self::BASE_PRISM_CDN . "/plugins/autoloader/prism-autoloader.min.js"
4184cadd4f8SNickeau            );
41937748cd8SNickeau    }
42037748cd8SNickeau
42137748cd8SNickeau
42237748cd8SNickeau}
423