Пример #1
0
        private static bool TryParseHtmlTagHtmlComment(ref StringSlice text, ref ValueStringBuilder builder)
        {
            var c = text.NextChar();

            if (c != '-')
            {
                return(false);
            }
            builder.Append('-');
            builder.Append('-');
            if (text.PeekChar() == '>')
            {
                return(false);
            }

            var countHyphen = 0;

            while (true)
            {
                c = text.NextChar();
                if (c == '\0')
                {
                    return(false);
                }

                if (countHyphen == 2)
                {
                    if (c == '>')
                    {
                        builder.Append('>');
                        text.SkipChar();
                        return(true);
                    }
                    return(false);
                }
                countHyphen = c == '-' ? countHyphen + 1 : 0;
                builder.Append(c);
            }
        }
Пример #2
0
        private static bool TryParseHtmlTag(ref StringSlice text, ref ValueStringBuilder builder)
        {
            var c = text.CurrentChar;

            if (c != '<')
            {
                return(false);
            }
            c = text.NextChar();

            builder.Append('<');

            switch (c)
            {
            case '/':
                return(TryParseHtmlCloseTag(ref text, ref builder));

            case '?':
                return(TryParseHtmlTagProcessingInstruction(ref text, ref builder));

            case '!':
                builder.Append(c);
                c = text.NextChar();
                if (c == '-')
                {
                    return(TryParseHtmlTagHtmlComment(ref text, ref builder));
                }

                if (c == '[')
                {
                    return(TryParseHtmlTagCData(ref text, ref builder));
                }

                return(TryParseHtmlTagDeclaration(ref text, ref builder));
            }

            return(TryParseHtmlTagOpenTag(ref text, ref builder));
        }
Пример #3
0
        private static bool TryParseHtmlTagProcessingInstruction(ref StringSlice text, ref ValueStringBuilder builder)
        {
            builder.Append('?');
            var prevChar = '\0';

            while (true)
            {
                var c = text.NextChar();
                if (c == '\0')
                {
                    return(false);
                }

                if (c == '>' && prevChar == '?')
                {
                    builder.Append('>');
                    text.SkipChar();
                    return(true);
                }
                prevChar = c;
                builder.Append(c);
            }
        }
Пример #4
0
        internal static bool TryParseHtmlTagOpenTag(ref StringSlice text, ref ValueStringBuilder builder)
        {
            var c = text.CurrentChar;

            // Parse the tagname
            if (!c.IsAlpha())
            {
                return(false);
            }
            builder.Append(c);

            while (true)
            {
                c = text.NextChar();
                if (c.IsAlphaNumeric() || c == '-')
                {
                    builder.Append(c);
                }
                else
                {
                    break;
                }
            }

            bool hasAttribute = false;

            while (true)
            {
                var hasWhitespaces = false;
                // Skip any whitespaces
                while (c.IsWhitespace())
                {
                    builder.Append(c);
                    c = text.NextChar();
                    hasWhitespaces = true;
                }

                switch (c)
                {
                case '\0':
                    return(false);

                case '>':
                    text.SkipChar();
                    builder.Append(c);
                    return(true);

                case '/':
                    builder.Append('/');
                    c = text.NextChar();
                    if (c != '>')
                    {
                        return(false);
                    }
                    text.SkipChar();
                    builder.Append('>');
                    return(true);

                case '=':

                    if (!hasAttribute)
                    {
                        return(false);
                    }

                    builder.Append('=');

                    // Skip any spaces after
                    c = text.NextChar();
                    while (c.IsWhitespace())
                    {
                        builder.Append(c);
                        c = text.NextChar();
                    }

                    // Parse a quoted string
                    if (c == '\'' || c == '\"')
                    {
                        builder.Append(c);
                        char openingStringChar = c;
                        while (true)
                        {
                            c = text.NextChar();
                            if (c == '\0')
                            {
                                return(false);
                            }
                            if (c != openingStringChar)
                            {
                                builder.Append(c);
                            }
                            else
                            {
                                break;
                            }
                        }
                        builder.Append(c);
                        c = text.NextChar();
                    }
                    else
                    {
                        // Parse until we match a space or a special html character
                        int matchCount = 0;
                        while (true)
                        {
                            if (c == '\0')
                            {
                                return(false);
                            }
                            if (c == ' ' || c == '\n' || c == '"' || c == '\'' || c == '=' || c == '<' || c == '>' || c == '`')
                            {
                                break;
                            }
                            matchCount++;
                            builder.Append(c);
                            c = text.NextChar();
                        }

                        // We need at least one char after '='
                        if (matchCount == 0)
                        {
                            return(false);
                        }
                    }

                    hasAttribute = false;
                    continue;

                default:
                    if (!hasWhitespaces)
                    {
                        return(false);
                    }

                    // Parse the attribute name
                    if (!(c.IsAlpha() || c == '_' || c == ':'))
                    {
                        return(false);
                    }
                    builder.Append(c);

                    while (true)
                    {
                        c = text.NextChar();
                        if (c.IsAlphaNumeric() || c == '_' || c == ':' || c == '.' || c == '-')
                        {
                            builder.Append(c);
                        }
                        else
                        {
                            break;
                        }
                    }

                    hasAttribute = true;
                    break;
                }
            }
        }