From b1f6bde29f1e4a150a762beec8a59c33abd441fd Mon Sep 17 00:00:00 2001 From: "Gustavo \"Guz\" L de Mello" Date: Fri, 16 May 2025 15:17:56 -0300 Subject: [PATCH] feat(ipub,ast): xml.Unmarshaller implementation for Elements --- ipub/ast/ast.go | 37 +++++++++++++++++++++++++++++++++++++ ipub/ast/content.go | 4 ++++ ipub/ast/section.go | 3 +++ 3 files changed, 44 insertions(+) diff --git a/ipub/ast/ast.go b/ipub/ast/ast.go index 7939d33..c04ebad 100644 --- a/ipub/ast/ast.go +++ b/ipub/ast/ast.go @@ -34,6 +34,8 @@ type Element interface { InsertBefore(self, v1, insertee Element) InsertAfter(self, v1, insertee Element) + xml.Unmarshaler +} type BaseElement struct { next Element @@ -178,6 +180,41 @@ func (e *BaseElement) InsertBefore(self, v1, insertee Element) { } } +func (e *BaseElement) UnmarshalChildren(self Element, d *xml.Decoder, start xml.StartElement) error { + for { + token, err := d.Token() + if err != nil { + return err + } + if err == io.EOF { + return nil + } + + switch tt := token.(type) { + case xml.StartElement: + i := slices.IndexFunc(tt.Attr, func(a xml.Attr) bool { + return a.Name.Local == "data-ipub-element" + }) + if i == -1 { + return fmt.Errorf("element kind not specified") + } + + kind := tt.Attr[i].Value + kt, ok := elementKindList[ElementKind(kind)] + if !ok { + return fmt.Errorf("element kind not found") + } + + err := d.DecodeElement(kt, &tt) + if err != nil && err != io.EOF { + return err + } + + e.AppendChild(self, kt) + } + } +} + func ensureIsolated(e Element) { if p := e.Parent(); p != nil { p.RemoveChild(p, e) diff --git a/ipub/ast/content.go b/ipub/ast/content.go index 4013265..4c3e336 100644 --- a/ipub/ast/content.go +++ b/ipub/ast/content.go @@ -15,3 +15,7 @@ func (n *Content) Kind() ElementKind { return KindContent } +func (n *Content) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { + return n.UnmarshalChildren(n, d, start) +} + diff --git a/ipub/ast/section.go b/ipub/ast/section.go index 10d5228..d2223a5 100644 --- a/ipub/ast/section.go +++ b/ipub/ast/section.go @@ -18,3 +18,6 @@ func (n *Body) Kind() ElementKind { return KindBody } +func (n *Body) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { + return n.UnmarshalChildren(n, d, start) +}