diff --git a/core/src/main/java/com/google/googlejavaformat/java/javadoc/JavadocWriter.java b/core/src/main/java/com/google/googlejavaformat/java/javadoc/JavadocWriter.java index 492bb0150..182762a7f 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/javadoc/JavadocWriter.java +++ b/core/src/main/java/com/google/googlejavaformat/java/javadoc/JavadocWriter.java @@ -335,6 +335,10 @@ void writeLiteral(Literal token) { } void writeMarkdownFencedCodeBlock(MarkdownFencedCodeBlock token) { + if (wroteAnythingSignificant && !atStartOfLine) { + // A reminder that atStartOfLine is still true after `-␣` because it is a StartOfLineToken. + requestBlankLine(); + } flushWhitespace(); output.append(token.start()); token 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 7f66b32e8..d5fdde5d9 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 @@ -30,6 +30,7 @@ import com.google.googlejavaformat.java.javadoc.Token.MarkdownFencedCodeBlock; import com.google.googlejavaformat.java.javadoc.Token.ParagraphCloseTag; import com.google.googlejavaformat.java.javadoc.Token.ParagraphOpenTag; +import java.util.Objects; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.commonmark.node.BulletList; @@ -128,12 +129,16 @@ private void visitFencedCodeBlock(FencedCodeBlock fencedCodeBlock) { // indentation gets subtracted from FencedCodeBlock.getLiteral(), which is the actual text // represented by the code block. int start = startPosition(fencedCodeBlock) + fencedCodeBlock.getFenceIndent(); + int closingLength = + Objects.requireNonNullElse( + fencedCodeBlock.getClosingFenceLength(), fencedCodeBlock.getOpeningFenceLength()); + // We have observed getClosingFenceLength() returning null in some cases. MarkdownFencedCodeBlock token = new MarkdownFencedCodeBlock( input.substring(start, endPosition(fencedCodeBlock)), fencedCodeBlock.getFenceCharacter().repeat(fencedCodeBlock.getOpeningFenceLength()) + fencedCodeBlock.getInfo(), - fencedCodeBlock.getFenceCharacter().repeat(fencedCodeBlock.getClosingFenceLength()), + fencedCodeBlock.getFenceCharacter().repeat(closingLength), fencedCodeBlock.getLiteral()); positionToToken.get(start).addLast(token); } diff --git a/core/src/main/java/com/google/googlejavaformat/java/javadoc/Token.java b/core/src/main/java/com/google/googlejavaformat/java/javadoc/Token.java index 134fbc8f6..42b73b069 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/javadoc/Token.java +++ b/core/src/main/java/com/google/googlejavaformat/java/javadoc/Token.java @@ -38,11 +38,12 @@ default int length() { /** * Tokens that are always pinned to the following token. For example, {@code

} in {@code

Foo - * bar} (never {@code

Foo bar} or {@code

\nFoo bar}). + * bar} (never {@code

Foo bar} or {@code

\nFoo bar}); or {#code + *

  • } or {@code -␣} in {@code
  • Foo bar} or {@code -␣Foo bar}. * - *

    This is not the only kind of "pinning" that we do: See also the joining of Literal tokens - * done by the lexer. The special pinning here is necessary because these tokens are not of type - * Literal (because they require other special handling). + *

    This is not the only kind of "pinning" that we do: See also the joining of Literal + * tokens done by the lexer. The special pinning here is necessary because these tokens are + * not of type Literal (because they require other special handling). */ interface StartOfLineToken {} diff --git a/core/src/test/java/com/google/googlejavaformat/java/JavadocFormattingTest.java b/core/src/test/java/com/google/googlejavaformat/java/JavadocFormattingTest.java index d9186717e..02af3d137 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/JavadocFormattingTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/JavadocFormattingTest.java @@ -1739,9 +1739,14 @@ public void markdownFencedCodeBlocks() { /// ``` /// /// - flibbertigibbet +/// ``` +/// code block in a list after text with no blank line intervening (one will be inserted) +/// ``` +/// +/// - flibbertigibbet /// /// ``` -/// code block in a list after text +/// code block in a list after text with a blank line intervening /// ``` /// /// ~~~java @@ -1767,8 +1772,16 @@ class Test {} /// in a list /// ``` /// -/// - flibbertigibbet``` -/// code block in a list after text +/// - flibbertigibbet +/// +/// ``` +/// code block in a list after text with no blank line intervening (one will be inserted) +/// ``` +/// +/// - flibbertigibbet +/// +/// ``` +/// code block in a list after text with a blank line intervening /// ``` /// /// ~~~java