func (n *BaseNode) AttributeString(s string) (interface{}, bool) {
	return n.Attribute(util.StringToReadOnlyBytes(s))
}
AttributeString implements Node.AttributeString.
package ast
import (
	"bytes"
	"fmt"
	"strings"
	textm "github.com/yuin/goldmark/text"
	"github.com/yuin/goldmark/util"
)
type NodeType int
const (
	TypeBlock NodeType = iota + 1
	TypeInline
	TypeDocument
)
type NodeKind int
func (k NodeKind) String() string {
	return kindNames[k]
}
var kindMax NodeKind
var kindNames = []string{""}
func NewNodeKind(name string) NodeKind {
	kindMax++
	kindNames = append(kindNames, name)
	return kindMax
}
type Attribute struct {
	Name  []byte
	Value interface{}
}
type Node interface {
	Type() NodeType
	Kind() NodeKind
	NextSibling() Node
	PreviousSibling() Node
	Parent() Node
	SetParent(Node)
	SetPreviousSibling(Node)
	SetNextSibling(Node)
	HasChildren() bool
	ChildCount() int
	FirstChild() Node
	LastChild() Node
	AppendChild(self, child Node)
	RemoveChild(self, child Node)
	RemoveChildren(self Node)
	SortChildren(comparator func(n1, n2 Node) int)
	ReplaceChild(self, v1, insertee Node)
	InsertBefore(self, v1, insertee Node)
	InsertAfter(self, v1, insertee Node)
	OwnerDocument() *Document
	Dump(source []byte, level int)
	Text(source []byte) []byte
	HasBlankPreviousLines() bool
	SetBlankPreviousLines(v bool)
	Lines() *textm.Segments
	SetLines(*textm.Segments)
	IsRaw() bool
	SetAttribute(name []byte, value interface{})
	SetAttributeString(name string, value interface{})
	Attribute(name []byte) (interface{}, bool)
	AttributeString(name string) (interface{}, bool)
	Attributes() []Attribute
	RemoveAttributes()
}
type BaseNode struct {
	firstChild Node
	lastChild  Node
	parent     Node
	next       Node
	prev       Node
	childCount int
	attributes []Attribute
}
func ensureIsolated(v Node) {
	if p := v.Parent(); p != nil {
		p.RemoveChild(p, v)
	}
}
func (n *BaseNode) HasChildren() bool {
	return n.firstChild != nil
}
func (n *BaseNode) SetPreviousSibling(v Node) {
	n.prev = v
}
func (n *BaseNode) SetNextSibling(v Node) {
	n.next = v
}
func (n *BaseNode) PreviousSibling() Node {
	return n.prev
}
func (n *BaseNode) NextSibling() Node {
	return n.next
}
func (n *BaseNode) RemoveChild(self, v Node) {
	if v.Parent() != self {
		return
	}
	n.childCount--
	prev := v.PreviousSibling()
	next := v.NextSibling()
	if prev != nil {
		prev.SetNextSibling(next)
	} else {
		n.firstChild = next
	}
	if next != nil {
		next.SetPreviousSibling(prev)
	} else {
		n.lastChild = prev
	}
	v.SetParent(nil)
	v.SetPreviousSibling(nil)
	v.SetNextSibling(nil)
}
func (n *BaseNode) RemoveChildren(self Node) {
	for c := n.firstChild; c != nil; {
		c.SetParent(nil)
		c.SetPreviousSibling(nil)
		next := c.NextSibling()
		c.SetNextSibling(nil)
		c = next
	}
	n.firstChild = nil
	n.lastChild = nil
	n.childCount = 0
}
func (n *BaseNode) SortChildren(comparator func(n1, n2 Node) int) {
	var sorted Node
	current := n.firstChild
	for current != nil {
		next := current.NextSibling()
		if sorted == nil || comparator(sorted, current) >= 0 {
			current.SetNextSibling(sorted)
			if sorted != nil {
				sorted.SetPreviousSibling(current)
			}
			sorted = current
			sorted.SetPreviousSibling(nil)
		} else {
			c := sorted
			for c.NextSibling() != nil && comparator(c.NextSibling(), current) < 0 {
				c = c.NextSibling()
			}
			current.SetNextSibling(c.NextSibling())
			current.SetPreviousSibling(c)
			if c.NextSibling() != nil {
				c.NextSibling().SetPreviousSibling(current)
			}
			c.SetNextSibling(current)
		}
		current = next
	}
	n.firstChild = sorted
	for c := n.firstChild; c != nil; c = c.NextSibling() {
		n.lastChild = c
	}
}
func (n *BaseNode) FirstChild() Node {
	return n.firstChild
}
func (n *BaseNode) LastChild() Node {
	return n.lastChild
}
func (n *BaseNode) ChildCount() int {
	return n.childCount
}
func (n *BaseNode) Parent() Node {
	return n.parent
}
func (n *BaseNode) SetParent(v Node) {
	n.parent = v
}
func (n *BaseNode) AppendChild(self, v Node) {
	ensureIsolated(v)
	if n.firstChild == nil {
		n.firstChild = v
		v.SetNextSibling(nil)
		v.SetPreviousSibling(nil)
	} else {
		last := n.lastChild
		last.SetNextSibling(v)
		v.SetPreviousSibling(last)
	}
	v.SetParent(self)
	n.lastChild = v
	n.childCount++
}
func (n *BaseNode) ReplaceChild(self, v1, insertee Node) {
	n.InsertBefore(self, v1, insertee)
	n.RemoveChild(self, v1)
}
func (n *BaseNode) InsertAfter(self, v1, insertee Node) {
	n.InsertBefore(self, v1.NextSibling(), insertee)
}
func (n *BaseNode) InsertBefore(self, v1, insertee Node) {
	n.childCount++
	if v1 == nil {
		n.AppendChild(self, insertee)
		return
	}
	ensureIsolated(insertee)
	if v1.Parent() == self {
		c := v1
		prev := c.PreviousSibling()
		if prev != nil {
			prev.SetNextSibling(insertee)
			insertee.SetPreviousSibling(prev)
		} else {
			n.firstChild = insertee
			insertee.SetPreviousSibling(nil)
		}
		insertee.SetNextSibling(c)
		c.SetPreviousSibling(insertee)
		insertee.SetParent(self)
	}
}
func (n *BaseNode) OwnerDocument() *Document {
	d := n.Parent()
	for {
		p := d.Parent()
		if p == nil {
			if v, ok := d.(*Document); ok {
				return v
			}
			break
		}
		d = p
	}
	return nil
}
func (n *BaseNode) Text(source []byte) []byte {
	var buf bytes.Buffer
	for c := n.firstChild; c != nil; c = c.NextSibling() {
		buf.Write(c.Text(source))
	}
	return buf.Bytes()
}
func (n *BaseNode) SetAttribute(name []byte, value interface{}) {
	if n.attributes == nil {
		n.attributes = make([]Attribute, 0, 10)
	} else {
		for i, a := range n.attributes {
			if bytes.Equal(a.Name, name) {
				n.attributes[i].Name = name
				n.attributes[i].Value = value
				return
			}
		}
	}
	n.attributes = append(n.attributes, Attribute{name, value})
}
func (n *BaseNode) SetAttributeString(name string, value interface{}) {
	n.SetAttribute(util.StringToReadOnlyBytes(name), value)
}
func (n *BaseNode) Attribute(name []byte) (interface{}, bool) {
	if n.attributes == nil {
		return nil, false
	}
	for i, a := range n.attributes {
		if bytes.Equal(a.Name, name) {
			return n.attributes[i].Value, true
		}
	}
	return nil, false
}