package html type nameQuery struct { value string } type attributesQuery struct { value Attributes } type attributeQuery struct { name string value any 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 Attributes{} } to := Attributes{values: make(map[string]any)} for i := len(a) - 1; i >= 0; i-- { for _, name := range a[i].names { if _, set := to.values[name]; set { continue } to.names = append(to.names, name) to.values[name] = a[i].values[name] } } return to } func findAttribute(c []any, name string) (any, bool) { a, _, _ := groupChildren(c) for i := len(a) - 1; i >= 0; i-- { value, ok := a[i].values[name] if ok { return value, true } } return nil, 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 } r.render(name, children[:last]) return true } return false }