0
# AST Node System
1
2
Comprehensive node hierarchy representing all CommonMark elements including blocks, inlines, and document structure. The AST (Abstract Syntax Tree) provides a structured representation of parsed Markdown documents with full support for tree traversal, manipulation, and the visitor pattern.
3
4
## Capabilities
5
6
### Base Node Classes
7
8
Core abstract classes that form the foundation of the AST hierarchy.
9
10
```java { .api }
11
/**
12
* Base class for all CommonMark AST nodes
13
*/
14
public abstract class Node {
15
/**
16
* Accept a visitor (visitor pattern implementation)
17
* @param visitor the visitor to accept
18
*/
19
public abstract void accept(Visitor visitor);
20
21
/**
22
* Get the next sibling node
23
* @return the next sibling, or null if this is the last child
24
*/
25
public Node getNext();
26
27
/**
28
* Get the previous sibling node
29
* @return the previous sibling, or null if this is the first child
30
*/
31
public Node getPrevious();
32
33
/**
34
* Get the first child node
35
* @return the first child, or null if no children
36
*/
37
public Node getFirstChild();
38
39
/**
40
* Get the last child node
41
* @return the last child, or null if no children
42
*/
43
public Node getLastChild();
44
45
/**
46
* Get the parent node
47
* @return the parent node, or null if this is the root
48
*/
49
public Node getParent();
50
51
/**
52
* Append a child node to this node
53
* @param child the child node to append
54
*/
55
public void appendChild(Node child);
56
57
/**
58
* Prepend a child node to this node
59
* @param child the child node to prepend
60
*/
61
public void prependChild(Node child);
62
63
/**
64
* Remove this node from its parent
65
*/
66
public void unlink();
67
68
/**
69
* Insert this node after the specified sibling
70
* @param sibling the sibling to insert after
71
*/
72
public void insertAfter(Node sibling);
73
74
/**
75
* Insert this node before the specified sibling
76
* @param sibling the sibling to insert before
77
*/
78
public void insertBefore(Node sibling);
79
80
/**
81
* Get source spans for this node (available since 0.16.0)
82
* @return list of source spans, empty if not included by parser
83
*/
84
public List<SourceSpan> getSourceSpans();
85
86
/**
87
* Replace current source spans with provided list (available since 0.16.0)
88
* @param sourceSpans the new source spans to set
89
*/
90
public void setSourceSpans(List<SourceSpan> sourceSpans);
91
92
/**
93
* Add a source span to the end of the list (available since 0.16.0)
94
* @param sourceSpan the source span to add
95
*/
96
public void addSourceSpan(SourceSpan sourceSpan);
97
}
98
99
/**
100
* Base class for block-level nodes
101
*/
102
public abstract class Block extends Node {
103
/**
104
* Get the parent block (overridden for type safety)
105
* @return the parent block
106
*/
107
public Block getParent();
108
}
109
```
110
111
### Document Structure Nodes
112
113
Nodes representing the overall document structure and major organizational elements.
114
115
```java { .api }
116
/**
117
* Root document node - the top level of any parsed document
118
*/
119
public class Document extends Block {
120
public void accept(Visitor visitor);
121
}
122
123
/**
124
* Heading nodes (# ## ### etc.)
125
*/
126
public class Heading extends Block {
127
/**
128
* Get the heading level (1-6)
129
* @return the heading level
130
*/
131
public int getLevel();
132
133
/**
134
* Set the heading level
135
* @param level the heading level (1-6)
136
*/
137
public void setLevel(int level);
138
139
public void accept(Visitor visitor);
140
}
141
142
/**
143
* Paragraph blocks
144
*/
145
public class Paragraph extends Block {
146
public void accept(Visitor visitor);
147
}
148
149
/**
150
* Block quotes (> text)
151
*/
152
public class BlockQuote extends Block {
153
public void accept(Visitor visitor);
154
}
155
156
/**
157
* Horizontal rules (---, ***, ___)
158
*/
159
public class ThematicBreak extends Block {
160
public void accept(Visitor visitor);
161
}
162
```
163
164
### Code Block Nodes
165
166
Nodes representing different types of code blocks in Markdown.
167
168
```java { .api }
169
/**
170
* Fenced code blocks (``` code ```)
171
*/
172
public class FencedCodeBlock extends Block {
173
/**
174
* Get the fence character (` or ~)
175
* @return the fence character
176
*/
177
public char getFenceChar();
178
179
/**
180
* Set the fence character
181
* @param fenceChar the fence character
182
*/
183
public void setFenceChar(char fenceChar);
184
185
/**
186
* Get the fence length (number of fence characters)
187
* @return the fence length
188
*/
189
public int getFenceLength();
190
191
/**
192
* Set the fence length
193
* @param fenceLength the fence length
194
*/
195
public void setFenceLength(int fenceLength);
196
197
/**
198
* Get the fence indentation
199
* @return the fence indentation
200
*/
201
public int getFenceIndent();
202
203
/**
204
* Set the fence indentation
205
* @param fenceIndent the fence indentation
206
*/
207
public void setFenceIndent(int fenceIndent);
208
209
/**
210
* Get the info string (language identifier)
211
* @return the info string, or null if not specified
212
*/
213
public String getInfo();
214
215
/**
216
* Set the info string
217
* @param info the info string
218
*/
219
public void setInfo(String info);
220
221
/**
222
* Get the literal code content
223
* @return the code content
224
*/
225
public String getLiteral();
226
227
/**
228
* Set the literal code content
229
* @param literal the code content
230
*/
231
public void setLiteral(String literal);
232
233
public void accept(Visitor visitor);
234
}
235
236
/**
237
* Indented code blocks (4+ spaces)
238
*/
239
public class IndentedCodeBlock extends Block {
240
/**
241
* Get the literal code content
242
* @return the code content
243
*/
244
public String getLiteral();
245
246
/**
247
* Set the literal code content
248
* @param literal the code content
249
*/
250
public void setLiteral(String literal);
251
252
public void accept(Visitor visitor);
253
}
254
```
255
256
### List Nodes
257
258
Nodes representing list structures and list items.
259
260
```java { .api }
261
/**
262
* Base class for list blocks (ordered and unordered)
263
*/
264
public abstract class ListBlock extends Block {
265
// Base class for BulletList and OrderedList
266
}
267
268
/**
269
* Unordered lists (*, -, +)
270
*/
271
public class BulletList extends ListBlock {
272
/**
273
* Get the bullet marker character
274
* @return the bullet marker (*, -, or +)
275
*/
276
public char getBulletMarker();
277
278
/**
279
* Set the bullet marker character
280
* @param bulletMarker the bullet marker
281
*/
282
public void setBulletMarker(char bulletMarker);
283
284
public void accept(Visitor visitor);
285
}
286
287
/**
288
* Ordered lists (1. 2. 3.)
289
*/
290
public class OrderedList extends ListBlock {
291
/**
292
* Get the starting number
293
* @return the starting number
294
*/
295
public int getStartNumber();
296
297
/**
298
* Set the starting number
299
* @param startNumber the starting number
300
*/
301
public void setStartNumber(int startNumber);
302
303
/**
304
* Get the delimiter character (. or ))
305
* @return the delimiter character
306
*/
307
public char getDelimiter();
308
309
/**
310
* Set the delimiter character
311
* @param delimiter the delimiter character
312
*/
313
public void setDelimiter(char delimiter);
314
315
public void accept(Visitor visitor);
316
}
317
318
/**
319
* Individual list items
320
*/
321
public class ListItem extends Block {
322
public void accept(Visitor visitor);
323
}
324
```
325
326
### Inline Nodes
327
328
Nodes representing inline elements within blocks.
329
330
```java { .api }
331
/**
332
* Plain text nodes
333
*/
334
public class Text extends Node {
335
/**
336
* Create an empty text node
337
*/
338
public Text();
339
340
/**
341
* Create a text node with the given literal content
342
* @param literal the text content
343
*/
344
public Text(String literal);
345
346
/**
347
* Get the literal text content
348
* @return the text content
349
*/
350
public String getLiteral();
351
352
/**
353
* Set the literal text content
354
* @param literal the text content
355
*/
356
public void setLiteral(String literal);
357
358
public void accept(Visitor visitor);
359
}
360
361
/**
362
* Inline code (`code`)
363
*/
364
public class Code extends Node {
365
/**
366
* Get the literal code content
367
* @return the code content
368
*/
369
public String getLiteral();
370
371
/**
372
* Set the literal code content
373
* @param literal the code content
374
*/
375
public void setLiteral(String literal);
376
377
public void accept(Visitor visitor);
378
}
379
380
/**
381
* Interface for nodes with delimiters (emphasis, strong emphasis)
382
*/
383
public interface Delimited {
384
/**
385
* Get the opening delimiter
386
* @return the opening delimiter string
387
*/
388
String getOpeningDelimiter();
389
390
/**
391
* Get the closing delimiter
392
* @return the closing delimiter string
393
*/
394
String getClosingDelimiter();
395
}
396
397
/**
398
* Italic text (*text* or _text_)
399
*/
400
public class Emphasis extends Node implements Delimited {
401
/**
402
* Create an empty emphasis node
403
*/
404
public Emphasis();
405
406
/**
407
* Create an emphasis node with the given delimiter
408
* @param delimiter the delimiter string (* or _)
409
*/
410
public Emphasis(String delimiter);
411
412
/**
413
* Get the opening delimiter
414
* @return the opening delimiter
415
*/
416
public String getOpeningDelimiter();
417
418
/**
419
* Get the closing delimiter
420
* @return the closing delimiter
421
*/
422
public String getClosingDelimiter();
423
424
/**
425
* Set the delimiter for both opening and closing
426
* @param delimiter the delimiter string
427
*/
428
public void setDelimiter(String delimiter);
429
430
public void accept(Visitor visitor);
431
}
432
433
/**
434
* Bold text (**text** or __text__)
435
*/
436
public class StrongEmphasis extends Node implements Delimited {
437
/**
438
* Create an empty strong emphasis node
439
*/
440
public StrongEmphasis();
441
442
/**
443
* Create a strong emphasis node with the given delimiter
444
* @param delimiter the delimiter string (** or __)
445
*/
446
public StrongEmphasis(String delimiter);
447
448
/**
449
* Get the opening delimiter
450
* @return the opening delimiter
451
*/
452
public String getOpeningDelimiter();
453
454
/**
455
* Get the closing delimiter
456
* @return the closing delimiter
457
*/
458
public String getClosingDelimiter();
459
460
/**
461
* Set the delimiter for both opening and closing
462
* @param delimiter the delimiter string
463
*/
464
public void setDelimiter(String delimiter);
465
466
public void accept(Visitor visitor);
467
}
468
```
469
470
### Link and Image Nodes
471
472
Nodes representing links and images with destinations and titles.
473
474
```java { .api }
475
/**
476
* Links [text](url "title")
477
*/
478
public class Link extends Node {
479
/**
480
* Create an empty link
481
*/
482
public Link();
483
484
/**
485
* Create a link with destination and title
486
* @param destination the link destination
487
* @param title the link title (may be null)
488
*/
489
public Link(String destination, String title);
490
491
/**
492
* Get the link destination
493
* @return the destination URL
494
*/
495
public String getDestination();
496
497
/**
498
* Set the link destination
499
* @param destination the destination URL
500
*/
501
public void setDestination(String destination);
502
503
/**
504
* Get the link title
505
* @return the title, or null if not specified
506
*/
507
public String getTitle();
508
509
/**
510
* Set the link title
511
* @param title the title
512
*/
513
public void setTitle(String title);
514
515
public void accept(Visitor visitor);
516
}
517
518
/**
519
* Images 
520
*/
521
public class Image extends Node {
522
/**
523
* Create an empty image
524
*/
525
public Image();
526
527
/**
528
* Create an image with destination and title
529
* @param destination the image source
530
* @param title the image title (may be null)
531
*/
532
public Image(String destination, String title);
533
534
/**
535
* Get the image destination (src)
536
* @return the image source URL
537
*/
538
public String getDestination();
539
540
/**
541
* Set the image destination
542
* @param destination the image source URL
543
*/
544
public void setDestination(String destination);
545
546
/**
547
* Get the image title
548
* @return the title, or null if not specified
549
*/
550
public String getTitle();
551
552
/**
553
* Set the image title
554
* @param title the title
555
*/
556
public void setTitle(String title);
557
558
public void accept(Visitor visitor);
559
}
560
561
/**
562
* Link reference definitions [label]: url "title"
563
*/
564
public class LinkReferenceDefinition extends Node {
565
/**
566
* Get the reference label
567
* @return the label
568
*/
569
public String getLabel();
570
571
/**
572
* Set the reference label
573
* @param label the label
574
*/
575
public void setLabel(String label);
576
577
/**
578
* Get the destination URL
579
* @return the destination
580
*/
581
public String getDestination();
582
583
/**
584
* Set the destination URL
585
* @param destination the destination
586
*/
587
public void setDestination(String destination);
588
589
/**
590
* Get the title
591
* @return the title, or null if not specified
592
*/
593
public String getTitle();
594
595
/**
596
* Set the title
597
* @param title the title
598
*/
599
public void setTitle(String title);
600
601
public void accept(Visitor visitor);
602
}
603
```
604
605
### HTML and Line Break Nodes
606
607
Nodes representing HTML content and line breaks.
608
609
```java { .api }
610
/**
611
* HTML block elements
612
*/
613
public class HtmlBlock extends Block {
614
/**
615
* Get the literal HTML content
616
* @return the HTML content
617
*/
618
public String getLiteral();
619
620
/**
621
* Set the literal HTML content
622
* @param literal the HTML content
623
*/
624
public void setLiteral(String literal);
625
626
public void accept(Visitor visitor);
627
}
628
629
/**
630
* Inline HTML elements
631
*/
632
public class HtmlInline extends Node {
633
/**
634
* Get the literal HTML content
635
* @return the HTML content
636
*/
637
public String getLiteral();
638
639
/**
640
* Set the literal HTML content
641
* @param literal the HTML content
642
*/
643
public void setLiteral(String literal);
644
645
public void accept(Visitor visitor);
646
}
647
648
/**
649
* Soft line breaks (newlines in text)
650
*/
651
public class SoftLineBreak extends Node {
652
public void accept(Visitor visitor);
653
}
654
655
/**
656
* Hard line breaks ( \n or \)
657
*/
658
public class HardLineBreak extends Node {
659
public void accept(Visitor visitor);
660
}
661
```
662
663
### Visitor Pattern Support
664
665
Interfaces and classes for traversing and processing AST nodes.
666
667
```java { .api }
668
/**
669
* Visitor pattern interface for traversing AST nodes
670
*/
671
public interface Visitor {
672
void visit(Document document);
673
void visit(Heading heading);
674
void visit(Paragraph paragraph);
675
void visit(BlockQuote blockQuote);
676
void visit(BulletList bulletList);
677
void visit(OrderedList orderedList);
678
void visit(ListItem listItem);
679
void visit(FencedCodeBlock fencedCodeBlock);
680
void visit(IndentedCodeBlock indentedCodeBlock);
681
void visit(HtmlBlock htmlBlock);
682
void visit(ThematicBreak thematicBreak);
683
void visit(Text text);
684
void visit(Code code);
685
void visit(Emphasis emphasis);
686
void visit(StrongEmphasis strongEmphasis);
687
void visit(Link link);
688
void visit(Image image);
689
void visit(HtmlInline htmlInline);
690
void visit(SoftLineBreak softLineBreak);
691
void visit(HardLineBreak hardLineBreak);
692
void visit(LinkReferenceDefinition linkReferenceDefinition);
693
void visit(CustomBlock customBlock);
694
void visit(CustomNode customNode);
695
}
696
697
/**
698
* Abstract visitor that visits all children by default.
699
* Provides default implementations of all visit methods that call visitChildren.
700
* Override specific visit methods to customize behavior for particular node types.
701
*/
702
public abstract class AbstractVisitor implements Visitor {
703
/**
704
* Visit all children of the given parent node.
705
* This method is called by all default visit method implementations.
706
* Override specific visit methods and call visitChildren if you want to continue traversal.
707
*
708
* @param parent the parent node whose children to visit
709
*/
710
protected void visitChildren(Node parent);
711
712
// Default implementations for all visit methods in Visitor interface:
713
// public void visit(Document document) { visitChildren(document); }
714
// public void visit(Heading heading) { visitChildren(heading); }
715
// ... and so on for all node types
716
}
717
```
718
719
### Custom Node Support
720
721
Base classes for creating custom node types in extensions.
722
723
```java { .api }
724
/**
725
* Base class for custom inline nodes
726
*/
727
public abstract class CustomNode extends Node {
728
// Base class for creating custom inline node types
729
}
730
731
/**
732
* Base class for custom block nodes
733
*/
734
public abstract class CustomBlock extends Block {
735
// Base class for creating custom block node types
736
}
737
```
738
739
### Utility Classes
740
741
Helper classes for working with nodes and collections of nodes.
742
743
```java { .api }
744
/**
745
* Utility class for working with multiple nodes
746
*/
747
public class Nodes {
748
/**
749
* Get all nodes between start and end (exclusive)
750
* @param start the starting node
751
* @param end the ending node
752
* @return iterable of nodes between start and end
753
*/
754
public static Iterable<Node> between(Node start, Node end);
755
}
756
```
757
758
**Usage Examples:**
759
760
```java
761
import org.commonmark.node.*;
762
import org.commonmark.parser.Parser;
763
764
// Parse and traverse AST
765
Parser parser = Parser.builder().build();
766
Node document = parser.parse("# Title\n\nHello **world**!");
767
768
// Using visitor pattern
769
document.accept(new AbstractVisitor() {
770
@Override
771
public void visit(Heading heading) {
772
System.out.println("Found heading level " + heading.getLevel());
773
super.visit(heading);
774
}
775
776
@Override
777
public void visit(StrongEmphasis strongEmphasis) {
778
System.out.println("Found bold text");
779
super.visit(strongEmphasis);
780
}
781
});
782
783
// Manual tree traversal
784
Node child = document.getFirstChild();
785
while (child != null) {
786
System.out.println("Child node: " + child.getClass().getSimpleName());
787
child = child.getNext();
788
}
789
790
// Modify AST - add a new paragraph
791
Paragraph newParagraph = new Paragraph();
792
Text text = new Text("This is a new paragraph.");
793
newParagraph.appendChild(text);
794
document.appendChild(newParagraph);
795
796
// Create links programmatically
797
Link link = new Link("https://example.com", "Example Site");
798
link.appendChild(new Text("Visit our site"));
799
```