using System.Globalization;
using System.Text.RegularExpressions;
using System.Windows.Data;
using System.Windows.Documents;
namespace Melskin.Converters.Internal;
///
/// StringToMarkDownConverter 类用于将普通字符串转换为具有Markdown格式的富文本显示。该类实现了IValueConverter接口,主要功能是通过正则表达式识别并处理字符串中的代码块(以反引号`包围的部分),将其转换为带有特定前景色和背景色的富文本Run对象,并嵌入到TextBlock中返回。
///
///
/// 本转换器特别适用于需要在WPF应用程序中展示含有内联代码样式的Markdown文本的情况。它会自动处理输入字符串中的换行符,并将匹配到的代码片段高亮显示。
///
internal class StringToMarkDownConverter : IValueConverter
{
// Explicit static constructor to tell C# compiler
// not to mark type as beforefieldinit
private StringToMarkDownConverter() { }
///
/// 获取 StringToMarkDownConverter 的单例实例。此属性确保在整个应用程序生命周期中只有一个 StringToMarkDownConverter 实例被创建和使用,从而提高性能并减少内存占用。
///
/// 返回一个 StringToMarkDownConverter 类型的实例。
///
/// 该属性通过延迟初始化(Lazy Initialization)模式来实现单例模式,首次访问时才创建实例。这样可以保证在多线程环境下也能安全地获取到唯一的实例。
///
public static readonly StringToMarkDownConverter Instance = new();
///
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;
}
///
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return DependencyProperty.UnsetValue;
}
}