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