package html type nameQuery struct { value string } type attributesQuery struct { value Attributes } type attributeQuery struct { name string value string found bool } type childrenQuery struct { value []any } type validator struct { err error } type renderGuidesQuery struct { value []renderGuide } func groupChildren(c []any) ([]Attributes, []any, []renderGuide) { var ( a []Attributes cc []any rg []renderGuide ) for _, ci := range c { if ai, ok := ci.(Attributes); ok { a = append(a, ai) continue } if rgi, ok := ci.(renderGuide); ok { rg = append(rg, rgi) continue } cc = append(cc, ci) } return a, cc, rg } func mergeAttributes(c []any) Attributes { a, _, _ := groupChildren(c) if len(a) == 0 { return nil } to := make(Attributes) for _, ai := range a { for name, value := range ai { to[name] = value } } return to } func findAttribute(c []any, name string) (string, bool) { a, _, _ := groupChildren(c) for i := len(a) - 1; i >= 0; i-- { value, ok := a[i][name] if ok { return value, true } } return "", false } func handleQuery(name string, children []any) bool { if len(children) == 0 { return false } last := len(children) - 1 lastChild := children[last] if q, ok := lastChild.(*nameQuery); ok { q.value = name return true } if q, ok := lastChild.(*attributesQuery); ok { q.value = mergeAttributes(children[:last]) return true } if q, ok := lastChild.(*attributeQuery); ok { q.value, q.found = findAttribute(children[:last], q.name) return true } if q, ok := lastChild.(*childrenQuery); ok { _, q.value, _ = groupChildren(children[:last]) return true } if q, ok := lastChild.(*renderGuidesQuery); ok { _, _, q.value = groupChildren(children[:last]) return true } if v, ok := lastChild.(*validator); ok { v.err = validate(name, children[:last]) return true } if r, ok := lastChild.(*renderer); ok { if err := validate(name, children[:last]); err != nil { r.err = err return true } render(r, name, children[:last]) return true } return false }