src/scanner.js
function readTag(sr) {
    let start = sr.getPos() - 1;
    let name;
    if (sr.accept("/")) {
        name = sr.expectRE(RE_TAG_NAME);
        sr.expect(">");
        return { type: "tag_2", start, name };
    }
    name = sr.expectRE(RE_TAG_NAME);
    let props = {};
    while (true) {
        sr.acceptRE(RE_WS);
        if (sr.accept(">")) {
            return { type: "tag_1", start, name, props };
        }
        if (sr.accept("/")) {
            sr.expect(">");
            return { type: "tag_0", start, name, props };
        }
        let pName = sr.expectRE(RE_PROP_NAME);
        sr.acceptRE(RE_WS);
        sr.expect("=");
        sr.acceptRE(RE_WS);
        sr.expect('"');
        let pValue = sr.expectRE(RE_PROP_VALUE);
        sr.expect('"');
        props[pName] = pValue;
    }
}
function readTag(sr) {
    let start = sr.getPos() - 1;
    let name;
    if (sr.accept("/")) {
        name = sr.expectRE(RE_TAG_NAME);
        sr.expect(">");
        return { type: "tag_2", start, name };
    }
    name = sr.expectRE(RE_TAG_NAME);
    let props = {};
    while (true) {
        sr.acceptRE(RE_WS);
        if (sr.accept(">")) {
            return { type: "tag_1", start, name, props };
        }
        if (sr.accept("/")) {
            sr.expect(">");
            return { type: "tag_0", start, name, props };
        }
        let pName = sr.expectRE(RE_PROP_NAME);
        sr.acceptRE(RE_WS);
        sr.expect("=");
        sr.acceptRE(RE_WS);
        sr.expect('"');
        let pValue = sr.expectRE(RE_PROP_VALUE);
        sr.expect('"');
        props[pName] = pValue;
    }
}
object => object