public static NextTokenType PeekNextToken(HtmlCharStream cs, int tagEnd, out ITextRange range) { NextTokenType tokenType = NextTokenType.Unknown; int current = cs.Position; if (cs.IsEndOfStream() || cs.Position == tagEnd) { range = new TextRange(); return NextTokenType.None; } int start = cs.Position; while (cs.IsWhiteSpace()) cs.MoveToNextChar(); if (cs.IsEndOfStream() || cs.Position == tagEnd) { range = TextRange.FromBounds(start, cs.Position); return NextTokenType.Unknown; } if (cs.IsAtTagDelimiter()) { tokenType = NextTokenType.Tag; } else if (cs.CurrentChar == '=') { tokenType = NextTokenType.Equals; } else { int digits = 0; bool firstLetter = false; int length = 0; int chars = 0; if (cs.IsAnsiLetter()) firstLetter = true; while (!cs.IsEndOfStream() && !cs.IsWhiteSpace() && !cs.IsAtTagDelimiter() && cs.CurrentChar != '=' && cs.Position < tagEnd) { if (cs.IsAnsiLetter() || cs.CurrentChar == '_' || cs.CurrentChar == '-') chars++; else if (cs.IsDecimal() || cs.CurrentChar == '.') digits++; cs.MoveToNextChar(); length++; } if (length > 0) { if (length == digits) tokenType = NextTokenType.Number; else if (length == chars) tokenType = NextTokenType.Letters; else if (firstLetter) tokenType = NextTokenType.Identifier; } } range = TextRange.FromBounds(start, cs.Position); cs.Position = current; return tokenType; }
public void CharStream_BasicTest() { string text = "abcd\"foo\"\r\n<a href="; HtmlCharStream cs = new HtmlCharStream(text); Assert.Equal('a', cs.CurrentChar); cs.Advance(2); Assert.False(cs.IsEndOfStream()); Assert.Equal('c', cs.CurrentChar); cs.Advance(-1); Assert.False(cs.IsEndOfStream()); Assert.Equal('b', cs.CurrentChar); cs.Advance(text.Length); Assert.True(cs.IsEndOfStream()); Assert.Equal(0, cs.CurrentChar); cs.Advance(-text.Length); Assert.False(cs.IsEndOfStream()); Assert.Equal('a', cs.CurrentChar); Assert.Equal('d', cs.LookAhead(3)); Assert.Equal('\"', cs.LookAhead(4)); Assert.Equal(0, cs.LookAhead(text.Length)); Assert.Equal(0, cs.LookAhead(-1)); Assert.Equal(text.Length, cs.DistanceFromEnd); cs.Advance(1); Assert.Equal(text.Length - 1, cs.DistanceFromEnd); cs.Position = 4; Assert.True(cs.IsAtString()); cs.Position = 5; Assert.False(cs.IsAtString()); cs.Position = 9; Assert.True(cs.IsWhiteSpace()); cs.MoveToNextChar(); Assert.True(cs.IsWhiteSpace()); cs.MoveToNextChar(); Assert.True(cs.IsAtTagDelimiter()); }