/// <summary> /// Creates the rules that convert <see cref="YafBBCode"/> to HTML /// </summary> /// <param name="ruleEngine"> /// The rule Engine. /// </param> /// <param name="doFormatting"> /// The do Formatting. /// </param> /// <param name="targetBlankOverride"> /// The target Blank Override. /// </param> /// <param name="useNoFollow"> /// The use No Follow. /// </param> /// <param name="convertBBQuotes"> /// The convert BB Quotes. /// </param> public void CreateBBCodeRules( IProcessReplaceRules ruleEngine, bool doFormatting, bool targetBlankOverride, bool useNoFollow, bool convertBBQuotes) { string target = (this.Get<YafBoardSettings>().BlankLinks || targetBlankOverride) ? "target=\"_blank\"" : string.Empty; string nofollow = useNoFollow ? "rel=\"nofollow\"" : string.Empty; const string ClassModal = "class=\"ceebox\""; // pull localized strings string localQuoteStr = this.Get<ILocalization>().GetText("COMMON", "BBCODE_QUOTE"); string localCodeStr = this.Get<ILocalization>().GetText("COMMON", "BBCODE_CODE"); // handle font sizes -- this rule class internally handles the "size" variable ruleEngine.AddRule( new FontSizeRegexReplaceRule(_RgxSize, @"<span style=""font-size:${size}"">${inner}</span>", _Options)); if (doFormatting) { ruleEngine.AddRule( new CodeRegexReplaceRule( _rgxNoParse, @"${inner}")); ruleEngine.AddRule(new SimpleRegexReplaceRule(_rgxBold, "<strong>${inner}</strong>")); ruleEngine.AddRule(new SimpleRegexReplaceRule(_RgxStrike, "<s>${inner}</s>", _Options)); ruleEngine.AddRule(new SimpleRegexReplaceRule(_RgxItalic, "<em>${inner}</em>", _Options)); ruleEngine.AddRule(new SimpleRegexReplaceRule(_RgxUnderline, "<u>${inner}</u>", _Options)); ruleEngine.AddRule( new SimpleRegexReplaceRule(_RgxHighlighted, @"<span class=""highlight"">${inner}</span>", _Options)); // e-mails ruleEngine.AddRule( new VariableRegexReplaceRule( _rgxEmail2, "<a href=\"mailto:${email}\">${inner}</a>", new[] { "email" })); ruleEngine.AddRule(new SimpleRegexReplaceRule(_rgxEmail1, @"<a href=""mailto:${inner}"">${inner}</a>")); // urls ruleEngine.AddRule( new VariableRegexReplaceRule( _rgxUrl2, "<a {0} {1} href=\"${http}${url}\" title=\"${http}${url}\">${inner}</a>".Replace("{0}", target).Replace("{1}", nofollow), new[] { "url", "http" }, new[] { string.Empty, string.Empty // "http://" })); ruleEngine.AddRule( new VariableRegexReplaceRule( _rgxUrl1, "<a {0} {1} href=\"${http}${inner}\" title=\"${http}${inner}\">${http}${innertrunc}</a>".Replace("{0}", target).Replace("{1}", nofollow), new[] { "http" }, new[] { string.Empty, string.Empty // "http://" }, 50)); // urls ruleEngine.AddRule( new VariableRegexReplaceRule( _rgxModalUrl2, "<a {0} {1} {2} href=\"${http}${url}\" title=\"${http}${url}\">${inner}</a>".Replace("{0}", target).Replace("{1}", nofollow).Replace("{2}", ClassModal), new[] { "url", "http" }, new[] { string.Empty, string.Empty // "http://" })); ruleEngine.AddRule( new VariableRegexReplaceRule( _rgxModalUrl1, "<a {0} {1} {2} href=\"${http}${inner}\" title=\"${http}${inner}\">${http}${innertrunc}</a>".Replace("{0}", target).Replace("{1}", nofollow).Replace("{2}", ClassModal), new[] { "http" }, new[] { string.Empty, string.Empty // "http://" }, 50)); // font ruleEngine.AddRule( new VariableRegexReplaceRule( _RgxFont, "<span style=\"font-family:${font}\">${inner}</span>", _Options, new[] { "font" })); // color ruleEngine.AddRule( new VariableRegexReplaceRule( _RgxColor, "<span style=\"color:${color}\">${inner}</span>", _Options, new[] { "color" })); // lists ruleEngine.AddRule(new SimpleRegexReplaceRule(_RgxList1, "<ul>${inner}</ul>", _Options)); /*ruleEngine.AddRule( new VariableRegexReplaceRule(_rgxList2, "<ol type=\"${type}\">${inner}</ol>", _options, new[] { "type" }));*/ ruleEngine.AddRule(new SimpleRegexReplaceRule(_RgxListNumber, "<ol style=\"list-style-type:number\">${inner}</ol>", RegexOptions.Singleline)); ruleEngine.AddRule(new SimpleRegexReplaceRule(_RgxListLowerRoman, "<ol style=\"list-style-type:lower-roman\">${inner}</ol>", RegexOptions.Singleline)); ruleEngine.AddRule(new SimpleRegexReplaceRule(_RgxListUpperRoman, "<ol style=\"list-style-type:upper-roman\">${inner}</ol>", RegexOptions.Singleline)); ruleEngine.AddRule(new SimpleRegexReplaceRule(_RgxListLowerAlpha, "<ol style=\"list-style-type:lower-alpha\">${inner}</ol>", RegexOptions.Singleline)); ruleEngine.AddRule(new SimpleRegexReplaceRule(_RgxListUpperAlpha, "<ol style=\"list-style-type:upper-alpha\">${inner}</ol>", RegexOptions.Singleline)); // bullets ruleEngine.AddRule(new SingleRegexReplaceRule(_RgxBullet, "<li>", _Options)); // alignment ruleEngine.AddRule( new SimpleRegexReplaceRule(_RgxCenter, "<div align=\"center\">${inner}</div>", _Options)); ruleEngine.AddRule(new SimpleRegexReplaceRule(_RgxLeft, "<div align=\"left\">${inner}</div>", _Options)); ruleEngine.AddRule( new SimpleRegexReplaceRule(_RgxRight, "<div align=\"right\">${inner}</div>", _Options)); // indent ruleEngine.AddRule( new SimpleRegexReplaceRule(_RgxIndent, "<div style=\"margin-left:40px\">${inner}</div>", _Options)); // add max-width and max-height to posted Image var maxWidth = this.Get<YafBoardSettings>().ImageAttachmentResizeWidth; var maxHeight = this.Get<YafBoardSettings>().ImageAttachmentResizeHeight; string styleAttribute = this.Get<YafBoardSettings>().ResizePostedImages ? " style=\"max-width:{0}px;max-height:{1}px\"".FormatWith( maxWidth, maxHeight) : string.Empty; // image ruleEngine.AddRule( new VariableRegexReplaceRule( _rgxImg, "<img src=\"${http}${inner}\" alt=\"UserPostedImage\" class=\"UserPostedImage\"{0} />".Replace( "{0}", styleAttribute), new[] { "http" }, new[] { "http://" }) { RuleRank = 70 }); ruleEngine.AddRule( new VariableRegexReplaceRule( _rgxImgEmptyTitle, "<img src=\"${http}${inner}\" alt=\"UserPostedImage\" class=\"UserPostedImage\"{0} />".Replace( "{0}", styleAttribute), new[] { "http" }, new[] { "http://" }) { RuleRank = 71 }); ruleEngine.AddRule( new VariableRegexReplaceRule( _rgxImgTitle, "<img src=\"${http}${inner}\" alt=\"${description}\" title=\"${description}\" class=\"UserPostedImage\"{0} />" .Replace("{0}", styleAttribute), new[] { "http", "description" }, new[] { "http://", string.Empty }) { RuleRank = 72 }); // basic hr and br rules var hrRule = new SingleRegexReplaceRule( _RgxHr, "<hr />", RegexOptions.IgnoreCase | RegexOptions.Multiline); // Multiline, since ^ must match beginning of line var brRule = new SingleRegexReplaceRule( _RgxBr, "<br />", RegexOptions.IgnoreCase | RegexOptions.Multiline) { RuleRank = hrRule.RuleRank + 1 }; // Ensure the newline rule is processed after the HR rule, otherwise the newline characters in the HR regex will never match ruleEngine.AddRule(hrRule); ruleEngine.AddRule(brRule); } // add smilies this.AddSmiles(ruleEngine); if (convertBBQuotes) { // add rule for code block type with syntax highlighting ruleEngine.AddRule( new SyntaxHighlightedCodeRegexReplaceRule( _regexCodeWithLanguage, @"<div class=""code""><strong>{0}</strong><div class=""innercode"">${inner}</div></div>".Replace("{0}", localCodeStr)) { RuleRank = 40 }); // handle custom YafBBCode this.AddCustomBBCodeRules(ruleEngine); // add rule for code block type with no syntax highlighting ruleEngine.AddRule( new CodeRegexReplaceRule( _rgxCode1, @"<div class=""code""><strong>{0}</strong><div class=""innercode"">${inner}</div></div>".Replace("{0}", localCodeStr))); ruleEngine.AddRule( new QuoteRegexReplaceRule( OpenQuoteUserIdRegex, @"<div class=""quote""><span class=""quotetitle"">${quote}</span><div class=""innerquote"">", _Options)); // simple open quote tag var simpleOpenQuoteReplace = @"<div class=""quote""><span class=""quotetitle"">{0}</span><div class=""innerquote"">" .FormatWith(localQuoteStr); ruleEngine.AddRule( new SimpleRegexReplaceRule(OpenQuoteRegex, simpleOpenQuoteReplace, _Options) { RuleRank = 62 }); // and finally the closing quote tag ruleEngine.AddRule( new SingleRegexReplaceRule(CloseQuoteRegex, "</div></div>", _Options) { RuleRank = 63 }); } // post and topic rules... ruleEngine.AddRule( new PostTopicRegexReplaceRule( _RgxPost, @"<a href=""${post}"" title=""${inner}"">${inner}</a>", _Options)); ruleEngine.AddRule( new PostTopicRegexReplaceRule( _RgxTopic, @"<a href=""${topic}"" title=""${inner}"">${inner}</a>", _Options)); }
/// <summary> /// Creates the rules that convert <see cref="YafBBCode"/> to HTML /// </summary> /// <param name="ruleEngine"> /// The rule Engine. /// </param> /// <param name="doFormatting"> /// The do Formatting. /// </param> /// <param name="targetBlankOverride"> /// The target Blank Override. /// </param> /// <param name="useNoFollow"> /// The use No Follow. /// </param> /// <param name="convertBBQuotes"> /// The convert BB Quotes. /// </param> public void CreateBBCodeRules( IProcessReplaceRules ruleEngine, bool doFormatting, bool targetBlankOverride, bool useNoFollow, bool convertBBQuotes) { string target = (this.Get<YafBoardSettings>().BlankLinks || targetBlankOverride) ? "target=\"_blank\"" : string.Empty; string nofollow = useNoFollow ? "rel=\"nofollow\"" : string.Empty; const string ClassModal = "class=\"ceebox\""; // pull localized strings string localQuoteStr = this.Get<ILocalization>().GetText("COMMON", "BBCODE_QUOTE"); string localQuoteWroteStr = this.Get<ILocalization>().GetText("COMMON", "BBCODE_QUOTEWROTE"); string localQuotePostedStr = this.Get<ILocalization>().GetText("COMMON", "BBCODE_QUOTEPOSTED"); string localCodeStr = this.Get<ILocalization>().GetText("COMMON", "BBCODE_CODE"); // handle font sizes -- this rule class internally handles the "size" variable ruleEngine.AddRule( new FontSizeRegexReplaceRule(_RgxSize, @"<span style=""font-size:${size}"">${inner}</span>", _Options)); if (doFormatting) { ruleEngine.AddRule( new CodeRegexReplaceRule( _rgxNoParse, @"${inner}")); ruleEngine.AddRule(new SimpleRegexReplaceRule(_rgxBold, "<b>${inner}</b>")); ruleEngine.AddRule(new SimpleRegexReplaceRule(_RgxStrike, "<s>${inner}</s>", _Options)); ruleEngine.AddRule(new SimpleRegexReplaceRule(_RgxItalic, "<em>${inner}</em>", _Options)); ruleEngine.AddRule(new SimpleRegexReplaceRule(_RgxUnderline, "<u>${inner}</u>", _Options)); ruleEngine.AddRule( new SimpleRegexReplaceRule(_RgxHighlighted, @"<span class=""highlight"">${inner}</span>", _Options)); // e-mails ruleEngine.AddRule( new VariableRegexReplaceRule( _rgxEmail2, "<a href=\"mailto:${email}\">${inner}</a>", new[] { "email" })); ruleEngine.AddRule(new SimpleRegexReplaceRule(_rgxEmail1, @"<a href=""mailto:${inner}"">${inner}</a>")); // urls ruleEngine.AddRule( new VariableRegexReplaceRule( _rgxUrl2, "<a {0} {1} href=\"${http}${url}\" title=\"${http}${url}\">${inner}</a>".Replace("{0}", target).Replace("{1}", nofollow), new[] { "url", "http" }, new[] { string.Empty, string.Empty // "http://" })); ruleEngine.AddRule( new VariableRegexReplaceRule( _rgxUrl1, "<a {0} {1} href=\"${http}${inner}\" title=\"${http}${inner}\">${http}${innertrunc}</a>".Replace("{0}", target).Replace("{1}", nofollow), new[] { "http" }, new[] { string.Empty, string.Empty // "http://" }, 50)); // urls ruleEngine.AddRule( new VariableRegexReplaceRule( _rgxModalUrl2, "<a {0} {1} {2} href=\"${http}${url}\" title=\"${http}${url}\">${inner}</a>".Replace("{0}", target).Replace("{1}", nofollow).Replace("{2}", ClassModal), new[] { "url", "http" }, new[] { string.Empty, string.Empty // "http://" })); ruleEngine.AddRule( new VariableRegexReplaceRule( _rgxModalUrl1, "<a {0} {1} {2} href=\"${http}${inner}\" title=\"${http}${inner}\">${http}${innertrunc}</a>".Replace("{0}", target).Replace("{1}", nofollow).Replace("{2}", ClassModal), new[] { "http" }, new[] { string.Empty, string.Empty // "http://" }, 50)); // font ruleEngine.AddRule( new VariableRegexReplaceRule( _RgxFont, "<span style=\"font-family:${font}\">${inner}</span>", _Options, new[] { "font" })); // color ruleEngine.AddRule( new VariableRegexReplaceRule( _RgxColor, "<span style=\"color:${color}\">${inner}</span>", _Options, new[] { "color" })); // lists ruleEngine.AddRule(new SimpleRegexReplaceRule(_RgxList1, "<ul>${inner}</ul>", _Options)); /*ruleEngine.AddRule( new VariableRegexReplaceRule(_rgxList2, "<ol type=\"${type}\">${inner}</ol>", _options, new[] { "type" }));*/ ruleEngine.AddRule(new SimpleRegexReplaceRule(_RgxListNumber, "<ol style=\"list-style-type:number\">${inner}</ol>", RegexOptions.Singleline)); ruleEngine.AddRule(new SimpleRegexReplaceRule(_RgxListLowerRoman, "<ol style=\"list-style-type:lower-roman\">${inner}</ol>", RegexOptions.Singleline)); ruleEngine.AddRule(new SimpleRegexReplaceRule(_RgxListUpperRoman, "<ol style=\"list-style-type:upper-roman\">${inner}</ol>", RegexOptions.Singleline)); ruleEngine.AddRule(new SimpleRegexReplaceRule(_RgxListLowerAlpha, "<ol style=\"list-style-type:lower-alpha\">${inner}</ol>", RegexOptions.Singleline)); ruleEngine.AddRule(new SimpleRegexReplaceRule(_RgxListUpperAlpha, "<ol style=\"list-style-type:upper-alpha\">${inner}</ol>", RegexOptions.Singleline)); // bullets ruleEngine.AddRule(new SingleRegexReplaceRule(_RgxBullet, "<li>", _Options)); // alignment ruleEngine.AddRule( new SimpleRegexReplaceRule(_RgxCenter, "<div align=\"center\">${inner}</div>", _Options)); ruleEngine.AddRule(new SimpleRegexReplaceRule(_RgxLeft, "<div align=\"left\">${inner}</div>", _Options)); ruleEngine.AddRule( new SimpleRegexReplaceRule(_RgxRight, "<div align=\"right\">${inner}</div>", _Options)); // TODO add max-width and max-height /* var maxWidth = this.Get<YafBoardSettings>().ImageAttachmentResizeWidth; var maxHeight = this.Get<YafBoardSettings>().ImageAttachmentResizeHeight; string styleAttribute = "style=\"max-width:{0}px;max-height:{1}px\"".FormatWith(maxWidth, maxHeight);*/ // image ruleEngine.AddRule( new VariableRegexReplaceRule( _rgxImg, "<img src=\"${http}${inner}\" alt=\"\" class=\"UserPostedImage\"/>", new[] { "http" }, new[] { "http://" }) { RuleRank = 70 }); ruleEngine.AddRule( new VariableRegexReplaceRule( _rgxImgEmptyTitle, "<img src=\"${http}${inner}\" alt=\"\" class=\"UserPostedImage\"/>", new[] { "http" }, new[] { "http://" }) { RuleRank = 71 }); ruleEngine.AddRule( new VariableRegexReplaceRule( _rgxImgTitle, "<img src=\"${http}${inner}\" alt=\"${description}\" title=\"${description}\" class=\"UserPostedImage\" />", new[] { "http", "description" }, new[] { "http://", string.Empty }) { RuleRank = 72 }); // tha_watcha : Easy Quote Disabled http://forum.yetanotherforum.net/yaf_postst13495_Addition-of-Easy-Quote-RegEx-in-Revision-4906.aspx // Looks like it doesnt work as expected should be correctly implemented or else removed. // // add easy quoting... /*var easyQuoteRule = new SimpleRegexReplaceRule( _RgxEasyQuote, @" <span class=""easyquote"">${inner}</span>", RegexOptions.IgnoreCase | RegexOptions.Multiline);*/ // basic hr and br rules var hrRule = new SingleRegexReplaceRule( _RgxHr, "<hr />", RegexOptions.IgnoreCase | RegexOptions.Multiline); // Multiline, since ^ must match beginning of line var brRule = new SingleRegexReplaceRule( _RgxBr, "<br />", RegexOptions.IgnoreCase | RegexOptions.Multiline) { RuleRank = hrRule.RuleRank + 1 }; // Ensure the newline rule is processed after the HR rule, otherwise the newline characters in the HR regex will never match //ruleEngine.AddRule(easyQuoteRule); ruleEngine.AddRule(hrRule); ruleEngine.AddRule(brRule); } // add smilies this.AddSmiles(ruleEngine); if (convertBBQuotes) { // add rule for code block type with syntax highlighting ruleEngine.AddRule( new SyntaxHighlightedCodeRegexReplaceRule( _regexCodeWithLanguage, @"<div class=""code""><strong>{0}</strong><div class=""innercode"">${inner}</div></div>".Replace("{0}", localCodeStr)) { RuleRank = 41 }); // add rule for code block type with syntax highlighting ruleEngine.AddRule( new SyntaxHighlightedCodeRegexReplaceRule( _regexCodeWithLanguage2, @"<div class=""code""><strong>{0}</strong><div class=""innercode"">${inner}</div></div>".Replace("{0}", localCodeStr)) { RuleRank = 40 }); // handle custom YafBBCode this.AddCustomBBCodeRules(ruleEngine); // add rule for code block type with no syntax highlighting ruleEngine.AddRule( new CodeRegexReplaceRule( _rgxCode1, @"<div class=""code""><strong>{0}</strong><div class=""innercode"">${inner}</div></div>".Replace("{0}", localCodeStr))); // "quote" handling... string tmpReplaceStr3 = @"<div class=""quote""><span class=""quotetitle"">{0} <a href=""{1}""><img src=""{2}"" title=""{3}"" alt=""{3}"" /></a></span><div class=""innerquote"">{4}</div></div>" .FormatWith( localQuotePostedStr.Replace("{0}", "${quote}"), YafBuildLink.GetLink(ForumPages.posts, "m={0}#post{0}", "${id}"), this.Get<ITheme>().GetItem("ICONS", "ICON_LATEST"), this.Get<ILocalization>().GetText("COMMON", "BBCODE_QUOTEPOSTED_TT"), "${inner}"); ruleEngine.AddRule(new VariableRegexReplaceRule(_rgxQuote3, tmpReplaceStr3, new[] { "quote", "id" }) { RuleRank = 60 }); string tmpReplaceStr2 = @"<div class=""quote""><span class=""quotetitle"">{0}</span><div class=""innerquote"">{1}</div></div>" .FormatWith(localQuoteWroteStr.Replace("{0}", "${quote}"), "${inner}"); ruleEngine.AddRule(new VariableRegexReplaceRule(_rgxQuote2, tmpReplaceStr2, new[] { "quote" }) { RuleRank = 61 }); string tmpReplaceStr1 = @"<div class=""quote""><span class=""quotetitle"">{0}</span><div class=""innerquote"">{1}</div></div>" .FormatWith(localQuoteStr, "${inner}"); ruleEngine.AddRule(new SimpleRegexReplaceRule(_rgxQuote1, tmpReplaceStr1) { RuleRank = 62 }); } // post and topic rules... ruleEngine.AddRule( new PostTopicRegexReplaceRule( _RgxPost, @"<a {0} href=""${post}"" title=""${inner}"">${inner}</a>".Replace("{0}", target), _Options)); ruleEngine.AddRule( new PostTopicRegexReplaceRule( _RgxTopic, @"<a {0} href=""${topic}"" title=""${inner}"">${inner}</a>".Replace("{0}", target), _Options)); }