def STag.parse(raw_string, is_stag, is_xml, is_html, inherited_context=DefaultContext)
attrs = []
if (is_stag ? /\A#{Pat::ValidStartTag_C}\z/o : /\A#{Pat::ValidEmptyTag_C}\z/o) =~ raw_string
qname = $1
$2.scan(Pat::ValidAttr_C) {
attrs << ($5 ? [nil, $5] : [$1, $2 || $3 || $4])
}
elsif (is_stag ? /\A#{Pat::InvalidStartTag_C}\z/o : /\A#{Pat::InvalidEmptyTag_C}\z/o) =~ raw_string
qname = $1
last_attr = $3
$2.scan(Pat::InvalidAttr1_C) {
attrs << ($5 ? [nil, $5] : [$1, $2 || $3 || $4])
}
if last_attr
/#{Pat::InvalidAttr1End_C}/o =~ last_attr
attrs << [$1, $2 || $3]
end
else
raise HTree::Error, "cannot recognize as start tag or empty tag: #{raw_string.inspect}"
end
qname = qname.downcase if !is_xml && is_html
attrs.map! {|aname, aval|
if aname
aname = (!is_xml && is_html) ? aname.downcase : aname
[aname, Text.parse_pcdata(aval)]
else
if val2name = OmittedAttrName[qname]
aval_downcase = aval.downcase
aname = val2name.fetch(aval_downcase, aval_downcase)
else
aname = aval
end
[aname, Text.new(aval)]
end
}
result = STag.new(qname, attrs, inherited_context)
result.raw_string = raw_string
result
end