Files
Shrlalgo.RvKits/Melskin/Converters/Internal/StringToMarkDownConverter.cs
2026-02-17 22:17:13 +08:00

63 lines
2.8 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System.Globalization;
using System.Text.RegularExpressions;
using System.Windows.Data;
using System.Windows.Documents;
namespace Melskin.Converters.Internal;
/// <summary>
/// StringToMarkDownConverter 类用于将普通字符串转换为具有Markdown格式的富文本显示。该类实现了IValueConverter接口主要功能是通过正则表达式识别并处理字符串中的代码块以反引号`包围的部分将其转换为带有特定前景色和背景色的富文本Run对象并嵌入到TextBlock中返回。
/// </summary>
/// <remarks>
/// 本转换器特别适用于需要在WPF应用程序中展示含有内联代码样式的Markdown文本的情况。它会自动处理输入字符串中的换行符并将匹配到的代码片段高亮显示。
/// </remarks>
internal class StringToMarkDownConverter : IValueConverter
{
// Explicit static constructor to tell C# compiler
// not to mark type as beforefieldinit
private StringToMarkDownConverter() { }
/// <summary>
/// 获取 StringToMarkDownConverter 的单例实例。此属性确保在整个应用程序生命周期中只有一个 StringToMarkDownConverter 实例被创建和使用,从而提高性能并减少内存占用。
/// </summary>
/// <returns>返回一个 StringToMarkDownConverter 类型的实例。</returns>
/// <remarks>
/// 该属性通过延迟初始化Lazy Initialization模式来实现单例模式首次访问时才创建实例。这样可以保证在多线程环境下也能安全地获取到唯一的实例。
/// </remarks>
public static readonly StringToMarkDownConverter Instance = new();
/// <inheritdoc />
public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
{
var str = value as string;
var textBlock = new TextBlock() { TextWrapping = TextWrapping.Wrap };
if (string.IsNullOrEmpty(str)) return textBlock;
const string pattern = @"`(.*?)`";
var index = 0;
var inlines = textBlock.Inlines;
str = str?.Replace(@"\n", Environment.NewLine);
var foreground = new SolidColorBrush(Color.FromRgb(31, 46, 59));
var background = new SolidColorBrush(Color.FromRgb(242, 244, 245));
if (str == null) return textBlock;
foreach (Match match in Regex.Matches(str, pattern))
{
inlines.Add(str.Substring(index, match.Index - index));
inlines.Add(new Run(match.Value.Replace('`', ' ')) { Foreground = foreground, Background = background });
index = match.Index + match.Length;
}
inlines.Add(str.Substring(index));
return textBlock;
}
/// <inheritdoc />
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return DependencyProperty.UnsetValue;
}
}