Example #1
0
            public override void Read(Tokeniser t, CharacterReader r)
            {
                if (r.IsEmpty())
                {
                    t.EofError(this);
                    t.DoctypePending.ForceQuirks = true;
                    t.EmitDoctypePending();
                    t.Transition(Data);
                    return;
                }
                if (r.MatchesAny('\t', '\n', '\r', '\f', ' '))
                {
                    r.Advance(); // ignore whitespace
                }
                else if (r.Matches('>'))
                {
                    t.EmitDoctypePending();
                    t.AdvanceTransition(Data);
                }
                else if (r.MatchConsumeIgnoreCase("PUBLIC"))
                {
                    t.Transition(AfterDoctypePublicKeyword);
                }
                else if (r.MatchConsumeIgnoreCase("SYSTEM"))
                {
                    t.Transition(AfterDoctypeSystemKeyword);
                }
                else
                {
                    t.Error(this);
                    t.DoctypePending.ForceQuirks = true;
                    t.AdvanceTransition(BogusDoctype);
                }

            }
Example #2
0
        public char?ConsumeCharacterReference(char?additionalAllowedCharacter, bool inAttribute)
        {
            if (_reader.IsEmpty())
            {
                return(null);
            }

            if (additionalAllowedCharacter != null && additionalAllowedCharacter == _reader.Current())
            {
                return(null);
            }

            if (_reader.MatchesAny('\t', '\n', '\r', '\f', ' ', '<', '&'))
            {
                return(null);
            }

            _reader.Mark();
            if (_reader.MatchConsume("#"))
            { // numbered
                bool isHexMode = _reader.MatchConsumeIgnoreCase("X");

                string numRef = isHexMode ? _reader.ConsumeHexSequence() : _reader.ConsumeDigitSequence();

                if (numRef.Length == 0)
                { // didn't match anything
                    CharacterReferenceError("Numeric reference with no numerals");
                    _reader.RewindToMark();
                    return(null);
                }

                if (!_reader.MatchConsume(";"))
                {
                    CharacterReferenceError("Missing semicolon"); // missing semi
                }

                int charval = -1;
                try
                {
                    int numbase = isHexMode ? 16 : 10;
                    charval = Convert.ToInt32(numRef, numbase);
                }
                catch (FormatException)
                {
                } // skip
                if (charval == -1 || (charval >= 0xD800 && charval <= 0xDFFF) || charval > 0x10FFFF)
                {
                    CharacterReferenceError("Character outside of valid range");
                    return(ReplacementChar);
                }
                else
                {
                    // todo: implement number replacement table
                    // todo: check for extra illegal unicode points as parse errors
                    return((char)charval);
                }
            }
            else
            { // named
                // get as many letters as possible, and look for matching entities. unconsume backwards till a match is found
                string nameRef    = _reader.ConsumeLetterThenDigitSequence();
                bool   looksLegit = _reader.Matches(';');

                // found if a base named entity without a ;, or an extended entity with the ;.
                bool found = (Entities.IsBaseNamedEntity(nameRef) || (Entities.IsNamedEntity(nameRef) && looksLegit));


                if (!found)
                {
                    _reader.RewindToMark();
                    if (looksLegit)
                    {
                        CharacterReferenceError(string.Format("Invalid named referenece '{0}'", nameRef));
                    }
                    return(null);
                }

                if (inAttribute && (_reader.MatchesLetter() || _reader.MatchesDigit() || _reader.MatchesAny('=', '-', '_')))
                {
                    // don't want that to match
                    _reader.RewindToMark();
                    return(null);
                }

                if (!_reader.MatchConsume(";"))
                {
                    CharacterReferenceError("Missing semicolon"); // missing semi
                }

                return(Entities.GetCharacterByName(nameRef));
            }
        }
Example #3
0
 public override void Read(Tokeniser t, CharacterReader r)
 {
     if (r.MatchConsume("--"))
     {
         t.CreateCommentPending();
         t.Transition(CommentStart);
     }
     else if (r.MatchConsumeIgnoreCase("DOCTYPE"))
     {
         t.Transition(Doctype);
     }
     else if (r.MatchConsume("[CDATA["))
     {
         // todo: should actually check current namepspace, and only non-html allows cdata. until namespace
         // is implemented properly, keep handling as cdata
         //} else if (!t.currentNodeInHtmlNS() && r.matchConsume("[CDATA[")) {
         t.Transition(CDataSection);
     }
     else
     {
         t.Error(this);
         t.AdvanceTransition(BogusComment); // advance so this character gets in bogus comment data's rewind
     }
 }