/// <summary> /// Parse using the supplied token reader. /// </summary> /// <param name="reader">Instance of token reader.</param> /// <param name="parseTagsOnly">True to parse tags only.</param> /// <returns>Parsed content.</returns> public MacroDoc Parse(Scanner reader, bool parseTagsOnly) { _reader = reader; _reader.ReadChar(); while (!_reader.IsEnded()) { char current = _reader.CurrentChar; char nextchar = _reader.PeekChar(); // Escaping tag via prefix. $$ if (_hasTagPrefix && current == _tagPrefix && nextchar == _tagPrefix) { _innerContent.Append(current); _reader.ReadChar(); } // Escaping tag with open bracket - no tag prefix. [[ else if (!_hasTagPrefix && current == _openBracket && nextchar == _openBracket) { _innerContent.Append(current); _reader.ReadChar(); } // Start tag. $[div else if (_hasTagPrefix && current == _tagPrefix && nextchar == _openBracket) { _reader.ReadChar(); ParseTagStart(true); } // Weird scenario w/ [] else if (current == _openBracket && nextchar == _closeBracket) { _innerContent.Append(current); _innerContent.Append(_reader.ReadChar()); } // Start tag no prefix else if (!_hasTagPrefix && current == _openBracket && nextchar != '/') { ParseTagStart(true); } // Empty tag else if (current == '/' && nextchar == _closeBracket && (_lastTokenType == TokenType.StartTag || _lastTokenType == TokenType.Attr)) { var lastTag = _tags.Peek(); lastTag.IsEmpty = true; _reader.ReadChar(); lastTag.Length = (_reader.Position - lastTag.Position) + 1; _lastTokenType = TokenType.EndTag; } // End tag [/div] else if (current == _openBracket && nextchar == '/') { ParseTagEnd(true); } // End of start tag ] else if (current == _closeBracket && (_lastTokenType == TokenType.StartTag || _lastTokenType == TokenType.Attr)) { ParseInnerHtml(true); } // Remove empty space between starttag and attributes and between attributes themselves. else if ((_lastTokenType == TokenType.Attr || _lastTokenType == TokenType.StartTag) && current == ' ') { _reader.ConsumeWhiteSpace(false, false); } // Character for antoher attribute. else if ((_lastTokenType == TokenType.StartTag || _lastTokenType == TokenType.Attr) && Char.IsLetter(current)) { ParseAttribute(); } // Other non tag related content. else if (_lastTokenType == TokenType.EndTag || _lastTokenType == TokenType.None) { _innerContent.Append(current); } else { Console.WriteLine(current); } _reader.ReadChar(); } var doc = new MacroDoc(); // The tags are in a stack ( most recent is index 0 ) // So reverse the order when building the list of tags so they come in sequential order. var tags = _tags.ToArray(); for (int ndx = tags.Length - 1; ndx >= 0; ndx--) { doc.Tags.Add(tags[ndx]); } doc.RawContent = _content; doc.Content = _innerContent.ToString(); return(doc); }
/// <summary> /// Parse using the supplied token reader. /// </summary> /// <param name="reader"></param> /// <returns></returns> public MacroDoc Parse(ITokenReader reader, bool parseTagsOnly) { _reader = reader; _reader.ReadChar(); while (!_reader.IsEnd()) { string current = _reader.CurrentChar; var nextchar = _reader.PeekChar(); // Escaping tag via prefix. $$ if (_hasTagPrefix && current == _tagPrefix && nextchar == _tagPrefix) { _innerContent.Append(current); _reader.ReadChar(); } // Escaping tag with open bracket - no tag prefix. [[ else if (!_hasTagPrefix && current == _openBracket && nextchar == _openBracket) { _innerContent.Append(current); _reader.ReadChar(); } // Start tag. $[div else if (_hasTagPrefix && current == _tagPrefix && nextchar == _openBracket) { _reader.ReadChar(); ParseTagStart(true); } // Weird scenario w/ [] else if (current == _openBracket && nextchar == _closeBracket) { _innerContent.Append(current); _innerContent.Append(_reader.ReadChar()); } // Start tag no prefix else if (!_hasTagPrefix && current == _openBracket && nextchar != "/") { ParseTagStart(true); } // Empty tag else if (current == "/" && nextchar == _closeBracket && (_lastTokenType == TokenType.StartTag || _lastTokenType == TokenType.Attr)) { _tags.Peek().IsEmpty = true; _reader.ReadChar(); _lastTokenType = TokenType.EndTag; } // End tag [/div] else if (current == _openBracket && nextchar == "/") { ParseTagEnd(true); } // End of start tag ] else if (current == _closeBracket && (_lastTokenType == TokenType.StartTag || _lastTokenType == TokenType.Attr)) { ParseInnerHtml(true); } // Remove empty space between starttag and attributes and between attributes themselves. else if ((_lastTokenType == TokenType.Attr || _lastTokenType == TokenType.StartTag) && current == " ") { _reader.ConsumeWhiteSpace(false, false); } // Character for antoher attribute. else if ((_lastTokenType == TokenType.StartTag || _lastTokenType == TokenType.Attr) && Char.IsLetter(current[0])) { ParseAttribute(); } // Other non tag related content. else if (_lastTokenType == TokenType.EndTag || _lastTokenType == TokenType.None) { _innerContent.Append(current); } else { Console.WriteLine(current); } _reader.ReadChar(); } var doc = new MacroDoc(); doc.Tags = new List <Tag>(_tags); doc.RawContent = _content; doc.Content = _innerContent.ToString(); return(doc); }