public virtual void Parse(Lexer lexer, Node table, short mode)
{
int istackbase;
TagCollection tt = lexer.Options.TagTable;
lexer.DeferDup();
istackbase = lexer.Istackbase;
lexer.Istackbase = lexer.Istack.Count;
while (true)
{
Node node = lexer.GetToken(Lexer.IGNORE_WHITESPACE);
if (node == null)
break;
if (node.Tag == table.Tag && node.Type == Node.END_TAG)
{
lexer.Istackbase = istackbase;
table.Closed = true;
Node.TrimEmptyElement(lexer, table);
return;
}
/* deal with comments etc. */
if (Node.InsertMisc(table, node))
continue;
/* discard unknown tags */
if (node.Tag == null && node.Type != Node.TEXT_NODE)
{
Report.Warning(lexer, table, node, Report.DISCARDING_UNEXPECTED);
continue;
}
/* if TD or TH or text or inline or block then infer <TR> */
if (node.Type != Node.END_TAG)
{
if (node.Tag == tt.TagTd || node.Tag == tt.TagTh || node.Tag == tt.TagTable)
{
lexer.UngetToken();
node = lexer.InferredTag("tr");
Report.Warning(lexer, table, node, Report.MISSING_STARTTAG);
}
else if (node.Tag != null && (node.Type == Node.TEXT_NODE ||
(node.Tag.Model & (ContentModel.BLOCK | ContentModel.INLINE)) != 0))
{
Node.InsertNodeBeforeElement(table, node);
Report.Warning(lexer, table, node, Report.TAG_NOT_ALLOWED_IN);
lexer.Exiled = true;
/* AQ: TODO
Line 2040 of parser.c (13 Jan 2000) reads as follows:
if (!node->type == TextNode)
This will always evaluate to false.
This has been reported to Dave Raggett <*****@*****.**>
*/
//Should be?: if (!(node.Type == Node.TextNode))
// if (false)
// TidyNet.ParserImpl.parseTag(lexer, node, Lexer.IgnoreWhitespace);
lexer.Exiled = false;
continue;
}
else if (node.Tag != null && (node.Tag.Model & ContentModel.HEAD) != 0)
{
MoveToHead(lexer, table, node);
continue;
}
}
/*
if this is the end tag for an ancestor element
then infer end tag for this element
*/
if (node.Type == Node.END_TAG)
{
if (node.Tag == tt.TagForm)
{
lexer.BadForm = 1;
Report.Warning(lexer, table, node, Report.DISCARDING_UNEXPECTED);
continue;
}
if (node.Tag != null && (node.Tag.Model & (ContentModel.TABLE | ContentModel.ROW)) != 0)
{
Report.Warning(lexer, table, node, Report.DISCARDING_UNEXPECTED);
continue;
}
Node parent;
for (parent = table.Parent; parent != null; parent = parent.Parent)
{
if (node.Tag != parent.Tag) continue;
Report.Warning(lexer, table, node, Report.MISSING_ENDTAG_BEFORE);
lexer.UngetToken();
lexer.Istackbase = istackbase;
Node.TrimEmptyElement(lexer, table);
return;
}
}
if (node.Tag != null && (node.Tag.Model & ContentModel.TABLE) == 0)
{
lexer.UngetToken();
Report.Warning(lexer, table, node, Report.TAG_NOT_ALLOWED_IN);
lexer.Istackbase = istackbase;
Node.TrimEmptyElement(lexer, table);
return;
}
if (node.Type == Node.START_TAG || node.Type == Node.START_END_TAG)
{
Node.InsertNodeAtEnd(table, node);
ParseTag(lexer, node, Lexer.IGNORE_WHITESPACE);
continue;
}
/* discard unexpected text nodes and end tags */
Report.Warning(lexer, table, node, Report.DISCARDING_UNEXPECTED);
}
Report.Warning(lexer, table, null, Report.MISSING_ENDTAG_FOR);
Node.TrimEmptyElement(lexer, table);
lexer.Istackbase = istackbase;
}