# Custom renderers for fenced code blocks/embedded content

**URL:** <https://forum.obsidian.md/t/custom-renderers-for-fenced-code-blocks-embedded-content/1149>\
**Category:** Devs: Plugins & API\
**Created:** [June 3, 2020, 7:14pm UTC](https://forum.obsidian.md/t/custom-renderers-for-fenced-code-blocks-embedded-content/1149 "2020-06-03T19:14:40Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![tang](https://forum.obsidian.md/letter_avatar_proxy/v4/letter/t/e8c25b/32.png) [@tang](https://forum.obsidian.md/u/tang)\
**Post date:** [June 3, 2020, 7:14pm UTC](https://forum.obsidian.md/t/custom-renderers-for-fenced-code-blocks-embedded-content/1149/1 "2020-06-03T19:14:40Z")

</div>

Many Markdown editors, allow for replacing fenced code blocks with some rendering of the content it provides. For instance, [Typora](https://typora.io/) allows one to create a document containing a [mermaid](https://mermaid-js.github.io/mermaid/) diagram:

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

````

And it will be rendered as:

![image](https://forum.obsidian.md/uploads/default/original/1X/ec3a919f2b01bea1fb5bd10ef8688d2e091bcd45.png)

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:

- [Mermaid Integration](https://forum.obsidian.md/t/mermaid-integration/344)
- [Music notation rendering with abcjs](https://forum.obsidian.md/t/music-notation-rendering-with-abcjs/846)
- [Embed tweets, youtube videos, etc](https://forum.obsidian.md/t/embed-tweets-youtube-videos-etc/326)

---

<div class="post-metadata">

**Author:** ![death.au](https://forum.obsidian.md/user_avatar/forum.obsidian.md/death.au/32/796_2.png) [@death.au](https://forum.obsidian.md/u/death.au)\
**Post date:** [June 4, 2020, 12:06pm UTC](https://forum.obsidian.md/t/custom-renderers-for-fenced-code-blocks-embedded-content/1149/2 "2020-06-04T12:06:15Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![tang](https://forum.obsidian.md/letter_avatar_proxy/v4/letter/t/e8c25b/32.png) [@tang](https://forum.obsidian.md/u/tang)\
**Post date:** [June 4, 2020, 5:06pm UTC](https://forum.obsidian.md/t/custom-renderers-for-fenced-code-blocks-embedded-content/1149/3 "2020-06-04T17:06:57Z")

</div>

> [@death.au](#):
>
> I’m undecided on the code fence vs embed syntax.

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.

---

<div class="post-metadata">

**Author:** ![Caketray](https://forum.obsidian.md/letter_avatar_proxy/v4/letter/c/c5a1d2/32.png) [@Caketray](https://forum.obsidian.md/u/Caketray)\
**Post date:** [June 4, 2020, 11:02pm UTC](https://forum.obsidian.md/t/custom-renderers-for-fenced-code-blocks-embedded-content/1149/4 "2020-06-04T23:02:17Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![death.au](https://forum.obsidian.md/user_avatar/forum.obsidian.md/death.au/32/796_2.png) [@death.au](https://forum.obsidian.md/u/death.au)\
**Post date:** [June 5, 2020, 12:45am UTC](https://forum.obsidian.md/t/custom-renderers-for-fenced-code-blocks-embedded-content/1149/5 "2020-06-05T00:45:42Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![tkf](https://forum.obsidian.md/letter_avatar_proxy/v4/letter/t/c77e96/32.png) [@tkf](https://forum.obsidian.md/u/tkf)\
**Post date:** [June 5, 2020, 1:16pm UTC](https://forum.obsidian.md/t/custom-renderers-for-fenced-code-blocks-embedded-content/1149/6 "2020-06-05T13:16:28Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![randulfr](https://forum.obsidian.md/user_avatar/forum.obsidian.md/randulfr/32/1212_2.png) [@randulfr](https://forum.obsidian.md/u/randulfr)\
**Post date:** [June 10, 2020, 1:37pm UTC](https://forum.obsidian.md/t/custom-renderers-for-fenced-code-blocks-embedded-content/1149/7 "2020-06-10T13:37:47Z")

</div>

> [@death.au](#):
>
> The question for this thread then is: given a proper mermaid renderer (as plugin or whatever), should this:
> 
> ````auto
> ```mermaid
> graph TD
> A --> B
> B --> A
> 
> ````
> 
> ```auto
> 
> be rendered in the preview as a mermaid diagram or syntax-highlighted code?
> 
> ```

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

---

<div class="post-metadata">

**Author:** ![death.au](https://forum.obsidian.md/user_avatar/forum.obsidian.md/death.au/32/796_2.png) [@death.au](https://forum.obsidian.md/u/death.au)\
**Post date:** [June 11, 2020, 12:09pm UTC](https://forum.obsidian.md/t/custom-renderers-for-fenced-code-blocks-embedded-content/1149/8 "2020-06-11T12:09:25Z")

</div>

🤔 That seems like a good option.

Looking at [Babelmark](https://babelmark.github.io/?text=%60%60%60javascript+test%0Avar+x+%3D+%27test%27%3B%0A%60%60%60) 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

---

<div class="post-metadata">

**Author:** ![randulfr](https://forum.obsidian.md/user_avatar/forum.obsidian.md/randulfr/32/1212_2.png) [@randulfr](https://forum.obsidian.md/u/randulfr)\
**Post date:** [June 11, 2020, 2:57pm UTC](https://forum.obsidian.md/t/custom-renderers-for-fenced-code-blocks-embedded-content/1149/9 "2020-06-11T14:57:14Z")

</div>

Thanks for the pointer to Babelmark

---

<div class="post-metadata">

**Author:** ![malecjan](https://forum.obsidian.md/letter_avatar_proxy/v4/letter/m/a6a055/32.png) [@malecjan](https://forum.obsidian.md/u/malecjan)\
**Post date:** [January 2, 2021, 1:11pm UTC](https://forum.obsidian.md/t/custom-renderers-for-fenced-code-blocks-embedded-content/1149/10 "2021-01-02T13:11:15Z")

</div>

There are some existing methods for adding attributes to fenced code-blocks that could be reused: [Ability to resize and align mermaid diagrams](https://forum.obsidian.md/t/ability-to-resize-and-align-mermaid-diagrams/7019/6)

---

<div class="post-metadata">

**Author:** ![fcsonline](https://forum.obsidian.md/user_avatar/forum.obsidian.md/fcsonline/32/9533_2.png) [@fcsonline](https://forum.obsidian.md/u/fcsonline)\
**Post date:** [January 30, 2021, 10:21am UTC](https://forum.obsidian.md/t/custom-renderers-for-fenced-code-blocks-embedded-content/1149/11 "2021-01-30T10:21:26Z")

</div>

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

> [@Embed URL Link to show Preview Boxes](https://forum.obsidian.md/t/url-link-preview-boxes/6520/2):
>
> Another example is how notion handles links and turns them into preview cards. I think this may be doable with plugins, no?

---

<div class="post-metadata">

**Author:** ![I-d-as](https://forum.obsidian.md/user_avatar/forum.obsidian.md/i-d-as/32/59965_2.png) [@I-d-as](https://forum.obsidian.md/u/I-d-as)\
**Post date:** [October 1, 2021, 10:52am UTC](https://forum.obsidian.md/t/custom-renderers-for-fenced-code-blocks-embedded-content/1149/12 "2021-10-01T10:52:46Z")

</div>

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 🙂. 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!
