Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

provide mermaidjs rendering #762

Open
rbuckland opened this issue Aug 7, 2018 · 7 comments
Open

provide mermaidjs rendering #762

rbuckland opened this issue Aug 7, 2018 · 7 comments
Labels
C-new-preprocessor Cateogry: A new preprocessor

Comments

@rbuckland
Copy link
Contributor

MermaidJS provides and excellent set of "features" for diagramming. I would like to provide this feature, similar to MathJAX into mdBook as an optional feature.

I am after some guidance regarding modularity.

  1. how do I cater for renderers such as epub or PDF ?
  2. at a high level, which way is it preferred to be integrated. With my quick hacking, I suspect it is with the hbs_renderer.rs (adding html.mermaidjs_support) flags for example.

Guidance will be appreciated.

@mattico
Copy link
Contributor

mattico commented Aug 8, 2018

I think this could be implemented as a preprocessor. It could transform something like this:

```mermaidjs
chart goes here
```

into this

<div class="mermaid">
chart goes here
</div>

The mermaidjs script tag could be added with output.html.additional-js, or perhaps an additional-js facility could be added onto the preprocessor itself somehow.

@badboy
Copy link
Member

badboy commented Sep 15, 2018

I built this as a preprocessor: https://github.com/badboy/mdbook-mermaid
Would this be considered to be included in mdbook directly?

@Michael-F-Bryan
Copy link
Contributor

I think this would be better written as a custom preprocessor, using a similar mechanism to custom renderers (e.g. the CmdRenderer). That way you can provide mdbook-mermaid as its own binary on crates.io and it won't be bound to mdbook's release cycle.

... Of course users can't yet provide their own preprocessors for mdbook to run, so we'd need to implement. You can wrap mdbook like @badboy has done, but that's not as nice as mdbook being able to shell out to a mdbook-mermaid preprocessor and interact with it via stdin/stdout.

@badboy
Copy link
Member

badboy commented Sep 16, 2018

That’s exactly the issue I’m facing right now.
I built 2 different preprocessors, but that also means I needed to build a mdbook clone that adds these 2 preprocessors.
Going forward it would be nice to either have a mechanism to use external preprocessors or to include more preprocessors in mdbook itself.

@Michael-F-Bryan
Copy link
Contributor

I wrote up some support for custom preprocessors. The idea is mdbook will shell out to the provided program, writing the inputs to stdin as JSON and reading the processed book from stdout. It's the same approach we use for custom renderers and should compose a lot better 🙂

It'd be awesome if someone could review the PR and see if the example is intuitive enough.

@ehuss ehuss added the C-new-preprocessor Cateogry: A new preprocessor label May 17, 2019
@sytsereitsma
Copy link

You do not strictly need a preprocessor for this, it works with a javascript hack too.
From my notes:

Mermaid preprocessor

You can easily use mermaid by making the following changes to your book.toml:

[output.html]
additional-css = ["mermaid.css"]
additional-js = ["mermaid.min.js", "mermaid-init.js"]

Where:

  • mermaid.min.js is the mermaid release you want to use
  • mermaid.css come's from badboy's repo (see below)
  • mermaid-init.js contains the following code
// mdBook creates <code> elements with the class 'language-mermaid hljs' whenever you
// define a mermaid code block.
// The mermaid javascript parser looks for elements with a class name 'mermaid'.
// So simply change the class name of the elements to 'mermaid' to make everything work.
function patchMermaidCodeElementClass() {
    var elements = document.getElementsByClassName("language-mermaid");
    for(var i=0; i < elements.length; i+=1) {
        var element = elements.item(i);
        if (element.tagName.toLowerCase() == "code") {
            element.className = "mermaid";
        }
    }
}

patchMermaidCodeElementClass();
mermaid.initialize({startOnLoad:true});

The stylesheet borks the rendering of the TOC though. To fix this remove the opacity of the '.section' definition (line 95 in version 3cea267 dated 2 Oct 2018):

.section {
  stroke: none;
  /*opacity: 0.2;*/
}

This was referenced Jul 8, 2019
@THeK3nger
Copy link
Contributor

I am here with a small update of @sytsereitsma's snippet. I had a problem with the original code on some browser because elements dynamically change when you modify the className of one of its elements. As a consequence I was not able to render multiple mermaid diagrams in a single page.

I have updated the code by duplicating elements to avoid side-effect:

// mdBook creates <code> elements with the class 'language-mermaid hljs' whenever you
// define a mermaid code block.
// The mermaid javascript parser looks for elements with a class name 'mermaid'.
// So simply change the class name of the elements to 'mermaid' to make everything work.
function patchMermaidCodeElementClass() {
    var elements = document.getElementsByClassName("language-mermaid");
    Array.from(elements).forEach(element => {
        if (element.tagName.toLowerCase() == "code") {
            element.className = "mermaid";
        }
    });
    
}

patchMermaidCodeElementClass();
mermaid.initialize({startOnLoad:true});

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-new-preprocessor Cateogry: A new preprocessor
Projects
None yet
Development

No branches or pull requests

7 participants