Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BBCode Validation #1

Open
BenjaminAbt opened this issue Nov 19, 2019 · 5 comments
Open

BBCode Validation #1

BenjaminAbt opened this issue Nov 19, 2019 · 5 comments

Comments

@BenjaminAbt
Copy link

@BenjaminAbt BenjaminAbt commented Nov 19, 2019

Hi, is it possible to validate attributes?

For example: you show a font-sample with font-size 12px.

  • How to I validate the attribute value for int-only values?
  • How to enrich the value, like "12" to "12px" or aliases like "small" to "10px" ?
  • How do I handle invalid input, like chars for that int-val?

Sample:

  • [font size=12px]Lorem ipsum[/font] should be <div style="font-size: 12px">Lorem ipsum</div>
    but
  • [font size=12]Lorem ipsum[/font] should also be <div style="font-size: 12px">Lorem ipsum</div>
  • [font]Lorem ipsum[/font] should be [font]Lorem ipsum[/font]
  • [font=A]Lorem ipsum[/font] should be [font=A]Lorem ipsum[/font]

I know I can pass contentTransformers, but the usage is not clear and the original CodeKicker docs are down :-/

@PoLaKoSz

This comment has been minimized.

Copy link
Owner

@PoLaKoSz PoLaKoSz commented Nov 19, 2019

Hi!

Thank You for checking out this repository! :)

How to validate attribute value

Maybe this is not the most elegant way, but here is a solution:

var bbTags = new List<BBTag>()
{
    new BBTag("font", "<div style=\"font-size: ${fontSize}\">", "</div>",
        new BBAttribute(
            "fontSize",
            "size",
            ((attr) =>
            {
                try
                {
                    int size = Convert.ToInt32(attr.AttributeValue);
                    return $"{attr.AttributeValue}px";
                }
                catch (FormatException ex)
                {
                    throw new FormatException($"Font size is not a whole number, but {attr.AttributeValue}", ex);
                }
            })))
};

var parser = new BBCodeParser(bbTags);

string output = parser.ToHtml("[font size=car]Lorem ipsum[/font]");

Enrich the value

var bbTags = new List<BBTag>()
{
    new BBTag("font", "<div style=\"font-size: ${fontSize}\">", "</div>",
        new BBAttribute("fontSize", "size", fontSize => $"{fontSize.AttributeValue}px"))
};

var parser = new BBCodeParser(bbTags);

string output = parser.ToHtml("[font size=12]Lorem ipsum[/font]");

Last two sample

I am not sure about what to comment on the last two because this library just do BBCode to HTML parsing and cannot do (yet) HTML to BBCode so i don't understand how [font]Lorem ipsum[/font] should be [font]Lorem ipsum[/font]. Can You provide more details on this?

@BenjaminAbt

This comment has been minimized.

Copy link
Author

@BenjaminAbt BenjaminAbt commented Nov 19, 2019

Thank you for the very fast answer. Awesome!

So the contentTransformers is the right place. Thanks.
The enrich syntax is a nice solution!

The last two samples are pretty simple; the idea is the validation result handling.
I'd like to avoid exceptions to avoid hard error handling, would like to use a "soft'ish error handling":

  • return a fixed value (for example, I allow a font size range from 10-16 and the input is 18, it would return 16) ´[size=18]Hello[/size] => <span style="font-size: 16px">Hello</span>. So this is more or less a "rule-behavior thing"
  • return the plain input if invalid, dont try to render => [size=A]Hello[/size] => [size=A]Hello[/size], otherwise I would return <span style="font-size: A">Hello</span> ... an exception breaks the whole rendering, but my wish is to just "ignore the invalid one" to render
@PoLaKoSz

This comment has been minimized.

Copy link
Owner

@PoLaKoSz PoLaKoSz commented Nov 20, 2019

Cannot test this, but should work

Return fixed value

var bbTags = new List<BBTag>()
{
    new BBTag("font", "<div style=\"font-size: ${fontSize}\">", "</div>",
        new BBAttribute(
            "fontSize",
            "size",
            ((attr) =>
            {
                try
                {
                    int size = Convert.ToInt32(attr.AttributeValue);
                    
                    if (size < 10)
                        return "10";
                    else if (16 < size)
                        return "16";
                    else
                        return $"{size}";
                }
                catch (FormatException ex)
                {
                    throw new FormatException($"Font size is not a whole number, but {attr.AttributeValue}", ex);
                }
            })))
};

var parser = new BBCodeParser(bbTags);

string output1 = parser.ToHtml("[font size=8]Lorem ipsum[/font]");
string output2 = parser.ToHtml("[font size=12]Lorem ipsum[/font]");
string output3 = parser.ToHtml("[font size=18]Lorem ipsum[/font]");

Return plain input if invalid

This could be done with a little changes in the Return fixed value block:

return $"{attr.Attribute.ID}: {attr.AttributeValue}";
@BenjaminAbt

This comment has been minimized.

Copy link
Author

@BenjaminAbt BenjaminAbt commented Nov 20, 2019

Thanks for your help.

I dipped into the source code step by step, and my scenario is currently not supported in the original code.

With a FormatException an exception is thrown despite ErrorFree-Mode, which was probably the sense at that time, but doesn't fit for me.

I have now made the following change, which results in the input being returned unchanged for a format exception.

        new BBTag("size", "<span style=\"font-size: ${size}\">" ,"</span>",
                new BBAttribute("size", "", BBCodeResolvers.GetSizeValue)),
        public static string GetSizeValue(IAttributeRenderingContext attributeRenderingContext)
        {
            string size = attributeRenderingContext.GetAttributeValueById("size");

            if (!int.TryParse(size, out int sizeVal)) throw new FormatException();
            return Math.Max(10, Math.Min(16, sizeVal)).ToString();
        }
// BBCodeParser.cs
        public virtual string ToHtml(string bbCode)
        {
            if (bbCode == null) throw new ArgumentNullException(nameof(bbCode));
            SequenceNode node = ParseSyntaxTree(bbCode);
            try
            {
                return node.ToHtml();
            }
            catch (FormatException)
            {
                if (ErrorMode == ErrorMode.ErrorFree)
                {
                    return bbCode;
                }

                throw;
            }
        }
@BenjaminAbt

This comment has been minimized.

Copy link
Author

@BenjaminAbt BenjaminAbt commented Nov 21, 2019

Found a better solution, just override TagNode.cs

        public override string ToHtml()
        {
            try
            {
                string content = GetContent();

                string start = ReplaceAttributeValues(Tag.OpenTagTemplate, content);
                string body = (Tag.AutoRenderContent ? content : null);
                string end = ReplaceAttributeValues(Tag.CloseTagTemplate, content);

                string transformedContent = start + body + end;

                return transformedContent;
            }
            catch (FormatException)
            {
                return ToBBCode();
            }
        }

Results is: only the invalid bbcode is returned raw, not the whole input.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
2 participants
You can’t perform that action at this time.