// Although nodes slice is not modified, its elements are. func compactNodes(nodes []types.Node) []types.Node { res := make([]types.Node, 0, len(nodes)) var last types.Node for _, n := range nodes { switch { case n.Type() == types.NodeList: l := n.(*types.ListNode) l.Nodes = compactNodes(l.Nodes) case types.IsItemsList(n.Type()): l := n.(*types.ItemsListNode) for _, it := range l.Items { it.Nodes = compactNodes(it.Nodes) } } if last == nil || !concatNodes(last, n) { last = n res = append(res, n) if n.Type() == types.NodeCode { c := n.(*types.CodeNode) c.Value = strings.TrimLeft(c.Value, "\n") } } } return res }
func concatNodes(a, b types.Node) bool { switch { case a.Type() == types.NodeText && b.Type() == types.NodeText: return concatText(a, b) case a.Type() == types.NodeCode && b.Type() == types.NodeCode: return concatCode(a, b) case a.Type() == types.NodeCode && b.Type() == types.NodeText: t := b.(*types.TextNode) if strings.TrimSpace(t.Value) == "" { return true } case a.Type() == types.NodeURL && b.Type() == types.NodeURL: return concatURL(a, b) case types.IsItemsList(a.Type()) && types.IsItemsList(b.Type()): return concatItemsList(a, b) } return false }