using System; using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Text.RegularExpressions; using System.Windows.Data; using System.Windows.Documents; namespace Juick.Classes { public class RichTextConverter : IValueConverter { static readonly Regex UrlRegex = new Regex(@"http(s)?://([\w+?\.\w+])+([a-zA-Z0-9\~\!\@\#\$\%\^\&\*\(\)_\-\=\+\\\/\?\.\:\;\'\,]*)?", RegexOptions.Compiled); // TODO: Add more entities static readonly Regex JuickEntityRegex = new Regex(@"#(\d+)(/\d+)?", RegexOptions.Compiled); public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { var stringValue = (string)value; if (string.IsNullOrEmpty(stringValue)) { return Enumerable.Empty(); } var result = new List(); var index = 0; foreach (var match in UrlRegex.Matches(stringValue).OfType().Union(JuickEntityRegex.Matches(stringValue).OfType())) { Uri uri = null; if (!Uri.TryCreate(match.Value, UriKind.Absolute, out uri)) { // Juick entity uri = new Uri(string.Format("/ThreadView.xaml?mid={0}", JuickEntityRegex.Replace(match.Value, "$1")), UriKind.Relative); } if (match.Index > 0) { var length = match.Index - index; if (length > 0) { result.Add(new Run { Text = stringValue.Substring(index, length) }); } } var hyperLink = new Hyperlink { NavigateUri = uri }; if (uri.IsAbsoluteUri) { hyperLink.TargetName = "_blank"; hyperLink.Inlines.Add(uri.Host); } else { hyperLink.Inlines.Add(match.Value); } result.Add(hyperLink); index = match.Index + match.Length; } if (index == 0 || index < stringValue.Length - 1) { var lastRunText = stringValue.Substring(index); if (lastRunText.Length > 0) { result.Add(new Run { Text = lastRunText }); } } return result; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { return value; } } }