diff --git a/core/src/main/java/com/google/googlejavaformat/java/javadoc/MarkdownPositions.java b/core/src/main/java/com/google/googlejavaformat/java/javadoc/MarkdownPositions.java index be70484d5..82504d805 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/javadoc/MarkdownPositions.java +++ b/core/src/main/java/com/google/googlejavaformat/java/javadoc/MarkdownPositions.java @@ -87,42 +87,8 @@ void visit(Node node) { case Paragraph paragraph -> addSpan(paragraph, PARAGRAPH_OPEN_TOKEN, PARAGRAPH_CLOSE_TOKEN); case BulletList bulletList -> addSpan(bulletList, LIST_OPEN_TOKEN, LIST_CLOSE_TOKEN); case OrderedList orderedList -> addSpan(orderedList, LIST_OPEN_TOKEN, LIST_CLOSE_TOKEN); - case ListItem listItem -> { - int startPosition = listItem.getSourceSpans().getFirst().getInputIndex(); - Matcher matcher = - LIST_ITEM_START_PATTERN.matcher(input).region(startPosition, input.length()); - verify(matcher.lookingAt()); - ListItemOpenTag openToken = new ListItemOpenTag(matcher.group(1)); - addSpan(listItem, openToken, LIST_ITEM_CLOSE_TOKEN); - if (listItem.getFirstChild() instanceof Paragraph paragraph) { - // A ListItem typically contains a Paragraph, but we don't want to visit that Paragraph - // because that would lead us to introduce a line break after the list introduction - // (the `-` or whatever). So we visit the children and siblings of the Paragraph - // instead. - alreadyVisitedChildren = true; - visitNodeList(paragraph.getFirstChild()); - visitNodeList(paragraph.getNext()); - } - } - case FencedCodeBlock fencedCodeBlock -> { - // Any indentation before the code block is part of FencedCodeBlock. This makes sense - // because the lines inside the code block must also be indented by that amount. That - // indentation gets subtracted from FencedCodeBlock.getLiteral(), which is the actual text - // represented by the code block. - int start = startPosition(fencedCodeBlock) + fencedCodeBlock.getFenceIndent(); - MarkdownFencedCodeBlock token = - new MarkdownFencedCodeBlock( - input.substring(start, endPosition(fencedCodeBlock)), - fencedCodeBlock - .getFenceCharacter() - .repeat(fencedCodeBlock.getOpeningFenceLength()) - + fencedCodeBlock.getInfo(), - fencedCodeBlock - .getFenceCharacter() - .repeat(fencedCodeBlock.getClosingFenceLength()), - fencedCodeBlock.getLiteral()); - positionToToken.get(start).addLast(token); - } + case ListItem listItem -> alreadyVisitedChildren = visitListItem(listItem); + case FencedCodeBlock fencedCodeBlock -> visitFencedCodeBlock(fencedCodeBlock); // TODO: others default -> {} } @@ -131,6 +97,43 @@ void visit(Node node) { } } + // Returns true if this method visited the children of the given ListItem. + private boolean visitListItem(ListItem listItem) { + int startPosition = listItem.getSourceSpans().getFirst().getInputIndex(); + Matcher matcher = + LIST_ITEM_START_PATTERN.matcher(input).region(startPosition, input.length()); + verify(matcher.lookingAt()); + ListItemOpenTag openToken = new ListItemOpenTag(matcher.group(1)); + addSpan(listItem, openToken, LIST_ITEM_CLOSE_TOKEN); + return switch (listItem.getFirstChild()) { + case Paragraph paragraph -> { + // A ListItem typically contains a Paragraph, but we don't want to visit that Paragraph + // because that would lead us to introduce a line break after the list introduction + // (the `-` or whatever). So we visit the children and siblings of the Paragraph instead. + visitNodeList(paragraph.getFirstChild()); + visitNodeList(paragraph.getNext()); + yield true; + } + default -> false; + }; + } + + private void visitFencedCodeBlock(FencedCodeBlock fencedCodeBlock) { + // Any indentation before the code block is part of FencedCodeBlock. This makes sense + // because the lines inside the code block must also be indented by that amount. That + // indentation gets subtracted from FencedCodeBlock.getLiteral(), which is the actual text + // represented by the code block. + int start = startPosition(fencedCodeBlock) + fencedCodeBlock.getFenceIndent(); + MarkdownFencedCodeBlock token = + new MarkdownFencedCodeBlock( + input.substring(start, endPosition(fencedCodeBlock)), + fencedCodeBlock.getFenceCharacter().repeat(fencedCodeBlock.getOpeningFenceLength()) + + fencedCodeBlock.getInfo(), + fencedCodeBlock.getFenceCharacter().repeat(fencedCodeBlock.getClosingFenceLength()), + fencedCodeBlock.getLiteral()); + positionToToken.get(start).addLast(token); + } + /** * Visits the given node and the other nodes that are reachable from it via the {@link * Node#getNext()} references. Does nothing if {@code node} is null.