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:

11 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

3 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

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.)

2 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