Skip to content

Commit 1f9d2ac

Browse files
cushongoogle-java-format Team
authored andcommitted
Preserve relative indentation in <pre>{@code ...} blocks lacking leading *.
In classic Javadoc, lines inside `<pre>` blocks that omit the `*` margin prefix previously had all leading whitespace stripped via `line.stripLeading()`, destroying relative indentation in code samples. Instead, strip only up to the comment's base indentation column so that `JavadocLexer.deindentPreCodeBlocks` can preserve the relative indentation of the sample. PiperOrigin-RevId: 994305827
1 parent 2957b19 commit 1f9d2ac

2 files changed

Lines changed: 56 additions & 5 deletions

File tree

‎core/src/main/java/com/google/googlejavaformat/java/javadoc/JavadocFormatter.java‎

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -236,15 +236,29 @@ private static String classicCommentText(String input) {
236236
// The end result should not strip the `*` from `* foo`.
237237
List<String> processedLines = new ArrayList<>();
238238
processedLines.add(lines.get(0));
239-
for (String line : lines.subList(1, lines.size())) {
239+
List<String> continuations = lines.subList(1, lines.size());
240+
int starPrefixLength =
241+
continuations.stream()
242+
.map(CLASSIC_PREFIX_PATTERN::matcher)
243+
.filter(Matcher::find)
244+
.mapToInt(Matcher::end)
245+
.min()
246+
.orElse(0);
247+
int nonStarMinLeading =
248+
continuations.stream()
249+
.filter(line -> !CLASSIC_PREFIX_PATTERN.matcher(line).find())
250+
.filter(line -> NOT_SPACE_OR_TAB.matchesAnyOf(line))
251+
.mapToInt(NOT_SPACE_OR_TAB::indexIn)
252+
.min()
253+
.orElse(0);
254+
int nonStarStripCount = Math.min(starPrefixLength, nonStarMinLeading);
255+
for (String line : continuations) {
240256
Matcher m = CLASSIC_PREFIX_PATTERN.matcher(line);
241257
if (m.find()) {
242258
processedLines.add(m.replaceFirst(""));
243259
} else {
244-
// Input line did not have leading `*`. In that case, it's hard to know what is supposed to
245-
// be indentation of the comment as a whole and what is supposed to be indentation of the
246-
// content. We just strip all leading whitespace.
247-
processedLines.add(line.stripLeading());
260+
processedLines.add(
261+
line.length() >= nonStarStripCount ? line.substring(nonStarStripCount) : "");
248262
}
249263
}
250264
// Unlike Markdown comments, stripping common leading whitespace is not mandated by any

‎core/src/test/java/com/google/googlejavaformat/java/JavadocFormattingTest.java‎

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2534,6 +2534,43 @@ class Test {}
25342534
doFormatTest(input, expected);
25352535
}
25362536

2537+
@Test
2538+
public void preCodeWithoutLeadingStarPreservesIndent() {
2539+
String input =
2540+
"""
2541+
/**
2542+
* <pre>{@code
2543+
class Demo {
2544+
// Comment
2545+
static final int X = 1;
2546+
2547+
public static void example() {
2548+
int y = 2;
2549+
}
2550+
}
2551+
* }</pre>
2552+
*/
2553+
class Test {}
2554+
""";
2555+
String expected =
2556+
"""
2557+
/**
2558+
* <pre>{@code
2559+
* class Demo {
2560+
* // Comment
2561+
* static final int X = 1;
2562+
*
2563+
* public static void example() {
2564+
* int y = 2;
2565+
* }
2566+
* }
2567+
* }</pre>
2568+
*/
2569+
class Test {}
2570+
""";
2571+
doFormatTest(input, expected);
2572+
}
2573+
25372574
// TODO: b/346668798 - Test the following Markdown constructs, and make the tests work as needed.
25382575
// We can assume that the CommonMark parser correctly handles Markdown, so the question is whether
25392576
// they are subsequently mishandled by our formatting logic. So for example the CommonMark parser

0 commit comments

Comments
 (0)