gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

ast.go (13070B)


      1 // Package ast defines AST nodes that represent markdown elements.
      2 package ast
      3 
      4 import (
      5 	"bytes"
      6 	"fmt"
      7 	"strings"
      8 
      9 	textm "github.com/yuin/goldmark/text"
     10 	"github.com/yuin/goldmark/util"
     11 )
     12 
     13 // A NodeType indicates what type a node belongs to.
     14 type NodeType int
     15 
     16 const (
     17 	// TypeBlock indicates that a node is kind of block nodes.
     18 	TypeBlock NodeType = iota + 1
     19 	// TypeInline indicates that a node is kind of inline nodes.
     20 	TypeInline
     21 	// TypeDocument indicates that a node is kind of document nodes.
     22 	TypeDocument
     23 )
     24 
     25 // NodeKind indicates more specific type than NodeType.
     26 type NodeKind int
     27 
     28 func (k NodeKind) String() string {
     29 	return kindNames[k]
     30 }
     31 
     32 var kindMax NodeKind
     33 var kindNames = []string{""}
     34 
     35 // NewNodeKind returns a new Kind value.
     36 func NewNodeKind(name string) NodeKind {
     37 	kindMax++
     38 	kindNames = append(kindNames, name)
     39 	return kindMax
     40 }
     41 
     42 // An Attribute is an attribute of the Node
     43 type Attribute struct {
     44 	Name  []byte
     45 	Value interface{}
     46 }
     47 
     48 // A Node interface defines basic AST node functionalities.
     49 type Node interface {
     50 	// Type returns a type of this node.
     51 	Type() NodeType
     52 
     53 	// Kind returns a kind of this node.
     54 	Kind() NodeKind
     55 
     56 	// NextSibling returns a next sibling node of this node.
     57 	NextSibling() Node
     58 
     59 	// PreviousSibling returns a previous sibling node of this node.
     60 	PreviousSibling() Node
     61 
     62 	// Parent returns a parent node of this node.
     63 	Parent() Node
     64 
     65 	// SetParent sets a parent node to this node.
     66 	SetParent(Node)
     67 
     68 	// SetPreviousSibling sets a previous sibling node to this node.
     69 	SetPreviousSibling(Node)
     70 
     71 	// SetNextSibling sets a next sibling node to this node.
     72 	SetNextSibling(Node)
     73 
     74 	// HasChildren returns true if this node has any children, otherwise false.
     75 	HasChildren() bool
     76 
     77 	// ChildCount returns a total number of children.
     78 	ChildCount() int
     79 
     80 	// FirstChild returns a first child of this node.
     81 	FirstChild() Node
     82 
     83 	// LastChild returns a last child of this node.
     84 	LastChild() Node
     85 
     86 	// AppendChild append a node child to the tail of the children.
     87 	AppendChild(self, child Node)
     88 
     89 	// RemoveChild removes a node child from this node.
     90 	// If a node child is not children of this node, RemoveChild nothing to do.
     91 	RemoveChild(self, child Node)
     92 
     93 	// RemoveChildren removes all children from this node.
     94 	RemoveChildren(self Node)
     95 
     96 	// SortChildren sorts childrens by comparator.
     97 	SortChildren(comparator func(n1, n2 Node) int)
     98 
     99 	// ReplaceChild replace a node v1 with a node insertee.
    100 	// If v1 is not children of this node, ReplaceChild append a insetee to the
    101 	// tail of the children.
    102 	ReplaceChild(self, v1, insertee Node)
    103 
    104 	// InsertBefore inserts a node insertee before a node v1.
    105 	// If v1 is not children of this node, InsertBefore append a insetee to the
    106 	// tail of the children.
    107 	InsertBefore(self, v1, insertee Node)
    108 
    109 	// InsertAfterinserts a node insertee after a node v1.
    110 	// If v1 is not children of this node, InsertBefore append a insetee to the
    111 	// tail of the children.
    112 	InsertAfter(self, v1, insertee Node)
    113 
    114 	// OwnerDocument returns this node's owner document.
    115 	// If this node is not a child of the Document node, OwnerDocument
    116 	// returns nil.
    117 	OwnerDocument() *Document
    118 
    119 	// Dump dumps an AST tree structure to stdout.
    120 	// This function completely aimed for debugging.
    121 	// level is a indent level. Implementer should indent informations with
    122 	// 2 * level spaces.
    123 	Dump(source []byte, level int)
    124 
    125 	// Text returns text values of this node.
    126 	Text(source []byte) []byte
    127 
    128 	// HasBlankPreviousLines returns true if the row before this node is blank,
    129 	// otherwise false.
    130 	// This method is valid only for block nodes.
    131 	HasBlankPreviousLines() bool
    132 
    133 	// SetBlankPreviousLines sets whether the row before this node is blank.
    134 	// This method is valid only for block nodes.
    135 	SetBlankPreviousLines(v bool)
    136 
    137 	// Lines returns text segments that hold positions in a source.
    138 	// This method is valid only for block nodes.
    139 	Lines() *textm.Segments
    140 
    141 	// SetLines sets text segments that hold positions in a source.
    142 	// This method is valid only for block nodes.
    143 	SetLines(*textm.Segments)
    144 
    145 	// IsRaw returns true if contents should be rendered as 'raw' contents.
    146 	IsRaw() bool
    147 
    148 	// SetAttribute sets the given value to the attributes.
    149 	SetAttribute(name []byte, value interface{})
    150 
    151 	// SetAttributeString sets the given value to the attributes.
    152 	SetAttributeString(name string, value interface{})
    153 
    154 	// Attribute returns a (attribute value, true) if an attribute
    155 	// associated with the given name is found, otherwise
    156 	// (nil, false)
    157 	Attribute(name []byte) (interface{}, bool)
    158 
    159 	// AttributeString returns a (attribute value, true) if an attribute
    160 	// associated with the given name is found, otherwise
    161 	// (nil, false)
    162 	AttributeString(name string) (interface{}, bool)
    163 
    164 	// Attributes returns a list of attributes.
    165 	// This may be a nil if there are no attributes.
    166 	Attributes() []Attribute
    167 
    168 	// RemoveAttributes removes all attributes from this node.
    169 	RemoveAttributes()
    170 }
    171 
    172 // A BaseNode struct implements the Node interface partialliy.
    173 type BaseNode struct {
    174 	firstChild Node
    175 	lastChild  Node
    176 	parent     Node
    177 	next       Node
    178 	prev       Node
    179 	childCount int
    180 	attributes []Attribute
    181 }
    182 
    183 func ensureIsolated(v Node) {
    184 	if p := v.Parent(); p != nil {
    185 		p.RemoveChild(p, v)
    186 	}
    187 }
    188 
    189 // HasChildren implements Node.HasChildren .
    190 func (n *BaseNode) HasChildren() bool {
    191 	return n.firstChild != nil
    192 }
    193 
    194 // SetPreviousSibling implements Node.SetPreviousSibling .
    195 func (n *BaseNode) SetPreviousSibling(v Node) {
    196 	n.prev = v
    197 }
    198 
    199 // SetNextSibling implements Node.SetNextSibling .
    200 func (n *BaseNode) SetNextSibling(v Node) {
    201 	n.next = v
    202 }
    203 
    204 // PreviousSibling implements Node.PreviousSibling .
    205 func (n *BaseNode) PreviousSibling() Node {
    206 	return n.prev
    207 }
    208 
    209 // NextSibling implements Node.NextSibling .
    210 func (n *BaseNode) NextSibling() Node {
    211 	return n.next
    212 }
    213 
    214 // RemoveChild implements Node.RemoveChild .
    215 func (n *BaseNode) RemoveChild(self, v Node) {
    216 	if v.Parent() != self {
    217 		return
    218 	}
    219 	n.childCount--
    220 	prev := v.PreviousSibling()
    221 	next := v.NextSibling()
    222 	if prev != nil {
    223 		prev.SetNextSibling(next)
    224 	} else {
    225 		n.firstChild = next
    226 	}
    227 	if next != nil {
    228 		next.SetPreviousSibling(prev)
    229 	} else {
    230 		n.lastChild = prev
    231 	}
    232 	v.SetParent(nil)
    233 	v.SetPreviousSibling(nil)
    234 	v.SetNextSibling(nil)
    235 }
    236 
    237 // RemoveChildren implements Node.RemoveChildren .
    238 func (n *BaseNode) RemoveChildren(self Node) {
    239 	for c := n.firstChild; c != nil; {
    240 		c.SetParent(nil)
    241 		c.SetPreviousSibling(nil)
    242 		next := c.NextSibling()
    243 		c.SetNextSibling(nil)
    244 		c = next
    245 	}
    246 	n.firstChild = nil
    247 	n.lastChild = nil
    248 	n.childCount = 0
    249 }
    250 
    251 // SortChildren implements Node.SortChildren
    252 func (n *BaseNode) SortChildren(comparator func(n1, n2 Node) int) {
    253 	var sorted Node
    254 	current := n.firstChild
    255 	for current != nil {
    256 		next := current.NextSibling()
    257 		if sorted == nil || comparator(sorted, current) >= 0 {
    258 			current.SetNextSibling(sorted)
    259 			if sorted != nil {
    260 				sorted.SetPreviousSibling(current)
    261 			}
    262 			sorted = current
    263 			sorted.SetPreviousSibling(nil)
    264 		} else {
    265 			c := sorted
    266 			for c.NextSibling() != nil && comparator(c.NextSibling(), current) < 0 {
    267 				c = c.NextSibling()
    268 			}
    269 			current.SetNextSibling(c.NextSibling())
    270 			current.SetPreviousSibling(c)
    271 			if c.NextSibling() != nil {
    272 				c.NextSibling().SetPreviousSibling(current)
    273 			}
    274 			c.SetNextSibling(current)
    275 		}
    276 		current = next
    277 	}
    278 	n.firstChild = sorted
    279 	for c := n.firstChild; c != nil; c = c.NextSibling() {
    280 		n.lastChild = c
    281 	}
    282 }
    283 
    284 // FirstChild implements Node.FirstChild .
    285 func (n *BaseNode) FirstChild() Node {
    286 	return n.firstChild
    287 }
    288 
    289 // LastChild implements Node.LastChild .
    290 func (n *BaseNode) LastChild() Node {
    291 	return n.lastChild
    292 }
    293 
    294 // ChildCount implements Node.ChildCount .
    295 func (n *BaseNode) ChildCount() int {
    296 	return n.childCount
    297 }
    298 
    299 // Parent implements Node.Parent .
    300 func (n *BaseNode) Parent() Node {
    301 	return n.parent
    302 }
    303 
    304 // SetParent implements Node.SetParent .
    305 func (n *BaseNode) SetParent(v Node) {
    306 	n.parent = v
    307 }
    308 
    309 // AppendChild implements Node.AppendChild .
    310 func (n *BaseNode) AppendChild(self, v Node) {
    311 	ensureIsolated(v)
    312 	if n.firstChild == nil {
    313 		n.firstChild = v
    314 		v.SetNextSibling(nil)
    315 		v.SetPreviousSibling(nil)
    316 	} else {
    317 		last := n.lastChild
    318 		last.SetNextSibling(v)
    319 		v.SetPreviousSibling(last)
    320 	}
    321 	v.SetParent(self)
    322 	n.lastChild = v
    323 	n.childCount++
    324 }
    325 
    326 // ReplaceChild implements Node.ReplaceChild .
    327 func (n *BaseNode) ReplaceChild(self, v1, insertee Node) {
    328 	n.InsertBefore(self, v1, insertee)
    329 	n.RemoveChild(self, v1)
    330 }
    331 
    332 // InsertAfter implements Node.InsertAfter .
    333 func (n *BaseNode) InsertAfter(self, v1, insertee Node) {
    334 	n.InsertBefore(self, v1.NextSibling(), insertee)
    335 }
    336 
    337 // InsertBefore implements Node.InsertBefore .
    338 func (n *BaseNode) InsertBefore(self, v1, insertee Node) {
    339 	n.childCount++
    340 	if v1 == nil {
    341 		n.AppendChild(self, insertee)
    342 		return
    343 	}
    344 	ensureIsolated(insertee)
    345 	if v1.Parent() == self {
    346 		c := v1
    347 		prev := c.PreviousSibling()
    348 		if prev != nil {
    349 			prev.SetNextSibling(insertee)
    350 			insertee.SetPreviousSibling(prev)
    351 		} else {
    352 			n.firstChild = insertee
    353 			insertee.SetPreviousSibling(nil)
    354 		}
    355 		insertee.SetNextSibling(c)
    356 		c.SetPreviousSibling(insertee)
    357 		insertee.SetParent(self)
    358 	}
    359 }
    360 
    361 // OwnerDocument implements Node.OwnerDocument
    362 func (n *BaseNode) OwnerDocument() *Document {
    363 	d := n.Parent()
    364 	for {
    365 		p := d.Parent()
    366 		if p == nil {
    367 			if v, ok := d.(*Document); ok {
    368 				return v
    369 			}
    370 			break
    371 		}
    372 		d = p
    373 	}
    374 	return nil
    375 }
    376 
    377 // Text implements Node.Text  .
    378 func (n *BaseNode) Text(source []byte) []byte {
    379 	var buf bytes.Buffer
    380 	for c := n.firstChild; c != nil; c = c.NextSibling() {
    381 		buf.Write(c.Text(source))
    382 	}
    383 	return buf.Bytes()
    384 }
    385 
    386 // SetAttribute implements Node.SetAttribute.
    387 func (n *BaseNode) SetAttribute(name []byte, value interface{}) {
    388 	if n.attributes == nil {
    389 		n.attributes = make([]Attribute, 0, 10)
    390 	} else {
    391 		for i, a := range n.attributes {
    392 			if bytes.Equal(a.Name, name) {
    393 				n.attributes[i].Name = name
    394 				n.attributes[i].Value = value
    395 				return
    396 			}
    397 		}
    398 	}
    399 	n.attributes = append(n.attributes, Attribute{name, value})
    400 }
    401 
    402 // SetAttributeString implements Node.SetAttributeString
    403 func (n *BaseNode) SetAttributeString(name string, value interface{}) {
    404 	n.SetAttribute(util.StringToReadOnlyBytes(name), value)
    405 }
    406 
    407 // Attribute implements Node.Attribute.
    408 func (n *BaseNode) Attribute(name []byte) (interface{}, bool) {
    409 	if n.attributes == nil {
    410 		return nil, false
    411 	}
    412 	for i, a := range n.attributes {
    413 		if bytes.Equal(a.Name, name) {
    414 			return n.attributes[i].Value, true
    415 		}
    416 	}
    417 	return nil, false
    418 }
    419 
    420 // AttributeString implements Node.AttributeString.
    421 func (n *BaseNode) AttributeString(s string) (interface{}, bool) {
    422 	return n.Attribute(util.StringToReadOnlyBytes(s))
    423 }
    424 
    425 // Attributes implements Node.Attributes
    426 func (n *BaseNode) Attributes() []Attribute {
    427 	return n.attributes
    428 }
    429 
    430 // RemoveAttributes implements Node.RemoveAttributes
    431 func (n *BaseNode) RemoveAttributes() {
    432 	n.attributes = nil
    433 }
    434 
    435 // DumpHelper is a helper function to implement Node.Dump.
    436 // kv is pairs of an attribute name and an attribute value.
    437 // cb is a function called after wrote a name and attributes.
    438 func DumpHelper(v Node, source []byte, level int, kv map[string]string, cb func(int)) {
    439 	name := v.Kind().String()
    440 	indent := strings.Repeat("    ", level)
    441 	fmt.Printf("%s%s {\n", indent, name)
    442 	indent2 := strings.Repeat("    ", level+1)
    443 	if v.Type() == TypeBlock {
    444 		fmt.Printf("%sRawText: \"", indent2)
    445 		for i := 0; i < v.Lines().Len(); i++ {
    446 			line := v.Lines().At(i)
    447 			fmt.Printf("%s", line.Value(source))
    448 		}
    449 		fmt.Printf("\"\n")
    450 		fmt.Printf("%sHasBlankPreviousLines: %v\n", indent2, v.HasBlankPreviousLines())
    451 	}
    452 	for name, value := range kv {
    453 		fmt.Printf("%s%s: %s\n", indent2, name, value)
    454 	}
    455 	if cb != nil {
    456 		cb(level + 1)
    457 	}
    458 	for c := v.FirstChild(); c != nil; c = c.NextSibling() {
    459 		c.Dump(source, level+1)
    460 	}
    461 	fmt.Printf("%s}\n", indent)
    462 }
    463 
    464 // WalkStatus represents a current status of the Walk function.
    465 type WalkStatus int
    466 
    467 const (
    468 	// WalkStop indicates no more walking needed.
    469 	WalkStop WalkStatus = iota + 1
    470 
    471 	// WalkSkipChildren indicates that Walk wont walk on children of current
    472 	// node.
    473 	WalkSkipChildren
    474 
    475 	// WalkContinue indicates that Walk can continue to walk.
    476 	WalkContinue
    477 )
    478 
    479 // Walker is a function that will be called when Walk find a
    480 // new node.
    481 // entering is set true before walks children, false after walked children.
    482 // If Walker returns error, Walk function immediately stop walking.
    483 type Walker func(n Node, entering bool) (WalkStatus, error)
    484 
    485 // Walk walks a AST tree by the depth first search algorithm.
    486 func Walk(n Node, walker Walker) error {
    487 	_, err := walkHelper(n, walker)
    488 	return err
    489 }
    490 
    491 func walkHelper(n Node, walker Walker) (WalkStatus, error) {
    492 	status, err := walker(n, true)
    493 	if err != nil || status == WalkStop {
    494 		return status, err
    495 	}
    496 	if status != WalkSkipChildren {
    497 		for c := n.FirstChild(); c != nil; c = c.NextSibling() {
    498 			if st, err := walkHelper(c, walker); err != nil || st == WalkStop {
    499 				return WalkStop, err
    500 			}
    501 		}
    502 	}
    503 	status, err = walker(n, false)
    504 	if err != nil || status == WalkStop {
    505 		return WalkStop, err
    506 	}
    507 	return WalkContinue, nil
    508 }