예제 #1
0
        /// <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);
        }
예제 #2
0
        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);
        }