private static HtmlTag ParseHelper(StringScanner p)
{
// Does it look like a tag?
if (p.Current != '<')
return null;
// Skip '<'
p.SkipForward(1);
// Is it a comment?
if (p.SkipString("!--"))
{
p.Mark();
if (p.Find("-->"))
{
var t = new HtmlTag("!");
t.m_attributes.Add("content", p.Extract());
t.m_closed = true;
p.SkipForward(3);
return t;
}
}
// Is it a closing tag eg: </div>
bool bClosing = p.SkipChar('/');
// Get the tag name
string tagName=null;
if (!p.SkipIdentifier(ref tagName))
return null;
// Probably a tag, create the HtmlTag object now
HtmlTag tag = new HtmlTag(tagName);
tag.m_closing = bClosing;
// If it's a closing tag, no attributes
if (bClosing)
{
if (p.Current != '>')
return null;
p.SkipForward(1);
return tag;
}
while (!p.Eof)
{
// Skip whitespace
p.SkipWhitespace();
// Check for closed tag eg: <hr />
if (p.SkipString("/>"))
{
tag.m_closed=true;
return tag;
}
// End of tag?
if (p.SkipChar('>'))
{
return tag;
}
// attribute name
string attributeName = null;
if (!p.SkipIdentifier(ref attributeName))
return null;
// Skip whitespace
p.SkipWhitespace();
// Skip equal sign
if (p.SkipChar('='))
{
// Skip whitespace
p.SkipWhitespace();
// Optional quotes
if (p.SkipChar('\"'))
{
// Scan the value
p.Mark();
if (!p.Find('\"'))
return null;
// Store the value
tag.m_attributes.Add(attributeName, p.Extract());
// Skip closing quote
p.SkipForward(1);
}
else
{
// Scan the value
p.Mark();
while (!p.Eof && !char.IsWhiteSpace(p.Current) && p.Current != '>' && p.Current != '/')
p.SkipForward(1);
if (!p.Eof)
{
// Store the value
tag.m_attributes.Add(attributeName, p.Extract());
}
}
}
else
{
tag.m_attributes.Add(attributeName, "");
}
}
return null;
}