Custom renderers for fenced code blocks/embedded content

Many Markdown editors, allow for replacing fenced code blocks with some rendering of the content it provides. For instance, Typora allows one to create a document containing a mermaid diagram:

```mermaid
graph TD
  A --> B
  B --> A
```

And it will be rendered as:

image

It’d be awesome if Obsidian’s plugin API allowed defining custom renderers like this. It would allow one be more productive by putting domain-specific content into their notes without needing to resort to screenshots.

Note that there’s probably some unification to be had across renderers for code fences like above, inline includes (e.g. ![[diagram.mermaid]]), and just viewing a custom file type in the file explorer.

Allowing custom renderers for content would allow many kinds of plugins to be relatively easily implemented, including:

13 Likes

I was thinking about this myself, recently, so thank you for posting this.

I’m undecided on the code fence vs embed syntax.

I think I’m leaning towards embed syntax though. It would allow me to, say, write a note about working with mermaid, have a syntax highlighted code fence to describe the syntax (assuming mermaid syntax highlighting is supported), then embed the diagram to show the results.

However, I’ll then have to create/open a separate file to define the diagram. :thinking:

2 Likes

I’d love to be able to have both (I personally use the inline version much more, for no reason other than convenience, maybe interoperability). Perhaps configurable globally per vault and/or per note via YAML front-matter? Although, any custom metadata increases the scope of Obsidian beyond “markdown note-taking app”…

edit: To expand on this, I imagine the ![[embed]] syntax to mean something like, “render this file and then embed the result here”. For markdown documents, this is recursing into the document and putting the result into a box with some extra chrome. Image embeds can be replaces by the related <img src.... I imagine this remains coherent for custom embeds, like Mermaid diagrams.

But something here feels very "special case"d. How would e.g. Twitter posts or Youtube videos be embedded? They’re not files in the vault, so should the ![[youtube.com/...]] syntax take a URI instead and match on specific domains? Should it reuse the image syntax ![alt text](youtube.com/...) and treat certain URL patterns as a custom file type? It could even use new syntax, for example something Discourse-inspired: [youtube="youtube.com/..."], which could allow for extensible custom elements.

In my personal opinion, the [[double brackets]] should stay exclusive to internal links to avoid confusion. Reusing the image syntax makes sense to me - the []() syntax is the same for local or external links, and ! being the universal syntax for “embed this thing” whether the thing is a note link, local image address, YouTube link, etc. makes it nice and simple

4 Likes

I agree. I see ! as “embed” when placed in front of a link, and double brackets as “internal link”.
So, following that logic, ![[diagram.mermaid]] should embed the mermaid diagram from the vault (preferably rendered).

Syntax for embedding online content (youtube, tweets) is probably a discussion for another thread, but ![](https://youtube.com/...) seems okay, but potentially problematic for other markdown parsers that would just show a broken image link here.

The question for this thread then is: given a proper mermaid renderer (as plugin or whatever), should this:

```mermaid
graph TD
  A --> B
  B --> A
```

be rendered in the preview as a mermaid diagram or syntax-highlighted code?

(prism.js/Obsidian doesn’t support mermaid syntax highlighting right now, so the example is flawed, but the question remains)

I am against using image url format, because it will really mess the things in other MD editors. For interoperability with other editors it will be good to use either embed format, or some custom tagging like *[[url]] for example

2 Likes

Definitely should be rendered in Preview as syntax-highlighted code. I believe this is what the code-fence indicates, and you def want to retain ability to render as ‘code’ for certain class of use cases.

That said, it would still be nice if “domain-specific markup” like mermaid could be recognized by a plugin and rendered in Preview. (I call it DSM because mermaid seems more like markdown than like, say, python.)

But your question remains, how to indicate that this text should be rendered according to some custom rules?

Since you would still need to somehow demarcate the text that should be considered as custom markup for the plugin to handle, one idea could be to ‘extend’ the code fence grammar to indicate an alt rendering is desired.

For example, something in form:
```language [style]…
where optional token ‘style’ indicates the alternate rendering.

So:
```mermaid graph
would indicate to render the mermaid code as a graph, not as code. (I do notice that adding a second token to the code fence grammar right now doesn’t break it, it seems to ignore it…so might not break other md tools.)

4 Likes

:thinking: That seems like a good option.

Looking at Babelmark it seems that most things that accept the language name in the code fence either ignore the second parameter or simply include it in the class for the output.

A good thing to keep in mind when developing plugins

3 Likes

Thanks for the pointer to Babelmark

There are some existing methods for adding attributes to fenced code-blocks that could be reused: Ability to resize and align mermaid diagrams

This thread is also related to the mentioned capability of customizing how to render some kind of content. In this case, remote links:

1 Like

In case anyone is interested, I did notice that Mermaid was recently added to the list of supported languages for Prism. Not sure if that is actually completely relevant to the discussion at hand. I only noticed because I had requested a now newly supported language implemented at just about the same exact time as Mermaid. Consequently, I am anxiously awaiting to see whether the next update to Obsidian with possibly an updated version of Prism, will make it work.

Thanks.

Edit 2: I am very happy to report that it appears the new mobile app release of Obsidian has updated versions of Prismjs and thus incorporated the new language that I had requested and which was implemented in Prismjs 25.0. So I imagine this also means that Mermaid syntax highlighting is in as well. All I know is that MAXScript syntax highlighting now works in Obsidian Mobile. I have to pat myself on the back for the request and give thanks to the awesome developers for making this tool that is bringing many of my favorite things together in one place :slightly_smiling_face:. Looking forward to next desktop release with hopes the upgrade is made there as well.

Edit 1: I may have jumped the gun. Looks like Mermaid is not in the Obsidian 0.12.17 Prism 24.1 implementation which I believe is the current. Correct me if I am wrong. I’d love to know how this works. Appreciation in advance!