/// <summary> /// The format message. /// </summary> /// <param name="message"> /// The message. /// </param> /// <param name="messageFlags"> /// The message flags. /// </param> /// <param name="targetBlankOverride"> /// The target blank override. /// </param> /// <param name="messageLastEdited"> /// The message last edited. /// </param> /// <returns> /// The formatted message. /// </returns> public string FormatMessage( [NotNull] string message, [NotNull] MessageFlags messageFlags, bool targetBlankOverride, DateTime messageLastEdited) { var boardSettings = this.Get <YafBoardSettings>(); var useNoFollow = boardSettings.UseNoFollowLinks; // check to see if no follow should be disabled since the message is properly aged if (useNoFollow && boardSettings.DisableNoFollowLinksAfterDay > 0) { var messageAge = messageLastEdited - DateTime.UtcNow; if (messageAge.Days > boardSettings.DisableNoFollowLinksAfterDay) { // disable no follow useNoFollow = false; } } // do html damage control message = this.RepairHtml(message, messageFlags.IsHtml); // get the rules engine from the creator... var ruleEngine = this.ProcessReplaceRuleFactory( new[] { true /*messageFlags.IsBBCode*/, targetBlankOverride, useNoFollow }); // see if the rules are already populated... if (!ruleEngine.HasRules) { // populate // get rules for YafBBCode this.Get <IBBCode>() .CreateBBCodeRules(ruleEngine, messageFlags.IsHtml, true, targetBlankOverride, useNoFollow); // add email rule // vzrus: it's freezing when post body contains full email address. // the fix provided by community var email = new VariableRegexReplaceRule( _RgxEmail, "${before}<a href=\"mailto:${inner}\">${inner}</a>", new[] { "before" }) { RuleRank = 31 }; ruleEngine.AddRule(email); // URLs Rules var target = (boardSettings.BlankLinks || targetBlankOverride) ? "target=\"_blank\"" : string.Empty; var nofollow = useNoFollow ? "rel=\"nofollow\"" : string.Empty; var youtubeVideo1 = new VariableRegexReplaceRule( _RgxYoutube1, "${before}<div class=\"YoutubeVideoEmbed\"><iframe src=\"//www.youtube.com/embed/${videoId}?wmode=transparent\" width=\"560\" height=\"315\" allowfullscreen=\"true\" allowscriptaccess=\"always\" scrolling=\"no\" frameborder=\"0\"></iframe></div>", new[] { "before", "videoId" }, new[] { string.Empty }, 50) { RuleRank = 40 }; ruleEngine.AddRule(youtubeVideo1); var youtubeVideo2 = new VariableRegexReplaceRule( _RgxYoutube2, "${before}<div class=\"YoutubeVideoEmbed\"><iframe src=\"//www.youtube.com/embed/${videoId}?wmode=transparent\" width=\"560\" height=\"315\" allowfullscreen=\"true\" allowscriptaccess=\"always\" scrolling=\"no\" frameborder=\"0\"></iframe></div>", new[] { "before", "videoId" }, new[] { string.Empty }, 50) { RuleRank = 41 }; ruleEngine.AddRule(youtubeVideo2); var url = new VariableRegexReplaceRule( _RgxUrl1, "${before}<a {0} {1} href=\"${inner}\" title=\"${inner}\">${innertrunc}</a>".Replace("{0}", target) .Replace("{1}", nofollow), new[] { "before" }, new[] { string.Empty }, 50) { RuleRank = 42 }; ruleEngine.AddRule(url); // ?<! - match if prefixes href="" and src="" are not present // <inner> = named capture group // (http://|https://|ftp://) - numbered capture group - select from 3 alternatives // Match expression but don't capture it, one or more repetions, in the end is dot(\.)? here we match "www." - (?:[\w-]+\.)+ // Match expression but don't capture it, zero or one repetions (?:/[\w-./?%&=+;,:#~$]*[^.<])? // (?<inner>(http://|https://|ftp://)(?:[\w-]+\.)+[\w-]+(?:/[\w-./?%&=+;,:#~$]*[^.<])?) url = new VariableRegexReplaceRule( _RgxUrl2, "${before}<a {0} {1} href=\"${inner}\" title=\"${inner}\">${innertrunc}</a>".Replace("{0}", target) .Replace("{1}", nofollow), new[] { "before" }, new[] { string.Empty }, 50) { RuleRank = 43 }; ruleEngine.AddRule(url); url = new VariableRegexReplaceRule( _RgxUrl3, "${before}<a {0} {1} href=\"http://${inner}\" title=\"http://${inner}\">${innertrunc}</a>".Replace( "{0}", target).Replace("{1}", nofollow), new[] { "before" }, new[] { string.Empty }, 50) { RuleRank = 44 }; ruleEngine.AddRule(url); } message = this.Get <IBadWordReplace>().Replace(message); // process... ruleEngine.Process(ref message); // Format Emoticons message = EmojiOne.ShortnameToUnicode(message, true); return(message); }
public void ShortnameToUnicode() { // shortname to unicode string text = "Hello world! π :smile:"; string expected = "Hello world! π π"; string actual = EmojiOne.ShortnameToUnicode(text); Assert.AreEqual(expected, actual); // single shortname text = ":snail:"; expected = "π"; actual = EmojiOne.ShortnameToUnicode(text); Assert.AreEqual(expected, actual); // shortname mid sentence with a comma text = "The :unicorn:, is Emoji One's official mascot."; expected = "The π¦, is Emoji One's official mascot."; actual = EmojiOne.ShortnameToUnicode(text); Assert.AreEqual(expected, actual); // shortname at start of sentence text = ":snail: mail."; expected = "π mail."; actual = EmojiOne.ShortnameToUnicode(text); Assert.AreEqual(expected, actual); // shortname at start of sentence with apostrophe text = ":snail:'s are cool!"; expected = "π's are cool!"; actual = EmojiOne.ShortnameToUnicode(text); Assert.AreEqual(expected, actual); // shortname shares a colon text = ":invalid:snail:"; expected = ":invalidπ"; actual = EmojiOne.ShortnameToUnicode(text); Assert.AreEqual(expected, actual); // mixed ascii, regular unicode and duplicate emoji text = ":alien: is π½ and μ is not :alien: or :alien: also :randomy: is not emoji"; expected = "π½ is π½ and μ is not π½ or π½ also :randomy: is not emoji"; actual = EmojiOne.ShortnameToUnicode(text); Assert.AreEqual(expected, actual); // multiline emoji string text = ":dancer:\n:dancer:"; expected = "π\nπ"; actual = EmojiOne.ShortnameToUnicode(text); Assert.AreEqual(expected, actual); // triple emoji string text = ":dancer::dancer::alien:"; expected = "πππ½"; actual = EmojiOne.ShortnameToUnicode(text); Assert.AreEqual(expected, actual); // shortname at end of sentence text = "Emoji One's official mascot is :unicorn:."; expected = "Emoji One's official mascot is π¦."; actual = EmojiOne.ShortnameToUnicode(text); Assert.AreEqual(expected, actual); // shortname at end of sentence with alternate punctuation text = "Emoji One's official mascot is :unicorn:!"; expected = "Emoji One's official mascot is π¦!"; actual = EmojiOne.ShortnameToUnicode(text); Assert.AreEqual(expected, actual); // shortname at end of sentence with preceeding colon text = "Emoji One's official mascot: :unicorn:"; expected = "Emoji One's official mascot: π¦"; actual = EmojiOne.ShortnameToUnicode(text); Assert.AreEqual(expected, actual); // shortname inside of IMG tag text = $@"The <img class=""emojione"" alt="":unicorn:"" src=""{EmojiOne.ImagePath}{EmojiOne.EmojiSize}/1f984.png"" /> is Emoji One's official mascot."; expected = text; actual = EmojiOne.ShortnameToUnicode(text); Assert.AreEqual(expected, actual); // shortname to unicode with code pairs text = ":nine:"; expected = "9β£"; actual = EmojiOne.ShortnameToUnicode(text); Assert.AreEqual(expected, actual); // shortname alias text = ":poo:"; expected = "π©"; actual = EmojiOne.ShortnameToUnicode(text); Assert.AreEqual(expected, actual); }