public override AstNode Process(ParserReader parser) { var reader = parser.Input; var attributeParser = new AttributeParser(parser); var baseIndent = parser.Indent; if(!reader.Read()) return null; var node = ReadTagNode(reader); while(!reader.IsEndOfStream) switch(reader.CurrentChar) { case '/': { reader.Skip("/"); node.AutoClose = true; break; } case '#': { reader.Skip("#"); //Todo: should be a port of output var attribute = node.Attributes.Find(a => a.Name.Equals("id", StringComparison.InvariantCultureIgnoreCase)); if(attribute == null) { attribute = new AttributeNode("id"); node.Attributes.Add(attribute); } attribute.Value = parser.ParseText(reader.ReadNameEscaped(), reader.Index); continue; } case '.': { reader.Skip("."); node.Attributes.Add(new AttributeNode("class") { Value = parser.ParseText(reader.ReadNameEscaped(), reader.Index) }); continue; } case '&': reader.CurrentLine.EscapeLine = true; reader.Skip("&"); break; case '!': reader.CurrentLine.EscapeLine = false; reader.Skip("!"); break; case '=': { reader.Skip("="); reader.SkipWhiteSpaces(); node.Child = new CodeNode(reader.ReadToEndMultiLine(), reader.CurrentLine.EscapeLine); break; } case '(': { node.Attributes.AddRange(attributeParser.ParseHtmlStyle()); break; } case '{': { node.Attributes.AddRange(attributeParser.ParseRubyStyle()); break; } default: { var index = reader.Index; var text = reader.ReadToEndMultiLine(); node.Child = parser.ParseText(text.TrimStart(), index); break; } } if (reader.NextLine != null && reader.NextLine.Indent > reader.CurrentLine.Indent) { node.Child = parser.ParseChildren(baseIndent, node.Child); } node.EndInfo = reader.SourceInfo; return node; }
public override AstNode Process(ParserReader parser) { var reader = parser.Input; var attributeParser = new AttributeParser(parser); var baseIndent = parser.Indent; bool isPartial = false; if (!reader.Read()) return null; string name; if (reader.CurrentChar == '_') { reader.Skip("_"); name = "contentplaceholder"; isPartial = true; } else { reader.Skip("@"); name = reader.ReadName(); isPartial = false; } var node = new MetaNode(name); reader.SkipWhiteSpaces(); if (isPartial && (reader.CurrentChar != null)) { node.Name = "partialcontent"; node.Value = reader.ReadWhile(c => !Char.IsWhiteSpace(c) && c != '(' && c != '{'); } else { node.Value = "Main"; } while (!reader.IsEndOfStream) { switch (reader.CurrentChar) { case '=': { if (!isPartial) { reader.Skip("="); reader.SkipWhiteSpaces(); switch (reader.CurrentChar) { case '\'': reader.Skip("'"); node.Value = reader.ReadWhile(c => c != '\''); reader.Skip("'"); break; case '"': reader.Skip("\""); node.Value = reader.ReadWhile(c => c != '"'); reader.Skip("\""); break; default: node.Value = reader.ReadWhile(c => !Char.IsWhiteSpace(c) && c != '(' && c != '{'); break; } } else { throw new ParserException(reader, "'=' is not allowed in partial definitions"); } break; } case '(': { node.Attributes.AddRange(attributeParser.ParseHtmlStyle(false)); break; } case '{': { node.Attributes.AddRange(attributeParser.ParseRubyStyle(false)); break; } default: { var index = reader.Index; var text = reader.ReadToEndMultiLine(); node.Child = parser.ParseText(text.TrimStart(), index); break; } } reader.SkipWhiteSpaces(); } if (reader.NextLine != null && reader.NextLine.Indent > reader.CurrentLine.Indent) { node.Child = parser.ParseChildren(baseIndent, node.Child); } node.EndInfo = reader.SourceInfo; if (!_node.Metadata.ContainsKey(name)) _node.Metadata[name] = new List<MetaNode>(); _node.Metadata[name].Add(node); return node; }