diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Renderers/IMarkdownToHtmlRenderer.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Renderers/IMarkdownToHtmlRenderer.cs deleted file mode 100644 index d11e76f6dd..0000000000 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Renderers/IMarkdownToHtmlRenderer.cs +++ /dev/null @@ -1,8 +0,0 @@ -using System.Threading.Tasks; - -namespace Volo.CmsKit.Public.Web.Renderers; - -public interface IMarkdownToHtmlRenderer -{ - Task RenderAsync(string rawMarkdown, bool preventXSS = true); -} diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Renderers/MarkdownToHtmlRenderer.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Renderers/MarkdownToHtmlRenderer.cs deleted file mode 100644 index b6fab3c008..0000000000 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Renderers/MarkdownToHtmlRenderer.cs +++ /dev/null @@ -1,129 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using System.Text.RegularExpressions; -using Markdig; -using System.Threading.Tasks; -using System.Web; -using Volo.Abp.DependencyInjection; -using Ganss.XSS; - -namespace Volo.CmsKit.Public.Web.Renderers; - -public class MarkdownToHtmlRenderer : IMarkdownToHtmlRenderer, ITransientDependency -{ - private readonly HtmlSanitizer _htmlSanitizer; - protected MarkdownPipeline MarkdownPipeline { get; } - - public MarkdownToHtmlRenderer(MarkdownPipeline markdownPipeline) - { - MarkdownPipeline = markdownPipeline; - _htmlSanitizer = new HtmlSanitizer(); - } - - public async Task RenderAsync(string rawMarkdown, bool preventXSS = false) - { - if (preventXSS) - { - rawMarkdown = EncodeHtmlTags(rawMarkdown, true); - } - - var html = Markdown.ToHtml(rawMarkdown, MarkdownPipeline); - - if (preventXSS) - { - html = _htmlSanitizer.Sanitize(html); - } - - return html; - } - - - private static List GetCodeBlockIndices(string markdownText) - { - var regexObj = new Regex(@"```(\w)*|`(\w)*", RegexOptions.IgnoreCase | - RegexOptions.IgnorePatternWhitespace | - RegexOptions.Singleline | - RegexOptions.Multiline | - RegexOptions.ExplicitCapture); - - var matches = regexObj.Matches(markdownText); - var indices = new List(); - - for (var i = 0; i < matches.Count; i++) - { - if (!indices.Any() || indices.Last().EndIndex.HasValue) - { - indices.Add(new CodeBlockIndexPair(matches[i].Index)); - } - else - { - indices.Last().EndIndex = matches[i].Index; - } - } - - return indices; - } - - /// - /// Encodes html tags. - /// - private static string EncodeHtmlTags(string text, bool dontEncodeCodeBlocks = true) - { - List codeBlockIndices = null; - if (dontEncodeCodeBlocks) - { - codeBlockIndices = GetCodeBlockIndices(text); - } - - return Regex.Replace(text, @"<[^>]*>", match => - { - if (dontEncodeCodeBlocks && codeBlockIndices != null) - { - var isInCodeBlock = false; - foreach (var codeBlock in codeBlockIndices) - { - if (IsInCodeBlock(match.Index, codeBlock.StartIndex, codeBlock.EndIndex)) - { - isInCodeBlock = true; - break; - } - } - - if (isInCodeBlock) - { - return match.ToString(); - } - else - { - return HttpUtility.HtmlEncode(match.ToString()); - } - } - else - { - return HttpUtility.HtmlEncode(match.ToString()); - } - }); - } - - private static bool IsInCodeBlock(int currentIndex, int codeBlockStartIndex, int? codeBlockEndIndex) - { - if (codeBlockEndIndex.HasValue) - { - return (currentIndex >= codeBlockStartIndex && currentIndex <= codeBlockEndIndex); - } - - return currentIndex >= codeBlockStartIndex; - } - - private class CodeBlockIndexPair - { - public int StartIndex { get; private set; } - public int? EndIndex { get; set; } - - public CodeBlockIndexPair(int startIndex, int? endIndex = null) - { - StartIndex = startIndex; - EndIndex = endIndex; - } - } -}