Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,15 @@ private void convertLink(Javadoc.Link link) {
private void convertStartElement(Javadoc.StartElement element) {
String name = element.getName().toLowerCase();
if (inPre && !"pre".equals(name)) {
if ("code".equals(name)) {
// Place the fence (and optional language) on its own line so the
// code content starts fresh; otherwise the first code line would be
// consumed as the fenced code block's info string.
currentLine.append(extractCodeLanguage(element));
lines.add(currentLine.toString());
currentLine = new StringBuilder();
return;
}
renderHtmlStartElement(element);
return;
}
Expand Down Expand Up @@ -293,6 +302,31 @@ private void convertStartElement(Javadoc.StartElement element) {
}
}

private String extractCodeLanguage(Javadoc.StartElement element) {
return element.getAttributes().stream()
.filter(attr -> attr instanceof Javadoc.Attribute)
.map(attr -> (Javadoc.Attribute) attr)
.filter(a -> "class".equalsIgnoreCase(a.getName()))
.filter(a -> a.getValue() != null)
.map(a -> renderInline(a.getValue()).trim())
.map(JavadocToMarkdownConverter::stripAttributeQuotes)
.findFirst()
.orElse("");
}

private static String stripAttributeQuotes(String value) {
if (value.length() < 2) {
return value;
}

char first = value.charAt(0);
char last = value.charAt(value.length() - 1);
if ((first == '\'' && last == '\'') || (first == '"' && last == '"')) {
return value.substring(1, value.length() - 1);
}
return value;
}

private void renderHtmlStartElement(Javadoc.StartElement element) {
currentLine.append('<').append(element.getName());
for (Javadoc attr : element.getAttributes()) {
Expand All @@ -314,12 +348,21 @@ private void renderHtmlStartElement(Javadoc.StartElement element) {
private void convertEndElement(Javadoc.EndElement element) {
String name = element.getName().toLowerCase();
if (inPre && !"pre".equals(name)) {
currentLine.append("</").append(element.getName()).append('>');
if (!"code".equals(name)) {
currentLine.append("</").append(element.getName()).append('>');
}
return;
}
switch (name) {
case "pre":
inPre = false;
// Flush any trailing inline code (e.g. `...);</code></pre>`) so the
// closing fence sits on its own line, as Markdown requires. Only flush
// real content; a whitespace-only line means the fence is already alone.
if (!currentLine.toString().trim().isEmpty()) {
lines.add(currentLine.toString());
currentLine = new StringBuilder();
}
currentLine.append("```");
break;
case "code":
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -496,6 +496,134 @@ public void m() {}
);
}

@Test
public void codeTagConverted() {
rewriteRun(
spec -> spec.recipe(new JavadocToMarkdownDocComment()),
java(
"""
class Test {
/**
* <pre><code> public class TolkienCharacter {
* String name;
* double height;
* }
* </code></pre>
*/
public void withErrorMessageForFields() {
}
}
""",
"""
class Test {
/// ```
/// public class TolkienCharacter {
/// String name;
/// double height;
/// }
/// ```
public void withErrorMessageForFields() {
}
}
""")
);
}

@Test
public void codeTagWithEmptyLanguageConverted() {
rewriteRun(
spec -> spec.recipe(new JavadocToMarkdownDocComment()),
java(
"""
class Test {
/**
* <pre><code class=''> public class TolkienCharacter {
* String name;
* double height;
* }
* </code></pre>
*/
public void withErrorMessageForFields() {
}
}
""",
"""
class Test {
/// ```
/// public class TolkienCharacter {
/// String name;
/// double height;
/// }
/// ```
public void withErrorMessageForFields() {
}
}
""")
);
}

@Test
public void codeTagLanguageNotConverted() {
rewriteRun(
spec -> spec.recipe(new JavadocToMarkdownDocComment()),
java(
"""
class Test {
/**
* <pre><code class='java'> public class TolkienCharacter {
* String name;
* double height;
* }
* </code></pre>
*/
public void withErrorMessageForFields() {
}
}
""",
"""
class Test {
/// ```java
/// public class TolkienCharacter {
/// String name;
/// double height;
/// }
/// ```
public void withErrorMessageForFields() {
}
}
""")
);
}

@Test
public void codeTagClosedInline() {
rewriteRun(
spec -> spec.recipe(new JavadocToMarkdownDocComment()),
java(
"""
class Test {
/**
* <pre><code class='java'> // assertion will pass
* assertThat("abc").contains("ab");</code></pre>
*/
public void withErrorMessageForFields() {
}
}
""",
"""
class Test {
/// ```java
/// // assertion will pass
/// assertThat("abc").contains("ab");
/// ```
public void withErrorMessageForFields() {
}
}
""")
);
}


@Nested
class Jep467FlagshipExamples {

Expand Down
Loading