using Ganss.Xss;
using Markdig;
using Markdig.Syntax;
namespace XFESystem.Documents;
/// <summary>The website's MarkdownService pipeline, independent of ASP.NET and host file access.</summary>
public sealed class MarkdownRenderer
{
private readonly MarkdownPipeline _pipeline = new MarkdownPipelineBuilder()
.UseAdvancedExtensions()
.UseAutoIdentifiers()
.Build();
public string RenderHtml(string? markdown)
{
if (string.IsNullOrEmpty(markdown)) return string.Empty;
// A sanitizer per call avoids sharing its mutable parser across concurrent document previews.
var sanitizer = new HtmlSanitizer();
sanitizer.AllowedTags.Remove("button");
sanitizer.AllowedTags.Remove("script");
sanitizer.AllowedTags.Remove("css");
sanitizer.AllowedAttributes.Add("id");
sanitizer.AllowedAttributes.Add("class");
sanitizer.AllowedAttributes.Remove("script");
return sanitizer.Sanitize(Markdown.ToHtml(markdown, _pipeline));
}
public MarkdownDocument Parse(string? markdown) => Markdown.Parse(markdown ?? string.Empty, _pipeline);
}
using Ganss.Xss;
using Markdig;
using Markdig.Syntax;
namespace XFESystem.Documents;
/// <summary>The website's MarkdownService pipeline, independent of ASP.NET and host file access.</summary>
public sealed class MarkdownRenderer
{
private readonly MarkdownPipeline _pipeline = new MarkdownPipelineBuilder()
.UseAdvancedExtensions()
.UseAutoIdentifiers()
.Build();
public string RenderHtml(string? markdown)
{
if (string.IsNullOrEmpty(markdown)) return string.Empty;
// A sanitizer per call avoids sharing its mutable parser across concurrent document previews.
var sanitizer = new HtmlSanitizer();
sanitizer.AllowedTags.Remove("button");
sanitizer.AllowedTags.Remove("script");
sanitizer.AllowedTags.Remove("css");
sanitizer.AllowedAttributes.Add("id");
sanitizer.AllowedAttributes.Add("class");
sanitizer.AllowedAttributes.Remove("script");
return sanitizer.Sanitize(Markdown.ToHtml(markdown, _pipeline));
}
public MarkdownDocument Parse(string? markdown) => Markdown.Parse(markdown ?? string.Empty, _pipeline);
}