Beispiel #1
0
        /// <summary>
        /// Creates the rules that convert <see cref="BBCode"/> to HTML
        /// </summary>
        /// <param name="messageId">
        /// The message Id.
        /// </param>
        /// <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="isEditMode">
        /// Indicates if the formatting is for the Editor.
        /// </param>
        public void CreateBBCodeRules(
            [NotNull] int messageId,
            IProcessReplaceRules ruleEngine,
            bool doFormatting,
            bool targetBlankOverride,
            bool useNoFollow,
            bool isEditMode = false)
        {
            var target = this.Get <BoardSettings>().BlankLinks || targetBlankOverride
                             ? "target=\"_blank\""
                             : string.Empty;

            var noFollow = useNoFollow ? "rel=\"nofollow\"" : string.Empty;

            // pull localized strings
            var localQuoteStr = this.Get <ILocalization>().GetText("COMMON", "BBCODE_QUOTE");

            // handle font sizes -- this rule class internally handles the "size" variable
            ruleEngine.AddRule(
                new FontSizeRegexReplaceRule(
                    @"\[size=(?<size>(.*?))\](?<inner>(.*?))\[/size\]",
                    @"<span style=""font-size:${size}"">${inner}</span>",
                    Options));

            if (doFormatting)
            {
                ruleEngine.AddRule(
                    new CodeRegexReplaceRule(
                        new Regex(@"\[noparse\](?<inner>(.*?))\[/noparse\]", Options | RegexOptions.Compiled),
                        @"${inner}"));

                ruleEngine.AddRule(
                    new SimpleRegexReplaceRule(
                        new Regex(@"\[B\](?<inner>(.*?))\[/B\]", Options | RegexOptions.Compiled),
                        "<strong>${inner}</strong>"));

                ruleEngine.AddRule(
                    new SimpleRegexReplaceRule(@"\[S\](?<inner>(.*?))\[/S\]", "<s>${inner}</s>", Options));

                ruleEngine.AddRule(
                    new SimpleRegexReplaceRule(@"\[I\](?<inner>(.*?))\[/I\]", "<em>${inner}</em>", Options));

                ruleEngine.AddRule(
                    new SimpleRegexReplaceRule(@"\[U\](?<inner>(.*?))\[/U\]", "<u>${inner}</u>", Options));
                ruleEngine.AddRule(
                    new SimpleRegexReplaceRule(@"\[h\](?<inner>(.*?))\[/h\]", "<mark>${inner}</mark>", Options));

                // e-mails
                ruleEngine.AddRule(
                    new VariableRegexReplaceRule(
                        new Regex(
                            @"\[email=(?<email>[^\]]*)\](?<inner>([^""\r\n\]\[]+?))\[/email\]",
                            Options | RegexOptions.Compiled),
                        "<a href=\"mailto:${email}\">${inner}&nbsp;<i class=\"fa fa-external-link-alt fa-fw\"></i></a>",
                        new[] { "email" }));

                ruleEngine.AddRule(
                    new SimpleRegexReplaceRule(
                        new Regex(
                            @"\[email[^\]]*\](?<inner>([^""\r\n\]\[]+?))\[/email\]",
                            Options | RegexOptions.Compiled),
                        @"<a href=""mailto:${inner}"">${inner}</a>"));

                // urls
                ruleEngine.AddRule(
                    new VariableRegexReplaceRule(
                        new Regex(
                            @"\[url\=(?<http>(skype:)|(http://)|(https://)|(ftp://)|(ftps://))?(?<url>([^javascript:])([^""\r\n\]\[]*?))\](?<inner>(.+?))\[/url\]",
                            Options | RegexOptions.Compiled),
                        "<a {0} {1} href=\"${http}${url}\" title=\"${http}${url}\">${inner}&nbsp;<i class=\"fa fa-external-link-alt fa-fw\"></i></a>"
                        .Replace("{0}", target).Replace("{1}", noFollow),
                        new[]
                {
                    "url", "http"
                },
                        new[]
                {
                    string.Empty, string.Empty             // "http://"
                })
                {
                    RuleRank = 10
                });

                ruleEngine.AddRule(
                    new VariableRegexReplaceRule(
                        new Regex(
                            @"\[url\](?<http>(skype:)|(http://)|(https://)|(ftp://)|(ftps://)|(mailto:))?(?<inner>([^javascript:])(.+?))\[/url\]",
                            Options | RegexOptions.Compiled),
                        "<a {0} {1} href=\"${http}${inner}\" title=\"${http}${inner}\">${http}${innertrunc}&nbsp;<i class=\"fa fa-external-link-alt fa-fw\"></i></a>"
                        .Replace("{0}", target).Replace("{1}", noFollow),
                        new[]
                {
                    "http"
                },
                        new[]
                {
                    string.Empty, string.Empty             // "http://"
                },
                        50)
                {
                    RuleRank = 11
                });

                // urls
                ruleEngine.AddRule(
                    new VariableRegexReplaceRule(
                        new Regex(
                            @"(?<before>^|[ ]|\[[A-Za-z0-9]\]|\[\*\]|[A-Za-z0-9])(?<!"")(?<!href="")(?<!src="")(?<inner>(http|ftp|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&amp;:/~\+#]*[\w\-\@?^=%&amp;/~\+#])?)",
                            RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.Compiled),
                        "${before}<a {0} {1} href=\"${inner}\" title=\"${inner}\">${innertrunc}&nbsp;<i class=\"fa fa-external-link-alt fa-fw\"></i></a>"
                        .Replace("{0}", target).Replace("{1}", noFollow),
                        new[]
                {
                    "before"
                },
                        new[] { string.Empty },
                        50)
                {
                    RuleRank = 12
                });

                ruleEngine.AddRule(
                    new VariableRegexReplaceRule(
                        new Regex(
                            @"(?<before>^|[ ]|\[[A-Za-z0-9]\]|\[\*\]|[A-Za-z0-9])(?<!href="")(?<!src="")(?<inner>(http://|https://|ftp://)(?:[\w-]+\.)+[\w-]+(?:/[\w-./?%&=+;,:#~/(/)$]*[^.<|^.\[])?)",
                            RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.Compiled),
                        "${before}<a {0} {1} href=\"${inner}\" title=\"${inner}\">${innertrunc}&nbsp;<i class=\"fa fa-external-link-alt fa-fw\"></i></a>"
                        .Replace("{0}", target).Replace("{1}", noFollow),
                        new[]
                {
                    "before"
                },
                        new[] { string.Empty },
                        50)
                {
                    RuleRank = 13
                });

                // font
                ruleEngine.AddRule(
                    new VariableRegexReplaceRule(
                        @"\[font=(?<font>([-a-z0-9, ]*))\](?<inner>(.*?))\[/font\]",
                        "<span style=\"font-family:${font}\">${inner}</span>",
                        Options,
                        new[] { "font" }));

                // color
                ruleEngine.AddRule(
                    new VariableRegexReplaceRule(
                        @"\[color=(?<color>(\#?[-a-z0-9]*))\](?<inner>(.*?))\[/color\]",
                        "<span style=\"color:${color}\">${inner}</span>",
                        Options,
                        new[] { "color" }));

                // lists
                ruleEngine.AddRule(
                    new SimpleRegexReplaceRule(@"\[list\](?<inner>(.*?))\[/list\]", "<ul>${inner}</ul>", Options));
                ruleEngine.AddRule(
                    new SimpleRegexReplaceRule(
                        @"\[list=1\](?<inner>(.*?))\[/list\]",
                        "<ol style=\"list-style-type:number\">${inner}</ol>",
                        RegexOptions.Singleline));
                ruleEngine.AddRule(
                    new SimpleRegexReplaceRule(
                        @"\[list=i\](?<inner>(.*?))\[/list\]",
                        "<ol style=\"list-style-type:lower-roman\">${inner}</ol>",
                        RegexOptions.Singleline));
                ruleEngine.AddRule(
                    new SimpleRegexReplaceRule(
                        @"\[list=I\](?<inner>(.*?))\[/list\]",
                        "<ol style=\"list-style-type:upper-roman\">${inner}</ol>",
                        RegexOptions.Singleline));
                ruleEngine.AddRule(
                    new SimpleRegexReplaceRule(
                        @"\[list=a\](?<inner>(.*?))\[/list\]",
                        "<ol style=\"list-style-type:lower-alpha\">${inner}</ol>",
                        RegexOptions.Singleline));
                ruleEngine.AddRule(
                    new SimpleRegexReplaceRule(
                        @"\[list=A\](?<inner>(.*?))\[/list\]",
                        "<ol style=\"list-style-type:upper-alpha\">${inner}</ol>",
                        RegexOptions.Singleline));

                // bullets
                ruleEngine.AddRule(new SingleRegexReplaceRule(@"\[\*\]", "<li>", Options));

                // alignment
                ruleEngine.AddRule(
                    new SimpleRegexReplaceRule(
                        @"\[center\](?<inner>(.*?))\[/center\]",
                        "<div align=\"center\">${inner}</div>",
                        Options));
                ruleEngine.AddRule(
                    new SimpleRegexReplaceRule(
                        @"\[left\](?<inner>(.*?))\[/left\]",
                        "<div align=\"left\">${inner}</div>",
                        Options));
                ruleEngine.AddRule(
                    new SimpleRegexReplaceRule(
                        @"\[right\](?<inner>(.*?))\[/right\]",
                        "<div align=\"right\">${inner}</div>",
                        Options));

                // indent
                ruleEngine.AddRule(
                    new SimpleRegexReplaceRule(
                        @"\[indent\](?<inner>(.*?))\[/indent\]",
                        "<div style=\"margin-left:40px\">${inner}</div>",
                        Options));

                string imageHtml;
                string imageHtmlWithDesc;

                if (messageId > 0)
                {
                    imageHtml = "<a href=\"${http}${inner}\" data-gallery=\"#blueimp-gallery-" +
                                messageId +
                                "\"><img src=\"${http}${inner}\" alt=\"UserPostedImage\" class=\"img-user-posted img-thumbnail\" style=\"max-height:${height}px;\"></a>";
                    imageHtmlWithDesc = "<a href=\"${http}${inner}\" alt=\"${description}\" title=\"${description}\" data-gallery=\"#blueimp-gallery-" +
                                        messageId +
                                        "\"><img src=\"${http}${inner}\" alt=\"UserPostedImage\" class=\"img-user-posted img-thumbnail\" style=\"max-height:${height}px;\"></a>";
                }
                else
                {
                    imageHtml         = "<img src=\"${http}${inner}\" alt=\"UserPostedImage\" class=\"img-user-posted img-thumbnail\" style=\"max-height:${height}px;\">";
                    imageHtmlWithDesc =
                        "<img src=\"${http}${inner}\" alt=\"${description}\" title=\"${description}\" class=\"img-user-posted img-thumbnail\" style=\"max-height:${height}px;\">";
                }

                // image
                ruleEngine.AddRule(
                    new VariableRegexReplaceRule(
                        new Regex(
                            @"\[img\](?<http>(http://)|(https://)|(ftp://)|(ftps://))?(?<inner>((?!.+logout)[^""\r\n\]\[]+?\.((googleusercontent[^\[]*)|(jpg[^\[]*)|(jpeg[^\[]*)|(bmp[^\[]*)|(png[^\[]*)|(gif[^\[]*)|(tif[^\[]*)|(ashx[^\[]*)|(php[^\[]*)|(aspx[^\[]*))))\[/img\]",
                            Options | RegexOptions.Compiled),
                        imageHtml,
                        new[]
                {
                    "http", "height"
                },
                        new[] { "http://", this.Get <BoardSettings>().ImageThumbnailMaxHeight.ToString() })
                {
                    RuleRank = 70
                });

                ruleEngine.AddRule(
                    new VariableRegexReplaceRule(
                        new Regex(
                            @"\[img=(?<http>(http://)|(https://)|(ftp://)|(ftps://))?(?<inner>((?!.+logout)[^""\r\n\]\[]+?\.((googleusercontent[^\[]*)|(jpg[^\]\[/img\]]*)|(jpeg[^\[\[/img\]]*)|(bmp[^\[\[/img\]]*)|(png[^\]\[/img\]]*)|(gif[^\]\[/img\]]*)|(tif[^\]\[/img\]]*)|(ashx[^\]\[/img\]]*)|(php[^\]\[/img\]]*)|(aspx[^\]\[/img\]]*))))\]\[/img\]",
                            Options | RegexOptions.Compiled),
                        imageHtml,
                        new[]
                {
                    "http", "height"
                },
                        new[] { "http://", this.Get <BoardSettings>().ImageThumbnailMaxHeight.ToString() })
                {
                    RuleRank = 71
                });

                ruleEngine.AddRule(
                    new VariableRegexReplaceRule(
                        new Regex(
                            @"\[img=(?<http>(http://)|(https://)|(ftp://)|(ftps://))?(?<inner>((?!.+logout)[^""\r\n\]\[]+?\.((googleusercontent[^\[]*)|(jpg[^\]]*)|(jpeg[^\]]*)|(bmp[^\]]*)|(png[^\]]*)|(gif[^\]]*)|(tif[^\]]*)|(ashx[^\]]*)|(php[^\]]*)|(aspx[^\]]*))))\](?<description>[^\[]*)\[/img\]",
                            Options | RegexOptions.Compiled),
                        imageHtmlWithDesc,
                        new[]
                {
                    "http", "description", "height"
                },
                        new[] { "http://", string.Empty, this.Get <BoardSettings>().ImageThumbnailMaxHeight.ToString() })
                {
                    RuleRank = 72
                });

                // basic hr and br rules
                var horizontalLineRule = new SingleRegexReplaceRule(
                    "^[-][-][-][-][-]*[\r]?[\n]",
                    "<hr />",
                    RegexOptions.IgnoreCase | RegexOptions.Multiline);

                ruleEngine.AddRule(new SingleRegexReplaceRule(@"\[br\]", "</p>", Options));

                // Multiline, since ^ must match beginning of line
                var breakRule = new SingleRegexReplaceRule(
                    "\r\n",
                    "<br />",
                    RegexOptions.IgnoreCase | RegexOptions.Multiline)
                {
                    RuleRank = horizontalLineRule.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(horizontalLineRule);

                ruleEngine.AddRule(isEditMode ? breakRule : new SingleRegexReplaceRule(@"\r\n", "<p>", Options));
            }

            // add rule for code block type with syntax highlighting
            ruleEngine.AddRule(
                new SyntaxHighlighterRegexReplaceRule(
                    isEditMode,
                    new Regex(@"\[code=(?<language>[^\]]*)\](?<inner>(.*?))\[/code\]\r\n|\[code=(?<language>[^\]]*)\](?<inner>(.*?))\[/code\]", Options),
                    @"<div class=""code"">${inner}</div>")
            {
                RuleRank = 2
            });

            // handle custom BBCode
            this.AddCustomBBCodeRules(ruleEngine);

            // add rule for code block type with no syntax highlighting
            ruleEngine.AddRule(
                new SyntaxHighlighterRegexReplaceRule(
                    isEditMode,
                    new Regex(@"\[code\](?<inner>(.*?))\[/code\]\r\n|\[code\](?<inner>(.*?))\[/code\]", Options),
                    @"<div class=""code"">${inner}</div>"));

            ruleEngine.AddRule(
                new QuoteRegexReplaceRule(
                    @"\[quote=(?<quote>(.*?))]",
                    @"<blockquote class=""blockquote blockquote-custom pt-3 px-1 pb-1 mb-4 border border-secondary rounded"">
                                         <div class=""blockquote-custom-icon bg-secondary"">
                                             <i class=""fa fa-quote-left fa-sm link-light""></i>
                                         </div>${quote}",
                    Options));

            // simple open quote tag
            var simpleOpenQuoteReplace =
                $@"<blockquote class=""blockquote blockquote-custom pt-3 px-1 pb-1 mb-4 border border-secondary rounded"">
                          <div class=""blockquote-custom-icon bg-secondary"">
                              <i class=""fa fa-quote-left fa-sm link-light""></i>
                          </div>
                          <footer class=""blockquote-footer""><cite>{localQuoteStr}</cite></footer>
                          <p class=""mb-0"">";

            ruleEngine.AddRule(
                new SimpleRegexReplaceRule(@"\[quote\]", simpleOpenQuoteReplace, Options)
            {
                RuleRank = 62
            });

            // and finally the closing quote tag
            ruleEngine.AddRule(
                new SingleRegexReplaceRule(@"\[/quote\]", "</p></blockquote>", Options)
            {
                RuleRank = 63
            });
        }
Beispiel #2
0
        /// <summary>
        /// Creates the rules that convert <see cref="YafBBCode" /> to HTML
        /// </summary>
        /// <param name="ruleEngine">The rule Engine.</param>
        /// <param name="isHtml">if set to <c>true</c> [is HTML].</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 isHtml,
            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 = "";

            // 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(
                    @"\[size=(?<size>(.*?))\](?<inner>(.*?))\[/size\]",
                    @"<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://"
                })
                {
                    RuleRank = 10
                });

                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)
                {
                    RuleRank = 11
                });

                // urls
                ruleEngine.AddRule(
                    new VariableRegexReplaceRule(
                        _rgxModalUrl2,
                        "<a {0} {1} {2} href=\"#\" data-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=\"#\" data-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);

                ruleEngine.AddRule(
                    new SingleRegexReplaceRule(@"\[br\]", "</p>", _Options));

                // 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);

                if (!isHtml)
                {
                    ruleEngine.AddRule(brRule);
                }
                else
                {
                    // handle paragraphs
                    ruleEngine.AddRule(
                        new SingleRegexReplaceRule(@"\r\n", "<p>", _Options));
                }
            }

            // 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 = 30
                });

                // handle custom YafBBCode
                this.AddCustomBBCodeRules(ruleEngine);

                // add rule for code block type with no syntax highlighting
                ruleEngine.AddRule(
                    new SyntaxHighlightedCodeRegexReplaceRule(
                        _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));
        }
Beispiel #3
0
        /// <summary>
        /// Creates the rules that convert <see cref="YafBBCode" /> to HTML
        /// </summary>
        /// <param name="ruleEngine">The rule Engine.</param>
        /// <param name="isHtml">if set to <c>true</c> [is HTML].</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 isHtml,
            bool doFormatting,
            bool targetBlankOverride,
            bool useNoFollow,
            bool convertBBQuotes)
        {
            var target = this.Get <YafBoardSettings>().BlankLinks || targetBlankOverride
                             ? "target=\"_blank\""
                             : string.Empty;

            var nofollow = useNoFollow ? "rel=\"nofollow\"" : string.Empty;

            var classModal = string.Empty;

            // pull localized strings
            var localQuoteStr = this.Get <ILocalization>().GetText("COMMON", "BBCODE_QUOTE");

            // handle font sizes -- this rule class internally handles the "size" variable
            ruleEngine.AddRule(
                new FontSizeRegexReplaceRule(
                    @"\[size=(?<size>(.*?))\](?<inner>(.*?))\[/size\]",
                    @"<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, @"<mark>${inner}</mark>", Options));

                // e-mails
                ruleEngine.AddRule(
                    new VariableRegexReplaceRule(
                        _rgxEmail2,
                        "<a href=\"mailto:${email}\">${inner}&nbsp;<i class=\"fa fa-external-link-alt fa-fw\"></i></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}&nbsp;<i class=\"fa fa-external-link-alt fa-fw\"></i></a>"
                        .Replace("{0}", target).Replace("{1}", nofollow),
                        new[] { "url", "http" },
                        new[]
                {
                    string.Empty, string.Empty             // "http://"
                })
                {
                    RuleRank = 10
                });

                ruleEngine.AddRule(
                    new VariableRegexReplaceRule(
                        _rgxUrl1,
                        "<a {0} {1} href=\"${http}${inner}\" title=\"${http}${inner}\">${http}${innertrunc}&nbsp;<i class=\"fa fa-external-link-alt fa-fw\"></i></a>"
                        .Replace("{0}", target).Replace("{1}", nofollow),
                        new[] { "http" },
                        new[]
                {
                    string.Empty, string.Empty             // "http://"
                },
                        50)
                {
                    RuleRank = 11
                });

                // urls
                ruleEngine.AddRule(
                    new VariableRegexReplaceRule(
                        _RgxUrl3,
                        "${before}<a {0} {1} href=\"${inner}\" title=\"${inner}\">${innertrunc}&nbsp;<i class=\"fa fa-external-link-alt fa-fw\"></i></a>"
                        .Replace("{0}", target).Replace("{1}", nofollow),
                        new[] { "before" },
                        new[] { string.Empty },
                        50)
                {
                    RuleRank = 12
                });

                ruleEngine.AddRule(
                    new VariableRegexReplaceRule(
                        _RgxUrl4,
                        "${before}<a {0} {1} href=\"${inner}\" title=\"${inner}\">${innertrunc}&nbsp;<i class=\"fa fa-external-link-alt fa-fw\"></i></a>"
                        .Replace("{0}", target).Replace("{1}", nofollow),
                        new[] { "before" },
                        new[] { string.Empty },
                        50)
                {
                    RuleRank = 13
                });

                ruleEngine.AddRule(
                    new VariableRegexReplaceRule(
                        _rgxModalUrl2,
                        "<a {0} {1} {2} href=\"#\" data-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=\"#\" data-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));

                // image
                ruleEngine.AddRule(
                    new VariableRegexReplaceRule(
                        _rgxImg,
                        "<img src=\"${http}${inner}\" alt=\"UserPostedImage\" class=\"img-user-posted img-thumbnail\" style=\"max-width:auto;max-height:${height}px;\" />",
                        new[]
                {
                    "http", "height"
                },
                        new[]
                {
                    "http://", this.Get <YafBoardSettings>().ImageThumbnailMaxHeight.ToString()
                })
                {
                    RuleRank = 70
                });

                ruleEngine.AddRule(
                    new VariableRegexReplaceRule(
                        _rgxImgEmptyTitle,
                        "<img src=\"${http}${inner}\" alt=\"UserPostedImage\" class=\"img-user-posted img-thumbnail\" style=\"max-width:auto;max-height:${height}px;\" />",
                        new[]
                {
                    "http", "height"
                },
                        new[]
                {
                    "http://", this.Get <YafBoardSettings>().ImageThumbnailMaxHeight.ToString()
                })
                {
                    RuleRank = 71
                });

                ruleEngine.AddRule(
                    new VariableRegexReplaceRule(
                        _rgxImgTitle,
                        "<img src=\"${http}${inner}\" alt=\"${description}\" title=\"${description}\" class=\"img-user-posted img-thumbnail\" style=\"max-width:auto;max-height:${height}px;\" />",
                        new[]
                {
                    "http", "description", "height"
                },
                        new[]
                {
                    "http://", string.Empty, this.Get <YafBoardSettings>().ImageThumbnailMaxHeight.ToString()
                })
                {
                    RuleRank = 72
                });

                // basic hr and br rules
                var hrRule = new SingleRegexReplaceRule(
                    _RgxHr,
                    "<hr />",
                    RegexOptions.IgnoreCase | RegexOptions.Multiline);

                ruleEngine.AddRule(new SingleRegexReplaceRule(@"\[br\]", "</p>", Options));

                // 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(!isHtml ? brRule : new SingleRegexReplaceRule(@"\r\n", "<p>", Options));
            }

            if (convertBBQuotes)
            {
                // add rule for code block type with syntax highlighting
                ruleEngine.AddRule(
                    new SyntaxHighlightedCodeRegexReplaceRule(
                        _regexCodeWithLanguage,
                        @"<div class=""code"">${inner}</div>")
                {
                    RuleRank = 2
                });

                // handle custom YafBBCode
                this.AddCustomBBCodeRules(ruleEngine);

                // add rule for code block type with no syntax highlighting
                ruleEngine.AddRule(
                    new SyntaxHighlightedCodeRegexReplaceRule(_rgxCode1, @"<div class=""code"">${inner}</div>"));

                ruleEngine.AddRule(
                    new QuoteRegexReplaceRule(
                        OpenQuoteUserIdRegex,
                        @"<div class=""card bg-light mb-3"">${quote}",
                        Options));

                // simple open quote tag
                var simpleOpenQuoteReplace =
                    $@"<div class=""card bg-light mb-3""><div class=""card-header text-muted"">{localQuoteStr}</div><div class=""card-body""><p class=""card-text"">";

                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));
        }