import * as htmlparser from "htmlparser2"
export interface HTMLTag extends ElementStructure {
name: string
attrs: {
[index: string]: string
}
type: "element"
}
export interface HTMLText extends ElementStructure {
content: string
type: "text"
}
export interface ElementStructure {
type: "element" | "text" | "style" | "script"
children: ElementStructure[]
}
export function parseHTMLStructure(content: string): ElementStructure[] {
let root: HTMLTag = { type: "element", children: [], attrs: {}, name: "root" }
let stack = []
let cur: ElementStructure = root
let parser = new htmlparser.Parser({
onopentag: (name, attrs) => {
let el: HTMLTag
el = {
type: "element", attrs,
children: [],
name
} as HTMLTag
cur.children.push(el)
stack.push(cur)
cur = el
},
ontext: (text: string) => {
cur.children.push({
type: "text",
content: text,
children: null
} as ElementStructure)
},
onclosetag: () => {
cur = stack.pop()
}
}, { decodeEntities: true })
parser.end(content)
return root.children
}
export function structureToString(s: ElementStructure) {
if (s.type === "text") return s["content"]
let result = ""
for (let child of s["children"] || []) {
result += structureToString(child)
}
return result
}