scanHtml function
Scans html sequentially, yielding HtmlTag and HtmlText tokens in
document order. Comments, doctypes, and processing instructions are
skipped. Malformed input degrades to text instead of throwing.
Implementation
Iterable<Object> scanHtml(String html) sync* {
var i = 0;
final length = html.length;
while (i < length) {
final lt = html.indexOf('<', i);
if (lt == -1) {
yield HtmlText(html.substring(i), i);
return;
}
if (lt > i) yield HtmlText(html.substring(i, lt), i);
// Not a tag start (a literal '<' in text): emit it as text and move on.
if (!_isTagStartAt(html, lt)) {
yield HtmlText('<', lt);
i = lt + 1;
continue;
}
final declarationEnd = _skipMarkupDeclaration(html, lt);
if (declarationEnd != null) {
i = declarationEnd;
continue;
}
final gt = _findTagEnd(html, lt + 1);
if (gt == -1) {
// Unterminated tag at EOF: treat the rest as text.
yield HtmlText(html.substring(lt), lt);
return;
}
yield* _tagTokens(html, lt, gt);
i = gt + 1;
}
}