protected virtual void AcceptWhiteSpaceByLines() { Debug.Assert(InTemporaryBuffer); // Eat whitespace until a non-whitespace character, while (Char.IsWhiteSpace(CurrentCharacter)) { Context.AcceptWhiteSpace(includeNewLines: false); // Stopped because of a newline, so accept the newline, then accept the temporary buffer and start it again if (Char.IsWhiteSpace(CurrentCharacter)) { Context.AcceptLine(includeNewLineSequence: true); Context.AcceptTemporaryBuffer(); Context.StartTemporaryBuffer(); } } }
private bool ParseTagBlock(bool inDocument) { // For tracking end tags Stack <TagInfo> tags = new Stack <TagInfo>(); bool startedByPseudoTag = false; bool?canGrow = null; do { // Append until the next tag, processing code as we find it AppendUntilAndParseCode(c => c == '<'); // Read the tag name in lookahead since we might not actually want to accept it TagInfo tag = ParseStartOfTag(); // Special case for "<text>" tag as the first tag we've seen if (IsPsuedoTagValidHere(inDocument, tags, startedByPseudoTag, tag)) { if (!tag.IsEndTag) { startedByPseudoTag = true; // Set a flag to indicate that a </text> is a valid end tag if (ParseStartPsuedoTag(tags, tag)) { // Can't just do "canGrow = !ParseStartPsuedoTag(...)" because we can't canGrow to // stay null if we get false from ParseStartPsuedoTag canGrow = false; } } else { ParseEndPsuedoTag(tags, tag, inDocument); canGrow = false; } } // It wasn't a "<text>" OR it was but it was within a block, so we don't do anything special else { // We're at the '<' Context.AcceptCurrent(); // "<" if (tag.IsEndTag) { Context.AcceptCurrent(); // "/" } Context.AcceptCharacters(tag.Name.Length); // tag name // Invalid tag name? Not a real tag if (!String.IsNullOrEmpty(tag.Name)) { // What kind of tag is it bool?unterminated = null; switch (tag.Name[0]) { case '!': unterminated = ParseBangTag(tag.Name); break; case '?': unterminated = ParseProcessingInstruction(); break; default: if (tag.IsEndTag) { unterminated = ParseEndTag(tags, tag, inDocument); } else { unterminated = ParseStartTag(tags, tag); } break; } if (tags.Count == 0 && unterminated != null) { canGrow = unterminated.Value; } } else { canGrow = true; if (tags.Count == 0) { OnError(CurrentLocation, RazorResources.ParseError_OuterTagMissingName); } } } } while (!EndOfFile && tags.Count > 0); if (canGrow == null) { canGrow = tags.Count > 0; } if (tags.Count > 0) { // Ended because of EOF, not matching close tag. Throw error for last tag while (tags.Count > 1) { tags.Pop(); } TagInfo tag = tags.Pop(); OnError(tag.Start, RazorResources.ParseError_MissingEndTag, tag.Name); } // Add the remaining whitespace (up to and including the next newline) to the token if run-time mode if (!DesignTimeMode) { // Dev10 Bug 884969 - Emit space between markup and code Context.AcceptWhiteSpace(includeNewLines: false); if (Char.IsWhiteSpace(CurrentCharacter)) { Context.AcceptLine(includeNewLineSequence: true); } } else if (canGrow.Value) { Context.AcceptWhiteSpace(includeNewLines: false); if (ParserHelpers.IsNewLine(CurrentCharacter)) { Context.AcceptNewLine(); } } return(canGrow.Value); }