@@ -87,42 +87,8 @@ void visit(Node node) {
8787 case Paragraph paragraph -> addSpan (paragraph , PARAGRAPH_OPEN_TOKEN , PARAGRAPH_CLOSE_TOKEN );
8888 case BulletList bulletList -> addSpan (bulletList , LIST_OPEN_TOKEN , LIST_CLOSE_TOKEN );
8989 case OrderedList orderedList -> addSpan (orderedList , LIST_OPEN_TOKEN , LIST_CLOSE_TOKEN );
90- case ListItem listItem -> {
91- int startPosition = listItem .getSourceSpans ().getFirst ().getInputIndex ();
92- Matcher matcher =
93- LIST_ITEM_START_PATTERN .matcher (input ).region (startPosition , input .length ());
94- verify (matcher .lookingAt ());
95- ListItemOpenTag openToken = new ListItemOpenTag (matcher .group (1 ));
96- addSpan (listItem , openToken , LIST_ITEM_CLOSE_TOKEN );
97- if (listItem .getFirstChild () instanceof Paragraph paragraph ) {
98- // A ListItem typically contains a Paragraph, but we don't want to visit that Paragraph
99- // because that would lead us to introduce a line break after the list introduction
100- // (the `-` or whatever). So we visit the children and siblings of the Paragraph
101- // instead.
102- alreadyVisitedChildren = true ;
103- visitNodeList (paragraph .getFirstChild ());
104- visitNodeList (paragraph .getNext ());
105- }
106- }
107- case FencedCodeBlock fencedCodeBlock -> {
108- // Any indentation before the code block is part of FencedCodeBlock. This makes sense
109- // because the lines inside the code block must also be indented by that amount. That
110- // indentation gets subtracted from FencedCodeBlock.getLiteral(), which is the actual text
111- // represented by the code block.
112- int start = startPosition (fencedCodeBlock ) + fencedCodeBlock .getFenceIndent ();
113- MarkdownFencedCodeBlock token =
114- new MarkdownFencedCodeBlock (
115- input .substring (start , endPosition (fencedCodeBlock )),
116- fencedCodeBlock
117- .getFenceCharacter ()
118- .repeat (fencedCodeBlock .getOpeningFenceLength ())
119- + fencedCodeBlock .getInfo (),
120- fencedCodeBlock
121- .getFenceCharacter ()
122- .repeat (fencedCodeBlock .getClosingFenceLength ()),
123- fencedCodeBlock .getLiteral ());
124- positionToToken .get (start ).addLast (token );
125- }
90+ case ListItem listItem -> alreadyVisitedChildren = visitListItem (listItem );
91+ case FencedCodeBlock fencedCodeBlock -> visitFencedCodeBlock (fencedCodeBlock );
12692 // TODO: others
12793 default -> {}
12894 }
@@ -131,6 +97,43 @@ void visit(Node node) {
13197 }
13298 }
13399
100+ // Returns true if this method visited the children of the given ListItem.
101+ private boolean visitListItem (ListItem listItem ) {
102+ int startPosition = listItem .getSourceSpans ().getFirst ().getInputIndex ();
103+ Matcher matcher =
104+ LIST_ITEM_START_PATTERN .matcher (input ).region (startPosition , input .length ());
105+ verify (matcher .lookingAt ());
106+ ListItemOpenTag openToken = new ListItemOpenTag (matcher .group (1 ));
107+ addSpan (listItem , openToken , LIST_ITEM_CLOSE_TOKEN );
108+ return switch (listItem .getFirstChild ()) {
109+ case Paragraph paragraph -> {
110+ // A ListItem typically contains a Paragraph, but we don't want to visit that Paragraph
111+ // because that would lead us to introduce a line break after the list introduction
112+ // (the `-` or whatever). So we visit the children and siblings of the Paragraph instead.
113+ visitNodeList (paragraph .getFirstChild ());
114+ visitNodeList (paragraph .getNext ());
115+ yield true ;
116+ }
117+ default -> false ;
118+ };
119+ }
120+
121+ private void visitFencedCodeBlock (FencedCodeBlock fencedCodeBlock ) {
122+ // Any indentation before the code block is part of FencedCodeBlock. This makes sense
123+ // because the lines inside the code block must also be indented by that amount. That
124+ // indentation gets subtracted from FencedCodeBlock.getLiteral(), which is the actual text
125+ // represented by the code block.
126+ int start = startPosition (fencedCodeBlock ) + fencedCodeBlock .getFenceIndent ();
127+ MarkdownFencedCodeBlock token =
128+ new MarkdownFencedCodeBlock (
129+ input .substring (start , endPosition (fencedCodeBlock )),
130+ fencedCodeBlock .getFenceCharacter ().repeat (fencedCodeBlock .getOpeningFenceLength ())
131+ + fencedCodeBlock .getInfo (),
132+ fencedCodeBlock .getFenceCharacter ().repeat (fencedCodeBlock .getClosingFenceLength ()),
133+ fencedCodeBlock .getLiteral ());
134+ positionToToken .get (start ).addLast (token );
135+ }
136+
134137 /**
135138 * Visits the given node and the other nodes that are reachable from it via the {@link
136139 * Node#getNext()} references. Does nothing if {@code node} is null.
0 commit comments