Exemplo n.º 1
0
        /// <summary>
        /// 4.4.7. At-keyword state
        /// </summary>
        CssToken AtKeywordStart(Char current)
        {
            if (current == Specification.MINUS)
            {
                current = src.Next;

                if (current.IsNameStart() || IsValidEscape(current))
                {
                    stringBuffer.Append(Specification.MINUS);
                    return(AtKeywordRest(current));
                }

                src.Back(2);
                return(CssToken.Delim(Specification.AT));
            }
            else if (current.IsNameStart())
            {
                stringBuffer.Append(current);
                return(AtKeywordRest(src.Next));
            }
            else if (IsValidEscape(current))
            {
                current = src.Next;
                stringBuffer.Append(ConsumeEscape(current));
                return(AtKeywordRest(src.Next));
            }
            else
            {
                src.Back();
                return(CssToken.Delim(Specification.AT));
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// 4.4.9. Ident state
        /// </summary>
        CssToken IdentStart(Char current)
        {
            if (current == Specification.MINUS)
            {
                current = src.Next;

                if (current.IsNameStart() || IsValidEscape(current))
                {
                    stringBuffer.Append(Specification.MINUS);
                    return(IdentRest(current));
                }

                src.Back();
                return(CssToken.Delim(Specification.MINUS));
            }
            else if (current.IsNameStart())
            {
                stringBuffer.Append(current);
                return(IdentRest(src.Next));
            }
            else if (current == Specification.RSOLIDUS)
            {
                if (IsValidEscape(current))
                {
                    current = src.Next;
                    stringBuffer.Append(ConsumeEscape(current));
                    return(IdentRest(src.Next));
                }
            }

            return(Data(current));
        }
Exemplo n.º 3
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.RSOLIDUS)
     {
         RaiseErrorOccurred(ErrorCode.InvalidCharacter);
         src.Back();
         return(CssToken.Delim(Specification.NUM));
     }
     else
     {
         src.Back();
         return(CssToken.Delim(Specification.NUM));
     }
 }
Exemplo n.º 4
0
        /// <summary>
        /// 4.4.1. Data state
        /// </summary>
        CssToken Data(Char current)
        {
            switch (current)
            {
            case Specification.LF:
            case Specification.CR:
            case Specification.TAB:
            case Specification.SPACE:
                do
                {
                    current = src.Next;
                }while (current.IsSpaceCharacter());
                src.Back();
                return(CssSpecialCharacter.Whitespace);

            case Specification.DQ:
                return(StringDQ(src.Next));

            case Specification.NUM:
                return(HashStart(src.Next));

            case Specification.DOLLAR:
                current = src.Next;

                if (current == Specification.EQ)
                {
                    return(CssMatchToken.Suffix);
                }

                return(CssToken.Delim(src.Previous));

            case Specification.SQ:
                return(StringSQ(src.Next));

            case '(':
                return(CssBracketToken.OpenRound);

            case ')':
                return(CssBracketToken.CloseRound);

            case Specification.ASTERISK:
                current = src.Next;

                if (current == Specification.EQ)
                {
                    return(CssMatchToken.Substring);
                }

                return(CssToken.Delim(src.Previous));

            case Specification.PLUS:
            {
                var c1 = src.Next;

                if (c1 == Specification.EOF)
                {
                    src.Back();
                }
                else
                {
                    var c2 = src.Next;
                    src.Back(2);

                    if (c1.IsDigit() || (c1 == Specification.DOT && c2.IsDigit()))
                    {
                        return(NumberStart(current));
                    }
                }

                return(CssToken.Delim(current));
            }

            case Specification.COMMA:
                return(CssSpecialCharacter.Comma);

            case Specification.DOT:
            {
                var c = src.Next;

                if (c.IsDigit())
                {
                    return(NumberStart(src.Previous));
                }

                return(CssToken.Delim(src.Previous));
            }

            case Specification.MINUS:
            {
                var c1 = src.Next;

                if (c1 == Specification.EOF)
                {
                    src.Back();
                }
                else
                {
                    var c2 = src.Next;
                    src.Back(2);

                    if (c1.IsDigit() || (c1 == Specification.DOT && c2.IsDigit()))
                    {
                        return(NumberStart(current));
                    }
                    else if (c1.IsNameStart())
                    {
                        return(IdentStart(current));
                    }
                    else if (c1 == Specification.RSOLIDUS && !c2.IsLineBreak() && c2 != Specification.EOF)
                    {
                        return(IdentStart(current));
                    }
                    else if (c1 == Specification.MINUS && c2 == Specification.GT)
                    {
                        src.Advance(2);
                        return(CssCommentToken.Close);
                    }
                }

                return(CssToken.Delim(current));
            }

            case Specification.SOLIDUS:
                current = src.Next;

                if (current == Specification.ASTERISK)
                {
                    return(Comment(src.Next));
                }

                return(CssToken.Delim(src.Previous));

            case Specification.RSOLIDUS:
                current = src.Next;

                if (current.IsLineBreak() || current == Specification.EOF)
                {
                    RaiseErrorOccurred(current == Specification.EOF ? ErrorCode.EOF : ErrorCode.LineBreakUnexpected);
                    return(CssToken.Delim(src.Previous));
                }

                return(IdentStart(src.Previous));

            case Specification.COLON:
                return(CssSpecialCharacter.Colon);

            case Specification.SC:
                return(CssSpecialCharacter.Semicolon);

            case Specification.LT:
                current = src.Next;

                if (current == Specification.EM)
                {
                    current = src.Next;

                    if (current == Specification.MINUS)
                    {
                        current = src.Next;

                        if (current == Specification.MINUS)
                        {
                            return(CssCommentToken.Open);
                        }

                        current = src.Previous;
                    }

                    current = src.Previous;
                }

                return(CssToken.Delim(src.Previous));

            case Specification.AT:
                return(AtKeywordStart(src.Next));

            case '[':
                return(CssBracketToken.OpenSquare);

            case ']':
                return(CssBracketToken.CloseSquare);

            case Specification.ACCENT:
                current = src.Next;

                if (current == Specification.EQ)
                {
                    return(CssMatchToken.Prefix);
                }

                return(CssToken.Delim(src.Previous));

            case '{':
                return(CssBracketToken.OpenCurly);

            case '}':
                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 = src.Next;

                if (current == Specification.PLUS)
                {
                    current = src.Next;

                    if (current.IsHex() || current == Specification.QM)
                    {
                        return(UnicodeRange(current));
                    }

                    current = src.Previous;
                }

                return(IdentStart(src.Previous));

            case Specification.PIPE:
                current = src.Next;

                if (current == Specification.EQ)
                {
                    return(CssMatchToken.Dash);
                }
                else if (current == Specification.PIPE)
                {
                    return(CssToken.Column);
                }

                return(CssToken.Delim(src.Previous));

            case Specification.TILDE:
                current = src.Next;

                if (current == Specification.EQ)
                {
                    return(CssMatchToken.Include);
                }

                return(CssToken.Delim(src.Previous));

            case Specification.EOF:
                return(null);

            case Specification.EM:
                current = src.Next;

                if (current == Specification.EQ)
                {
                    return(CssMatchToken.Not);
                }

                return(CssToken.Delim(src.Previous));

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

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