#region using using System; using System.Globalization; using System.Text.RegularExpressions; using BlogEngine.Core; using BlogEngine.Core.Web.Controls; #endregion /// /// Auto resolves URLs in the comments and turn them into valid hyperlinks. /// [Extension("Auto resolves URLs in the comments and turn them into valid hyperlinks.", "1.4", "BlogEngine.NET")] public class ResolveLinks { static ResolveLinks() { Comment.Serving += new EventHandler(Post_CommentServing); } /// /// The regular expression used to parse links. /// private static readonly Regex regex = new Regex("((http://|https://|www\\.)([A-Z0-9.\\-]{1,})\\.[0-9A-Z?;~&\\(\\)#,=\\-_\\./\\+]{2,})", RegexOptions.Compiled | RegexOptions.IgnoreCase); private const string link = "{2}"; private const int MAX_LENGTH = 50; /// /// The event handler that is triggered every time a comment is served to a client. /// private static void Post_CommentServing(object sender, ServingEventArgs e) { if (string.IsNullOrEmpty(e.Body)) return; e.Body = regex.Replace(e.Body, new MatchEvaluator(ResolveLinks.Evaluator)); } /// /// Evaluates the replacement for each link match. /// public static string Evaluator(Match match) { CultureInfo info = CultureInfo.InvariantCulture; if (!match.Value.Contains("://")) { return string.Format(info, link, "http://", match.Value, ShortenUrl(match.Value, MAX_LENGTH)); } else { return string.Format(info, link, string.Empty, match.Value, ShortenUrl(match.Value, MAX_LENGTH)); } } /// /// Shortens any absolute URL to a specified maximum length /// private static string ShortenUrl(string url, int max) { if (url.Length <= max) return url; // Remove the protocal int startIndex = url.IndexOf("://"); if (startIndex > -1) url = url.Substring(startIndex + 3); if (url.Length <= max) return url; // Compress folder structure int firstIndex = url.IndexOf("/") + 1; int lastIndex = url.LastIndexOf("/"); if (firstIndex < lastIndex) { url = url.Remove(firstIndex, lastIndex - firstIndex); url = url.Insert(firstIndex, "..."); } if (url.Length <= max) return url; // Remove URL parameters int queryIndex = url.IndexOf("?"); if (queryIndex > -1) url = url.Substring(0, queryIndex); if (url.Length <= max) return url; // Remove URL fragment int fragmentIndex = url.IndexOf("#"); if (fragmentIndex > -1) url = url.Substring(0, fragmentIndex); if (url.Length <= max) return url; // Compress page firstIndex = url.LastIndexOf("/") + 1; lastIndex = url.LastIndexOf("."); if (lastIndex - firstIndex > 10) { string page = url.Substring(firstIndex, lastIndex - firstIndex); int length = url.Length - max + 3; if (page.Length > length) url = url.Replace(page, "..." + page.Substring(length)); } return url; } }