htmlLines
Highlighted code's HTML as lines: an element a line break falls inside is closed at the end of its line and opened again on the next, so each line is whole. A final line break ends the last line; it doesn't start another.
export function htmlLines(html: string): string[] { const lines: string[] = []; const open: string[] = []; let line = ""; for (const [t] of html.matchAll(/<[^>]*>|\n|[^<\n]+/g)) { if (t === "\n") { lines.push( line + open .map((o) => `</${/^<([\w-]+)/.exec(o)![1]}>`) .reverse() .join(""), ); line = open.join(""); } else { if (t.startsWith("</")) open.pop(); else if (t.startsWith("<") && !t.endsWith("/>")) open.push(t); line += t; } } if (line !== open.join("") || !lines.length) lines.push(line); return lines; }