diff options
| author | Mitja Felicijan <mitja.felicijan@gmail.com> | 2024-10-25 00:47:47 +0200 |
|---|---|---|
| committer | Mitja Felicijan <mitja.felicijan@gmail.com> | 2024-10-25 00:47:47 +0200 |
| commit | c6cc0108ca7738023b45e0eeac0fa2390532dd93 (patch) | |
| tree | 36890e6cd3091bbab8efbe686cc56f467f645bfd /vendor/github.com/yuin/goldmark/ast/ast.go | |
| parent | 0130404a1dc663d4aa68d780c9bcb23a4243e68d (diff) | |
| download | jbmafp-c6cc0108ca7738023b45e0eeac0fa2390532dd93.tar.gz | |
Diffstat (limited to 'vendor/github.com/yuin/goldmark/ast/ast.go')
| -rw-r--r-- | vendor/github.com/yuin/goldmark/ast/ast.go | 508 |
1 files changed, 508 insertions, 0 deletions
diff --git a/vendor/github.com/yuin/goldmark/ast/ast.go b/vendor/github.com/yuin/goldmark/ast/ast.go new file mode 100644 index 0000000..3719ebb --- /dev/null +++ b/vendor/github.com/yuin/goldmark/ast/ast.go | |||
| @@ -0,0 +1,508 @@ | |||
| 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 | } | ||
