reveal.js icon indicating copy to clipboard operation
reveal.js copied to clipboard

Is it possible to set marked extension directly?

Open wlnirvana opened this issue 2 years ago • 0 comments

TL;DR

Reveal.initialize({markdown:{render: myRenderer}}) does not extend the default renderer, but completely replace it with the argument passed.

Details

I'm trying to integrate mermaidjs into reveal by setting up an extended renderer to marked. However, the following code does not work as expected:

<!doctype html>
<html>

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">

    <title>Test</title>

    <link href="https://lf3-cdn-tos.bytecdntp.com/cdn/expire-1-M/reveal.js/4.1.0/reset.min.css" type="text/css" rel="stylesheet" />
    <link href="https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/reveal.js/4.1.0/reveal.css" type="text/css" rel="stylesheet" />
    <link href="https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/reveal.js/4.1.0/theme/black.min.css" type="text/css" rel="stylesheet" />
    <link href="https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/reveal.js/4.1.0/plugin/highlight/monokai.min.css" type="text/css" rel="stylesheet" />
</head>

<body>
    <div class="reveal">
        <div class="slides">
            <section data-markdown data-separator="^\n\n\n">
                <textarea data-template>
# Mermaid Graph

```mermaid
graph TD;
    A-->B;
    A-->C;
    B-->D;
    C-->D;
```
		</textarea>
            </section>
        </div>
    </div>

    <script src="https://lf3-cdn-tos.bytecdntp.com/cdn/expire-1-M/reveal.js/4.1.0/reveal.min.js" type="application/javascript"></script>
    <script src="https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/reveal.js/4.1.0/plugin/notes/notes.min.js" type="application/javascript"></script>
    <script src="https://lf3-cdn-tos.bytecdntp.com/cdn/expire-1-M/reveal.js/4.1.0/plugin/markdown/markdown.min.js" type="application/javascript"></script>
    <script src="https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/reveal.js/4.1.0/plugin/highlight/highlight.min.js" type="application/javascript"></script>
    <script src="https://lf3-cdn-tos.bytecdntp.com/cdn/expire-0-M/mermaid/8.14.0/mermaid.min.js" type="application/javascript"></script>
    <script>
        mermaid.initialize({
            startOnLoad: true
        });
    </script>
    <script>
        const renderer = {
            code(code, language, escaped) {
                if (code.match(/^sequenceDiagram/) || code.match(/^graph/)) {
                    return '<div class="mermaid">' + code + '</div>';
                } else {
                    return '<pre><code>' + code + '</code></pre>';
                }
            }
        };
        Reveal.initialize({
            hash: true,
            transition: 'none',
            slideNumber: true,
            markdown: {
                renderer
            },
            plugins: [RevealMarkdown, RevealHighlight, RevealNotes]
        });
    </script>
</body>

</html>

The error message below indicates that Reveal.initialize(...) does not internally call marked.use to merge the renderer, but replaces the default renderer with a brand new object.

Uncaught (in promise) TypeError: t.text is not a function
Please report this to https://github.com/markedjs/marked.
    at as.value (markdown.min.js:1:62962)
    at as.value (markdown.min.js:1:60731)
    at Function.value (markdown.min.js:1:63175)
    at fs (markdown.min.js:1:65090)
    at markdown.min.js:1:70592
    at Array.forEach (<anonymous>)
    at s (markdown.min.js:1:70474)

To work around this issue, I have to manually introduce marked script, call new marked.Renderer(); to construct a default renderer, extend it, and finally "inject" it into reveal.js, like in the following code snippet.

<!doctype html>
<html>

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">

    <title>Test</title>

    <link href="https://lf3-cdn-tos.bytecdntp.com/cdn/expire-1-M/reveal.js/4.1.0/reset.min.css" type="text/css" rel="stylesheet" />
    <link href="https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/reveal.js/4.1.0/reveal.css" type="text/css" rel="stylesheet" />
    <link href="https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/reveal.js/4.1.0/theme/black.min.css" type="text/css" rel="stylesheet" />
    <link href="https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/reveal.js/4.1.0/plugin/highlight/monokai.min.css" type="text/css" rel="stylesheet" />
</head>

<body>
    <div class="reveal">
        <div class="slides">
            <section data-markdown data-separator="^\n\n\n">
                <textarea data-template>
# Mermaid Graph

```mermaid
graph TD;
    A-->B;
    A-->C;
    B-->D;
    C-->D;
```
		</textarea>
            </section>
        </div>
    </div>

    <script src="https://lf3-cdn-tos.bytecdntp.com/cdn/expire-1-M/reveal.js/4.1.0/reveal.min.js" type="application/javascript"></script>
    <script src="https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/reveal.js/4.1.0/plugin/notes/notes.min.js" type="application/javascript"></script>
    <script src="https://lf3-cdn-tos.bytecdntp.com/cdn/expire-1-M/reveal.js/4.1.0/plugin/markdown/markdown.min.js" type="application/javascript"></script>
    <script src="https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/reveal.js/4.1.0/plugin/highlight/highlight.min.js" type="application/javascript"></script>
    <script src="https://lf3-cdn-tos.bytecdntp.com/cdn/expire-0-M/mermaid/8.14.0/mermaid.min.js" type="application/javascript"></script>
    <script src="https://lf9-cdn-tos.bytecdntp.com/cdn/expire-0-M/marked/4.0.2/marked.min.js" type="application/javascript"></script>
    <script>
        mermaid.initialize({
            startOnLoad: true
        });
    </script>
    <script>
        const renderer = new marked.Renderer();
        renderer.code = function(code, language, escaped) {
            if (language.match(/^mermaid/)) {
                return '<div class="mermaid">' + code + '</div>';
            } else {
                return '<pre><code>' + code + '</code></pre>';
            }
        };
        Reveal.initialize({
            hash: true,
            transition: 'none',
            slideNumber: true,
            markdown: {
                renderer
            },
            plugins: [RevealMarkdown, RevealHighlight, RevealNotes]
        });
    </script>
</body>

</html>

This seems quite awkward, especially considering reveal.js already includes marked. Did I miss anything?

wlnirvana avatar Apr 25 '22 13:04 wlnirvana