public void ConsumeLetterSequence() { CharacterReader r = new CharacterReader("One &bar; qux"); Assert.AreEqual("One", r.ConsumeLetterSequence()); Assert.AreEqual(" &", r.ConsumeTo("bar;")); Assert.AreEqual("bar", r.ConsumeLetterSequence()); Assert.AreEqual("; qux", r.ConsumeToEnd()); }
internal override void Read(Tokeniser t, CharacterReader r) { if (r.MatchesLetter()) { string name = r.ConsumeLetterSequence(); t.tagPending.AppendTagName(name.ToLower()); t.dataBuffer.Append(name); return; } char c = r.Consume(); switch (c) { case '\t': case '\n': case '\r': case '\f': case ' ': if (t.IsAppropriateEndTagToken()) { t.Transition(TokeniserState.BeforeAttributeName); } else { this.AnythingElse(t, r); } break; case '/': if (t.IsAppropriateEndTagToken()) { t.Transition(TokeniserState.SelfClosingStartTag); } else { this.AnythingElse(t, r); } break; case '>': if (t.IsAppropriateEndTagToken()) { t.EmitTagPending(); t.Transition(TokeniserState.Data); } else { this.AnythingElse(t, r); } break; default: this.AnythingElse(t, r); break; } }
/// <summary> /// Handles RawtextEndTagName, ScriptDataEndTagName, and ScriptDataEscapedEndTagName. /// </summary> /// <remarks> /// Handles RawtextEndTagName, ScriptDataEndTagName, and ScriptDataEscapedEndTagName. Same body impl, just /// different else exit transitions. /// </remarks> private static void HandleDataEndTag(Tokeniser t, CharacterReader r, TokeniserState elseTransition) { if (r.MatchesLetter()) { string name = r.ConsumeLetterSequence(); t.tagPending.AppendTagName(name.ToLower()); t.dataBuffer.Append(name); return; } bool needsExitTransition = false; if (t.IsAppropriateEndTagToken() && !r.IsEmpty()) { char c = r.Consume(); switch (c) { case '\t': case '\n': case '\r': case '\f': case ' ': { t.Transition(BeforeAttributeName); break; } case '/': { t.Transition(SelfClosingStartTag); break; } case '>': { t.EmitTagPending(); t.Transition(Data); break; } default: { t.dataBuffer.Append(c); needsExitTransition = true; break; } } } else { needsExitTransition = true; } if (needsExitTransition) { t.Emit("</" + t.dataBuffer.ToString()); t.Transition(elseTransition); } }
private static void HandleDataDoubleEscapeTag(Tokeniser t, CharacterReader r, TokeniserState primary, TokeniserState fallback) { if (r.MatchesLetter()) { string name = r.ConsumeLetterSequence(); t.dataBuffer.Append(name.ToLower()); t.Emit(name); return; } char c = r.Consume(); switch (c) { case '\t': case '\n': case '\r': case '\f': case ' ': case '/': case '>': { if (t.dataBuffer.ToString().Equals("script")) { t.Transition(primary); } else { t.Transition(fallback); } t.Emit(c); break; } default: { r.Unconsume(); t.Transition(fallback); break; } } }
internal override void Read(Tokeniser t, CharacterReader r) { if (r.MatchesLetter()) { string name = r.ConsumeLetterSequence(); t.doctypePending.name.Append(name.ToLower()); return; } char c = r.Consume(); switch (c) { case '>': t.EmitDoctypePending(); t.Transition(TokeniserState.Data); break; case '\t': case '\n': case '\r': case '\f': case ' ': t.Transition(TokeniserState.AfterDoctypeName); break; case TokeniserState.nullChar: t.Error(this); t.doctypePending.name.Append(TokeniserState.replacementChar); break; case TokeniserState.eof: t.EofError(this); t.doctypePending.forceQuirks = true; t.EmitDoctypePending(); t.Transition(TokeniserState.Data); break; default: t.doctypePending.name.Append(c); break; } }