v2 / vlib / x / markdown / node.v
118 lines · 110 sloc · 2.2 KB · 3094cf12ec589dd1a0c63b37010c156c581dd373
Raw
1// Copyright 2026 The V Language. All rights reserved.
2// Use of this source code is governed by an MIT license
3// that can be found in the LICENSE file.
4module markdown
5
6import strings
7
8// NodeKind identifies what kind of AST node a Node represents.
9pub enum NodeKind {
10 document
11 heading
12 paragraph
13 blockquote
14 list
15 list_item
16 code_block
17 fenced_code
18 thematic_break
19 html_block
20 link_ref_def
21 table
22 table_head
23 table_body
24 table_row
25 table_cell
26 definition_list
27 definition_term
28 definition_desc
29 footnote_def
30 text
31 emphasis
32 strong
33 code_span
34 link
35 image
36 autolink
37 raw_html
38 hard_break
39 soft_break
40 strikethrough
41 footnote_ref
42 task_checkbox
43}
44
45// Alignment is the text alignment of a table cell column.
46pub enum Alignment {
47 none_
48 left
49 center
50 right
51}
52
53// Node is a node in the parsed markdown AST.
54// A document is a tree of Nodes with .document as the root.
55@[heap]
56pub struct Node {
57pub mut:
58 kind NodeKind
59 level int
60 is_tight bool
61 is_ordered bool
62 list_start int = 1
63 fence_info string
64 literal string
65 dest string
66 title string
67 label string
68 checked bool
69 align Alignment
70 id string
71 fn_label string
72 fn_index int
73 children []&Node
74}
75
76// new_node allocates and returns a new Node of the given kind.
77pub fn new_node(kind NodeKind) &Node {
78 return &Node{
79 kind: kind
80 }
81}
82
83// append_child appends child as the last child of n.
84pub fn (mut n Node) append_child(child &Node) {
85 n.children << child
86}
87
88// text_content returns the plain-text content of this node and all descendants,
89// concatenated in document order.
90pub fn (n &Node) text_content() string {
91 match n.kind {
92 .text, .code_span, .raw_html {
93 return n.literal
94 }
95 else {
96 mut sb := strings.new_builder(64)
97 for child in n.children {
98 sb.write_string(child.text_content())
99 }
100 return sb.str()
101 }
102 }
103}
104
105// walk traverses n and all its descendants in pre-order (root before children).
106// The callback f receives each node; return false from f to stop traversal early.
107// walk itself returns false if traversal was stopped, true otherwise.
108pub fn (n &Node) walk(f fn (&Node) bool) bool {
109 if !f(n) {
110 return false
111 }
112 for child in n.children {
113 if !child.walk(f) {
114 return false
115 }
116 }
117 return true
118}
119