Markdown renderers for Blazor and MudBlazor
KaTeX integration
If you want to render MathInline
, you need to do following steps.
Install KaTeX in your app
Add this to <head>
element.
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.22/dist/katex.min.css" integrity="sha384-5TcZemv2l/9On385z///+d7MSYlvIEw9FuZTIdZ14vJLqWphw7e7ZPuOiCHJcFCP" crossorigin="anonymous">
using Markdig.Renderers.RazorComponent.Katex;
pipelineBuilder.UseKatex();
Vega-Embed integration
If you want to render Vega and Vega-Lite charts, you need to do following steps.
using Markdig.Renderers.RazorComponent.Vega.Embed;
pipelineBuilder.UseVegaEmbed();
Kroki integration
If you want to render diagrams supported by Kroki, you need to do following steps.
builder.Services.AddKrokiHttpRequestFactory();
using Markdig.Renderers.RazorComponent.Kroki;
pipelineBuilder.UseKroki();
This library is using CSS isolation.
So don't forget to bundle it.
Use MudMarkdown
component.
@using Markdig.Renderers.MudBlazor.Components
<MudMarkdown Value="$ e^{i\theta} = \cos\theta + i\sin\theta $" />
Use MarkdownDocument.ToRenderFragment
extension method.
@using Markdig
@using Markdig.Renderers.RazorComponent
@using Microsoft.AspNetCore.Components.Rendering
@GetMarkdownContent()
@code{
string markdownText = @"
# Heading 1
## Heading 2
### Heading 3
#### Heading 4
##### Heading 5
###### Heading 6
Paragraph
*Emphasis*
**Emphasis**
> BlockQuote
This is a $math block$
a | b
-------|-------
0 | 1
2 | 3
";
RenderFragment GetMarkdownContent()
{
var pipelineBuilder = new MarkdownPipelineBuilder().UseAdvancedExtensions();
var pipeline = pipelineBuilder.Build();
var markdownDocument = Markdown.Parse(markdownText, pipeline);
return markdownDocument.ToRenderFragment(pipeline);
}
}
Just write extension for RazorComponentRenderer
.
Actually, MudBlazor integration is implemented in this way.
public class MudBlazorExtension : IMarkdownExtension
{
public void Setup(MarkdownPipelineBuilder pipeline)
{
}
public void Setup(MarkdownPipeline pipeline, IMarkdownRenderer renderer)
{
if (renderer is not RazorComponentRenderer razorComponentRenderer)
{
return;
}
razorComponentRenderer.ObjectRenderers.TryRemove<RazorComponent.HeadingRenderer>();
razorComponentRenderer.ObjectRenderers.AddIfNotAlready<HeadingRenderer>();
razorComponentRenderer.ObjectRenderers.TryRemove<RazorComponent.ParagraphRenderer>();
razorComponentRenderer.ObjectRenderers.AddIfNotAlready<ParagraphRenderer>();
razorComponentRenderer.ObjectRenderers.TryRemove<RazorComponent.ThematicBreakRenderer>();
razorComponentRenderer.ObjectRenderers.AddIfNotAlready<ThematicBreakRenderer>();
razorComponentRenderer.ObjectRenderers.TryRemove<RazorComponent.Inlines.AutolinkInlineRenderer>();
razorComponentRenderer.ObjectRenderers.AddIfNotAlready<AutolinkInlineRenderer>();
razorComponentRenderer.ObjectRenderers.TryRemove<RazorComponent.Inlines.LinkInlineRenderer>();
razorComponentRenderer.ObjectRenderers.AddIfNotAlready<LinkInlineRenderer>();
razorComponentRenderer.ObjectRenderers.TryRemove<RazorComponent.TableRenderer>();
razorComponentRenderer.ObjectRenderers.AddIfNotAlready<TableRenderer>();
}
}
There is already existing well-known Markdown integration for MudBlazor, MudBlazor.Markdown.
MudBlazor.Markdown has wont-fix issue around rendering MathInline
.
Unlike MudBlazor.Markdown, this library is using KaTeX instead of MathJax and never depends on direct DOM manipulation.
MudBlazor.Markdown is using highlight.js to manipulate DOM directly.
Unlike MudBlazor.Markdown, this library is using ColorCode instead of highlight.js and never depends on direct DOM manipulation.
mermaid.js is very difficult to integrate to Blazor because it does terrible DOM manipulation.
This library is using Kroki, and does not depend on mermaid.js directly.
Use CascadingCodeBlockOptions.OpenCodeBlockContent
to override code block content for Vega-Embed, Kroki open code blocks.
This would be helpful for LLM apps. Open code blocks indicates that the code is imcomplete and rendering them resulted in error.
<CascadingCodeBlockOptions>
<OpenCodeBlockContent>
<MudProgressCircular Indeterminate />
</OpenCodeBlockContent>
<ChildContent>
<MudMarkdown Value="@markdownText" Pipeline="@GetPipeline()" />
</ChildContent>
</CascadingCodeBlockOptions>