private Node parseTag()
{
// ast-filter look-ahead
int i = 2;
if (lookahead(i) is Attribute)
{
i++;
}
if (lookahead(i) is Colon)
{
i++;
if (lookahead(i) is Indent)
{
return this.parseASTFilter();
}
}
Token token = nextToken();
String name = token.getValue();
TagNode tagNode = new TagNode();
tagNode.setLineNumber(_jadeLexer.getLineno());
tagNode.setFileName(filename);
tagNode.setName(name);
tagNode.setValue(name);
tagNode.setSelfClosing(token.isSelfClosing());
while (true)
{
Token incomingToken = peek();
if (incomingToken is CssId)
{
Token tok = nextToken();
tagNode.addAttribute("id", tok.getValue());
continue;
}
else if (incomingToken is CssClass)
{
Token tok = nextToken();
tagNode.addAttribute("class", tok.getValue());
continue;
}
else if (incomingToken is Attribute)
{
Attribute tok = (Attribute) nextToken();
tagNode.addAttributes(tok.getAttributes());
tagNode.setSelfClosing(tok.isSelfClosing());
continue;
}
else
{
break;
}
}
// check immediate '.'
bool dot = false;
if (peek() is Dot)
{
dot = true;
tagNode.setTextOnly(true);
nextToken();
}
// (text | code | ':')?
if (peek() is Text)
{
tagNode.setTextNode(parseText());
}
else if (peek() is Jade.Lexer.Tokens.Expression)
{
tagNode.setCodeNode(parseCode());
}
else if (peek() is Colon)
{
Token next = nextToken();
BlockNode block = new BlockNode();
block.setLineNumber(next.getLineNumber());
block.setFileName(filename);
tagNode.setBlock(block);
block.push(parseExpr());
}
// newline*
while (peek() is Newline)
{
nextToken();
}
if (!tagNode.isTextOnly())
{
if (Array.IndexOf(textOnlyTags, tagNode.getName()) >= 0)
{
tagNode.setTextOnly(true);
}
}
// script special-case
if ("script".Equals(tagNode.getName()))
{
String type = tagNode.getAttribute("type");
if (!dot && StringUtils.isNotBlank(type))
{
String cleanType = type.replaceAll("^['\"]|['\"]$", "");
if (!"text/javascript".Equals(cleanType))
{
tagNode.setTextOnly(false);
}
}
}
if (peek() is Indent)
{
if (tagNode.isTextOnly())
{
_jadeLexer.setPipeless(true);
tagNode.setTextNode(parseTextBlock());
_jadeLexer.setPipeless(false);
}
else
{
Node blockNode = block();
if (tagNode.hasBlock())
{
tagNode.getBlock().getNodes().AppendRange(blockNode.getNodes());
}
else
{
tagNode.setBlock(blockNode);
}
}
}
return tagNode;
}