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

Add a `display_mermaid(diagram: str) function which rendered the provided diagram as a Mermaid diagram #14319

Open
afonit opened this issue Feb 1, 2024 · 19 comments

Comments

@afonit
Copy link

afonit commented Feb 1, 2024

As mentioned by @dhirschfeld in jupyterlab/jupyterlab#15725

With jupyterlab 4.1 coming out and supporting Mermaid.js diagrams, it would be useful to display programmatically generated Mermaid diagrams in JupyterLab.

See this comment for the initial idea:
jupyterlab/jupyterlab#15725 (comment)

@afonit
Copy link
Author

afonit commented Feb 1, 2024

@krassowski,
messaging you as you stated you wanted to review it:
jupyterlab/jupyterlab#15725 (comment)

@Carreau
Copy link
Member

Carreau commented Feb 3, 2024

Really I don't think we should, if something has a mermaid repr, then display(obj) should be sufficient. I don't think IPython should grow all those display_*

display have the include and exclude keywords if you really want to customize which repr are sent, and in general the frontend should let you choose with a dropdown or anything else.

The current display_* methods that exists are more a historical artifact than an API that should be mimicked.

@Carreau
Copy link
Member

Carreau commented Feb 3, 2024

Also see this talk I did with Paul Ivanov at JupyterCon arround 20 ish minutes you see a prototype where the frontend let you choise the repr you want, making display_* unecaesary anymore.

@dhirschfeld
Copy link

Sure, I actually agree with that - I was just trying to follow existing convention. All I care about is that I can view a str object as a mermaid diagram.

Maybe that just needs a MermaidJS(DisplayObject) class?

@dhirschfeld
Copy link

Maybe the issue title should be changed to:

Allow displaying a string variable as a Mermaid diagram

@Carreau
Copy link
Member

Carreau commented Feb 3, 2024

You can register custom mimetype for any objects, even builtin types, or types you don't control methods of:

https://ipython.readthedocs.io/en/stable/config/integrating.html#formatters-for-third-party-types

https://ipython.readthedocs.io/en/stable/config/shell_mimerenderer.html

https://ipython.readthedocs.io/en/stable/api/generated/IPython.core.formatters.html

That is if you want to display all strings via mermaid.

Otherwise yes, I believe you "just" need an object that define _repr_mimebundle_, which return a dict with the right informations, it does not need to inherit from DisplayObject.

@dhirschfeld
Copy link

Don't you need a MermaidJS mimetype that JupyterLab knows how to display?

From the current markdown implementation it looks like it's being converted to an inline svg:

<div class="jp-RenderedMermaid" style="">
  <figure>
    <img src="data:image/svg+xml,%3Csvg%20<snip>">
  </figure>
</div>

@dhirschfeld
Copy link

NB: the metadata link points to importlib.metadata which is a totally different thing right? (or am I just very confused!?)

of two dictionaries: *data, metadata* (see :ref:`Metadata`).

https://ipython.readthedocs.io/en/stable/config/integrating.html#more-powerful-methods

@dhirschfeld
Copy link

dhirschfeld commented Feb 4, 2024

I can create a string variable, representing html, wrap it in the display.HTML class and have JupyterLab display a rendered view - e.g.

image

I'd like to be able to do the same with a string object representing a mermaid diagram - import a class from IPYthon.display, wrap my string object and have JupyterLab display the rendered diagram:

image

Since not all strings are mermaid diagrams I think I need some custom class to wrap them and it would seem to make sense for that to live alongside the other rich-repr classes in IPython.display?

@dhirschfeld
Copy link

it would seem to make sense for that to live alongside the other rich-repr classes in IPython.display

...it doesn't have to though - I would be happy to define my own class:

class MyMermaidJS:
    def _repr_mimebundle_(self, include=None, exclude=None) -> tuple[dict, dict]:
        ...
        return ???

...I'm just not too sure what I need to return for JupyterLab to understand how to display it as a rendered Mermaid diagram 🤔

@dhirschfeld
Copy link

Also see this talk I did with Paul Ivanov at JupyterCon arround 20 ish minutes you see a prototype where the frontend let you choose the repr you want, making display_* unecaesary anymore.

Yep - I know of your efforts in that area ( ❤️ ) and I've thought for a long time that it would be very useful to have that capability.

Funnily enough, this came up for me again just the other week where the rich-repr of a shapely point is a rather useless dot:

image

...but since you can force the text-repr easily it wasn't a big deal for that use-case.

@Carreau
Copy link
Member

Carreau commented Feb 4, 2024

NB: the metadata link points to importlib.metadata which is a totally different thing right? (or am I just very confused!?)

Gha... sphinx is resolving to the wrong thing indeed.

@Carreau
Copy link
Member

Carreau commented Feb 4, 2024

Yes, JupyterLab would need to know about the mermaid mimetype, it would need a mimerender:

https://jupyterlab.readthedocs.io/en/stable/extension/extension_dev.html#mime-renderer-plugins

Here are a few renderer: https://github.com/jupyterlab/jupyter-renderers

It seem it's currently a provider, I'm not sure the difference between a provider and renderer, you woudl have to ask the JupyterLab team, but my guess is if there is a provider it's likely only a few line to add a render, you just need to decide the mimetipe (and file extension), but mermaid already recommend text/vnd.mermaid, and .mermaid/.mmd.

@dhirschfeld
Copy link

Yes, JupyterLab would need to know about the mermaid mimetype, it would need a mimerender:

I sort-of expected that which was why I initially opened the issue in the JupyterLab repo. I'll try and see what the JL devs say about it.

Thanks for your help here!

@Carreau
Copy link
Member

Carreau commented Feb 4, 2024

There is already a notebook that should display a mermaid diagram:

https://github.com/jupyterlab/jupyterlab/blob/b2f36ff0a2a6c3c9f42ca4501593cb67e1c6a840/galata/test/jupyterlab/notebooks/mermaid_notebook.ipynb

it basically show you what _repr_mime_ should return, except it returns only mermaid, and you should also likely return text/plain, if you want a text repr for frontends that don't support mermaid

@dhirschfeld
Copy link

Cool, that seems to do the job! 🚀

image

@bollwyvl
Copy link
Contributor

bollwyvl commented Feb 5, 2024

Yep, .mmd files and text/vnd.mermaid rendered by mermaid.js is only a widely-implemented (e.g. on GitLab, GitHub, HackMD, and now, nbconvert, jupyterlab, and notebook) way to communicate, not a full multi-stakeholder-managed specification like image/svg+xml with many (albeit semi-incompatible) renderers.

The _repr_mimebundle_ approach for custom objects is the right way, today, and something that was generating these displays dynamically could likely just as easily generate text/vnd.graphviz or other visual outputs.

Indeed, the argument could be made that things like YoutubeVideo are already a bridge too far, and even the venerable LaTeX renderers famously doesn't work the way that the reference implementation does.

Some possible contribution targets for an actual render_mermaid/Mermaid for IPython:

  • ipylab
  • a new jupyterlab-contrib repo
  • a new jupyter-widgets repo (actually embracing the interactivity/hypertext features, instead of explicitly avoiding them for security-at-rest, could be a really fun)

@dhirschfeld
Copy link

Would there be any interest in having this in IPython.display itself, alongside the JSON, HTML, Markdown and other DisplayObjects?

It's certainly where I'd first look for this functionality. (I'd be happy with just the DisplayObject subclass and not bothering with the display_mermaid function)

@MRYingLEE
Copy link

I am not familiar with technical detail. I thought Jupyter notebook was a web application and the ability to display any HTML (including the support of Mermaid diagram) was natural. It seems not.

So may Jupyter provide a more general display_html function? If so, mermaid or any formats supported by web can be displayed. I understand there may be some security concerns.

Any ideas?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants