Пример #1
0
        /// <summary>
        /// 4.4.9. Ident state
        /// </summary>
        CssToken IdentStart(Char current)
        {
            if (current == Symbols.Minus)
            {
                current = GetNext();

                if (current.IsNameStart() || IsValidEscape(current))
                {
                    _stringBuffer.Append(Symbols.Minus);
                    return(IdentRest(current));
                }

                Back();
                return(CssToken.Delim(Symbols.Minus));
            }
            else if (current.IsNameStart())
            {
                _stringBuffer.Append(current);
                return(IdentRest(GetNext()));
            }
            else if (current == Symbols.ReverseSolidus)
            {
                if (IsValidEscape(current))
                {
                    current = GetNext();
                    _stringBuffer.Append(ConsumeEscape(current));
                    return(IdentRest(GetNext()));
                }
            }

            return(Data(current));
        }
Пример #2
0
        /// <summary>
        /// 4.4.7. At-keyword state
        /// </summary>
        CssToken AtKeywordStart()
        {
            var current = GetNext();

            if (current == Symbols.Minus)
            {
                current = GetNext();

                if (current.IsNameStart() || IsValidEscape(current))
                {
                    _stringBuffer.Append(Symbols.Minus);
                    return(AtKeywordRest(current));
                }

                Back(2);
                return(CssToken.Delim(Symbols.At));
            }
            else if (current.IsNameStart())
            {
                _stringBuffer.Append(current);
                return(AtKeywordRest(GetNext()));
            }
            else if (IsValidEscape(current))
            {
                current = GetNext();
                _stringBuffer.Append(ConsumeEscape(current));
                return(AtKeywordRest(GetNext()));
            }
            else
            {
                Back();
                return(CssToken.Delim(Symbols.At));
            }
        }
Пример #3
0
        /// <summary>
        /// 4.4.4. Hash state
        /// </summary>
        CssToken HashStart()
        {
            var current = GetNext();

            if (current.IsNameStart())
            {
                _stringBuffer.Append(current);
                return(HashRest());
            }
            else if (IsValidEscape(current))
            {
                current = GetNext();
                _stringBuffer.Append(ConsumeEscape(current));
                return(HashRest());
            }
            else if (current == Symbols.ReverseSolidus)
            {
                RaiseErrorOccurred(ErrorCode.InvalidCharacter);
                Back();
                return(CssToken.Delim(Symbols.Num));
            }
            else
            {
                Back();
                return(CssToken.Delim(Symbols.Num));
            }
        }
Пример #4
0
        /// <summary>
        /// 4.4.9. Ident state
        /// </summary>
        CssToken IdentStart(Char current)
        {
            if (current == Specification.Minus)
            {
                current = Next;

                if (current.IsNameStart() || IsValidEscape(current))
                {
                    _stringBuffer.Append(Specification.Minus);
                    return(IdentRest(current));
                }

                Back();
                return(CssToken.Delim(Specification.Minus));
            }
            else if (current.IsNameStart())
            {
                _stringBuffer.Append(current);
                return(IdentRest(Next));
            }
            else if (current == Specification.ReverseSolidus)
            {
                if (IsValidEscape(current))
                {
                    current = Next;
                    _stringBuffer.Append(ConsumeEscape(current));
                    return(IdentRest(Next));
                }
            }

            return(Data(current));
        }
Пример #5
0
        /// <summary>
        /// 4.4.7. At-keyword state
        /// </summary>
        CssToken AtKeywordStart()
        {
            var current = Next;

            if (current == Specification.Minus)
            {
                current = Next;

                if (current.IsNameStart() || IsValidEscape(current))
                {
                    _stringBuffer.Append(Specification.Minus);
                    return(AtKeywordRest(current));
                }

                Back(2);
                return(CssToken.Delim(Specification.At));
            }
            else if (current.IsNameStart())
            {
                _stringBuffer.Append(current);
                return(AtKeywordRest(Next));
            }
            else if (IsValidEscape(current))
            {
                current = Next;
                _stringBuffer.Append(ConsumeEscape(current));
                return(AtKeywordRest(Next));
            }
            else
            {
                Back();
                return(CssToken.Delim(Specification.At));
            }
        }
Пример #6
0
 /// <summary>
 /// 4.4.4. Hash state
 /// </summary>
 CssToken HashStart(Char current)
 {
     if (current.IsNameStart())
     {
         _stringBuffer.Append(current);
         return(HashRest(_src.Next));
     }
     else if (IsValidEscape(current))
     {
         current = _src.Next;
         _stringBuffer.Append(ConsumeEscape(current));
         return(HashRest(_src.Next));
     }
     else if (current == Specification.ReverseSolidus)
     {
         RaiseErrorOccurred(ErrorCode.InvalidCharacter);
         _src.Back();
         return(CssToken.Delim(Specification.Num));
     }
     else
     {
         _src.Back();
         return(CssToken.Delim(Specification.Num));
     }
 }
Пример #7
0
        /// <summary>
        /// 4.4.1. Data state
        /// </summary>
        CssToken Data(Char current)
        {
            switch (current)
            {
            case Symbols.LineFeed:
            case Symbols.CarriageReturn:
            case Symbols.Tab:
            case Symbols.Space:
                do
                {
                    current = GetNext();
                }while (current.IsSpaceCharacter());

                if (_ignoreWs)
                {
                    return(Data(current));
                }

                Back();
                return(CssSpecialCharacter.Whitespace);

            case Symbols.DoubleQuote:
                return(StringDQ());

            case Symbols.Num:
                return(HashStart());

            case Symbols.Dollar:
                current = GetNext();

                if (current == Symbols.Equality)
                {
                    return(CssMatchToken.Suffix);
                }

                return(CssToken.Delim(GetPrevious()));

            case Symbols.SingleQuote:
                return(StringSQ());

            case Symbols.RoundBracketOpen:
                return(CssBracketToken.OpenRound);

            case Symbols.RoundBracketClose:
                return(CssBracketToken.CloseRound);

            case Symbols.Asterisk:
                current = GetNext();

                if (current == Symbols.Equality)
                {
                    return(CssMatchToken.Substring);
                }

                return(CssToken.Delim(GetPrevious()));

            case Symbols.Plus:
            {
                var c1 = GetNext();

                if (c1 != Symbols.EndOfFile)
                {
                    var c2 = GetNext();
                    Back(2);

                    if (c1.IsDigit() || (c1 == Symbols.Dot && c2.IsDigit()))
                    {
                        return(NumberStart(current));
                    }
                }
                else
                {
                    Back();
                }

                return(CssToken.Delim(current));
            }

            case Symbols.Comma:
                return(CssSpecialCharacter.Comma);

            case Symbols.Dot:
            {
                var c = GetNext();

                if (c.IsDigit())
                {
                    return(NumberStart(GetPrevious()));
                }

                return(CssToken.Delim(GetPrevious()));
            }

            case Symbols.Minus:
            {
                var c1 = GetNext();

                if (c1 != Symbols.EndOfFile)
                {
                    var c2 = GetNext();
                    Back(2);

                    if (c1.IsDigit() || (c1 == Symbols.Dot && c2.IsDigit()))
                    {
                        return(NumberStart(current));
                    }
                    else if (c1.IsNameStart())
                    {
                        return(IdentStart(current));
                    }
                    else if (c1 == Symbols.ReverseSolidus && !c2.IsLineBreak() && c2 != Symbols.EndOfFile)
                    {
                        return(IdentStart(current));
                    }
                    else if (c1 == Symbols.Minus && c2 == Symbols.GreaterThan)
                    {
                        Advance(2);

                        if (_ignoreCs)
                        {
                            return(Data(GetNext()));
                        }

                        return(CssCommentToken.Close);
                    }
                }
                else
                {
                    Back();
                }

                return(CssToken.Delim(current));
            }

            case Symbols.Solidus:
                current = GetNext();

                if (current == Symbols.Asterisk)
                {
                    return(Comment());
                }

                return(CssToken.Delim(GetPrevious()));

            case Symbols.ReverseSolidus:
                current = GetNext();

                if (current.IsLineBreak() || current == Symbols.EndOfFile)
                {
                    RaiseErrorOccurred(current == Symbols.EndOfFile ? ErrorCode.EOF : ErrorCode.LineBreakUnexpected);
                    return(CssToken.Delim(GetPrevious()));
                }

                return(IdentStart(GetPrevious()));

            case Symbols.Colon:
                return(CssSpecialCharacter.Colon);

            case Symbols.Semicolon:
                return(CssSpecialCharacter.Semicolon);

            case Symbols.LessThan:
                current = GetNext();

                if (current == Symbols.ExclamationMark)
                {
                    current = GetNext();

                    if (current == Symbols.Minus)
                    {
                        current = GetNext();

                        if (current == Symbols.Minus)
                        {
                            if (_ignoreCs)
                            {
                                return(Data(GetNext()));
                            }

                            return(CssCommentToken.Open);
                        }

                        current = GetPrevious();
                    }

                    current = GetPrevious();
                }

                return(CssToken.Delim(GetPrevious()));

            case Symbols.At:
                return(AtKeywordStart());

            case Symbols.SquareBracketOpen:
                return(CssBracketToken.OpenSquare);

            case Symbols.SquareBracketClose:
                return(CssBracketToken.CloseSquare);

            case Symbols.Accent:
                current = GetNext();

                if (current == Symbols.Equality)
                {
                    return(CssMatchToken.Prefix);
                }

                return(CssToken.Delim(GetPrevious()));

            case Symbols.CurlyBracketOpen:
                return(CssBracketToken.OpenCurly);

            case Symbols.CurlyBracketClose:
                return(CssBracketToken.CloseCurly);

            case '0':
            case '1':
            case '2':
            case '3':
            case '4':
            case '5':
            case '6':
            case '7':
            case '8':
            case '9':
                return(NumberStart(current));

            case 'U':
            case 'u':
                current = GetNext();

                if (current == Symbols.Plus)
                {
                    current = GetNext();

                    if (current.IsHex() || current == Symbols.QuestionMark)
                    {
                        return(UnicodeRange(current));
                    }

                    current = GetPrevious();
                }

                return(IdentStart(GetPrevious()));

            case Symbols.Pipe:
                current = GetNext();

                if (current == Symbols.Equality)
                {
                    return(CssMatchToken.Dash);
                }
                else if (current == Symbols.Pipe)
                {
                    return(CssColumnToken.Instance);
                }

                return(CssToken.Delim(GetPrevious()));

            case Symbols.Tilde:
                current = GetNext();

                if (current == Symbols.Equality)
                {
                    return(CssMatchToken.Include);
                }

                return(CssToken.Delim(GetPrevious()));

            case Symbols.EndOfFile:
                return(null);

            case Symbols.ExclamationMark:
                current = GetNext();

                if (current == Symbols.Equality)
                {
                    return(CssMatchToken.Not);
                }

                return(CssToken.Delim(GetPrevious()));

            default:
                if (current.IsNameStart())
                {
                    return(IdentStart(current));
                }

                return(CssToken.Delim(current));
            }
        }