Skip to content

Commit

Permalink
Merge pull request #42907 from gsmet/output-markdown
Browse files Browse the repository at this point in the history
Allow multiple format and themes in the Config Doc generator
  • Loading branch information
gsmet authored Sep 11, 2024
2 parents 1aee9a2 + 3cfa644 commit f9530d6
Show file tree
Hide file tree
Showing 44 changed files with 1,363 additions and 819 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,12 @@ public void finalizeProcessing() {

Properties javadocProperties = new Properties();
for (Entry<String, JavadocElement> javadocElementEntry : configCollector.getJavadocElements().entrySet()) {
javadocProperties.put(javadocElementEntry.getKey(), javadocElementEntry.getValue().rawJavadoc());
if (javadocElementEntry.getValue().description() == null
|| javadocElementEntry.getValue().description().isBlank()) {
continue;
}

javadocProperties.put(javadocElementEntry.getKey(), javadocElementEntry.getValue().description());
}
utils.filer().write(Outputs.META_INF_QUARKUS_JAVADOC, javadocProperties);

Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package io.quarkus.annotation.processor.documentation.config.discovery;

public record ParsedJavadoc(String description, String since, String deprecated, JavadocFormat originalFormat) {
import io.quarkus.annotation.processor.documentation.config.model.JavadocFormat;

public record ParsedJavadoc(String description, JavadocFormat format, String since, String deprecated) {

public static ParsedJavadoc empty() {
return new ParsedJavadoc(null, null, null, null);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package io.quarkus.annotation.processor.documentation.config.discovery;

public record ParsedJavadocSection(String title, String details, String deprecated) {
import io.quarkus.annotation.processor.documentation.config.model.JavadocFormat;

public record ParsedJavadocSection(String title, String details, JavadocFormat format, String deprecated) {

public static ParsedJavadocSection empty() {
return new ParsedJavadocSection(null, null, null);
return new ParsedJavadocSection(null, null, null, null);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package io.quarkus.annotation.processor.documentation.config.formatter;

import java.util.Optional;
import java.util.regex.Pattern;

import org.jsoup.Jsoup;
Expand All @@ -9,29 +8,17 @@

import com.github.javaparser.StaticJavaParser;
import com.github.javaparser.javadoc.Javadoc;
import com.github.javaparser.javadoc.JavadocBlockTag;
import com.github.javaparser.javadoc.JavadocBlockTag.Type;
import com.github.javaparser.javadoc.description.JavadocDescription;
import com.github.javaparser.javadoc.description.JavadocDescriptionElement;
import com.github.javaparser.javadoc.description.JavadocInlineTag;

import io.quarkus.annotation.processor.documentation.config.discovery.JavadocFormat;
import io.quarkus.annotation.processor.documentation.config.discovery.ParsedJavadoc;
import io.quarkus.annotation.processor.documentation.config.discovery.ParsedJavadocSection;
import io.quarkus.annotation.processor.documentation.config.model.JavadocFormat;
import io.quarkus.annotation.processor.documentation.config.util.ConfigNamingUtil;

public final class JavadocToAsciidocTransformer {

public static final JavadocToAsciidocTransformer INSTANCE = new JavadocToAsciidocTransformer();
public static final JavadocToAsciidocTransformer INLINE_MACRO_INSTANCE = new JavadocToAsciidocTransformer(true);

private static final Pattern START_OF_LINE = Pattern.compile("^", Pattern.MULTILINE);
private static final Pattern REPLACE_WINDOWS_EOL = Pattern.compile("\r\n");
private static final Pattern REPLACE_MACOS_EOL = Pattern.compile("\r");
private static final Pattern STARTING_SPACE = Pattern.compile("^ +");

private static final String DOT = ".";

private static final String BACKTICK = "`";
private static final String HASH = "#";
private static final String STAR = "*";
Expand Down Expand Up @@ -75,126 +62,31 @@ public final class JavadocToAsciidocTransformer {
private static final String BLOCKQUOTE_BLOCK_ASCIDOC_STYLE = "[quote]\n____";
private static final String BLOCKQUOTE_BLOCK_ASCIDOC_STYLE_END = "____";

private final boolean inlineMacroMode;

private JavadocToAsciidocTransformer(boolean inlineMacroMode) {
this.inlineMacroMode = inlineMacroMode;
}

private JavadocToAsciidocTransformer() {
this(false);
}

public ParsedJavadoc parseConfigItemJavadoc(String rawJavadoc) {
if (rawJavadoc == null || rawJavadoc.isBlank()) {
return ParsedJavadoc.empty();
}

// the parser expects all the lines to start with "* "
// we add it as it has been previously removed
Javadoc javadoc = StaticJavaParser.parseJavadoc(START_OF_LINE.matcher(rawJavadoc).replaceAll("* "));

String description;
JavadocFormat originalFormat;
public static String toAsciidoc(String javadoc, JavadocFormat format) {
return toAsciidoc(javadoc, format, false);
}

if (isAsciidoc(javadoc)) {
description = handleEolInAsciidoc(javadoc);
originalFormat = JavadocFormat.ASCIIDOC;
} else {
description = htmlJavadocToAsciidoc(javadoc.getDescription());
originalFormat = JavadocFormat.JAVADOC;
public static String toAsciidoc(String javadoc, JavadocFormat format, boolean inlineMacroMode) {
if (javadoc == null || javadoc.isBlank()) {
return null;
}

Optional<String> since = javadoc.getBlockTags().stream()
.filter(t -> t.getType() == Type.SINCE)
.map(JavadocBlockTag::getContent)
.map(JavadocDescription::toText)
.findFirst();

Optional<String> deprecated = javadoc.getBlockTags().stream()
.filter(t -> t.getType() == Type.DEPRECATED)
.map(JavadocBlockTag::getContent)
.map(JavadocDescription::toText)
.findFirst();

if (description != null && description.isBlank()) {
description = null;
}

return new ParsedJavadoc(description, since.orElse(null), deprecated.orElse(null), originalFormat);
}

public ParsedJavadocSection parseConfigSectionJavadoc(String javadocComment) {
if (javadocComment == null || javadocComment.trim().isEmpty()) {
return ParsedJavadocSection.empty();
if (format == JavadocFormat.ASCIIDOC) {
return javadoc;
} else if (format == JavadocFormat.MARKDOWN) {
throw new IllegalArgumentException("Conversion from Markdown to Asciidoc is not supported");
}

// the parser expects all the lines to start with "* "
// we add it as it has been previously removed
javadocComment = START_OF_LINE.matcher(javadocComment).replaceAll("* ");
Javadoc javadoc = StaticJavaParser.parseJavadoc(javadocComment);
Javadoc parsedJavadoc = StaticJavaParser.parseJavadoc(START_OF_LINE.matcher(javadoc).replaceAll("* "));

Optional<String> deprecated = javadoc.getBlockTags().stream()
.filter(t -> t.getType() == Type.DEPRECATED)
.map(JavadocBlockTag::getContent)
.map(JavadocDescription::toText)
.findFirst();

String asciidoc;
if (isAsciidoc(javadoc)) {
asciidoc = handleEolInAsciidoc(javadoc);
} else {
asciidoc = htmlJavadocToAsciidoc(javadoc.getDescription());
}

if (asciidoc == null || asciidoc.isBlank()) {
return ParsedJavadocSection.empty();
}

final int newLineIndex = asciidoc.indexOf(NEW_LINE);
final int dotIndex = asciidoc.indexOf(DOT);

final int endOfTitleIndex;
if (newLineIndex > 0 && newLineIndex < dotIndex) {
endOfTitleIndex = newLineIndex;
} else {
endOfTitleIndex = dotIndex;
}

if (endOfTitleIndex == -1) {
final String title = asciidoc.replaceAll("^([^\\w])+", "").trim();

return new ParsedJavadocSection(title, null, deprecated.orElse(null));
} else {
final String title = asciidoc.substring(0, endOfTitleIndex).replaceAll("^([^\\w])+", "").trim();
final String details = asciidoc.substring(endOfTitleIndex + 1).trim();

return new ParsedJavadocSection(title, details.isBlank() ? null : details, deprecated.orElse(null));
}
}

private String handleEolInAsciidoc(Javadoc javadoc) {
// it's Asciidoc, so we just pass through
// it also uses platform specific EOL, so we need to convert them back to \n
String asciidoc = javadoc.getDescription().toText();
asciidoc = REPLACE_WINDOWS_EOL.matcher(asciidoc).replaceAll("\n");
asciidoc = REPLACE_MACOS_EOL.matcher(asciidoc).replaceAll("\n");
return asciidoc;
}

private boolean isAsciidoc(Javadoc javadoc) {
for (JavadocBlockTag blockTag : javadoc.getBlockTags()) {
if ("asciidoclet".equals(blockTag.getTagName())) {
return true;
}
}
return false;
}

private String htmlJavadocToAsciidoc(JavadocDescription javadocDescription) {
StringBuilder sb = new StringBuilder();

for (JavadocDescriptionElement javadocDescriptionElement : javadocDescription.getElements()) {
for (JavadocDescriptionElement javadocDescriptionElement : parsedJavadoc.getDescription().getElements()) {
if (javadocDescriptionElement instanceof JavadocInlineTag) {
JavadocInlineTag inlineTag = (JavadocInlineTag) javadocDescriptionElement;
String content = inlineTag.getContent().trim();
Expand All @@ -204,7 +96,7 @@ private String htmlJavadocToAsciidoc(JavadocDescription javadocDescription) {
case LITERAL:
case SYSTEM_PROPERTY:
sb.append('`');
appendEscapedAsciiDoc(sb, content);
appendEscapedAsciiDoc(sb, content, inlineMacroMode);
sb.append('`');
break;
case LINK:
Expand All @@ -213,28 +105,30 @@ private String htmlJavadocToAsciidoc(JavadocDescription javadocDescription) {
content = ConfigNamingUtil.hyphenate(content.substring(1));
}
sb.append('`');
appendEscapedAsciiDoc(sb, content);
appendEscapedAsciiDoc(sb, content, inlineMacroMode);
sb.append('`');
break;
default:
sb.append(content);
break;
}
} else {
appendHtml(sb, Jsoup.parseBodyFragment(javadocDescriptionElement.toText()));
appendHtml(sb, Jsoup.parseBodyFragment(javadocDescriptionElement.toText()), inlineMacroMode);
}
}

return trim(sb);
String asciidoc = trim(sb);

return asciidoc.isBlank() ? null : asciidoc;
}

private void appendHtml(StringBuilder sb, Node node) {
private static void appendHtml(StringBuilder sb, Node node, boolean inlineMacroMode) {
for (Node childNode : node.childNodes()) {
switch (childNode.nodeName()) {
case PARAGRAPH_NODE:
newLine(sb);
newLine(sb);
appendHtml(sb, childNode);
appendHtml(sb, childNode, inlineMacroMode);
break;
case PREFORMATED_NODE:
newLine(sb);
Expand All @@ -254,7 +148,7 @@ private void appendHtml(StringBuilder sb, Node node) {
newLine(sb);
sb.append(BLOCKQUOTE_BLOCK_ASCIDOC_STYLE);
newLine(sb);
appendHtml(sb, childNode);
appendHtml(sb, childNode, inlineMacroMode);
newLineIfNeeded(sb);
sb.append(BLOCKQUOTE_BLOCK_ASCIDOC_STYLE_END);
newLine(sb);
Expand All @@ -263,75 +157,75 @@ private void appendHtml(StringBuilder sb, Node node) {
case ORDERED_LIST_NODE:
case UN_ORDERED_LIST_NODE:
newLine(sb);
appendHtml(sb, childNode);
appendHtml(sb, childNode, inlineMacroMode);
break;
case LIST_ITEM_NODE:
final String marker = childNode.parent().nodeName().equals(ORDERED_LIST_NODE)
? ORDERED_LIST_ITEM_ASCIDOC_STYLE
: UNORDERED_LIST_ITEM_ASCIDOC_STYLE;
newLine(sb);
sb.append(marker);
appendHtml(sb, childNode);
appendHtml(sb, childNode, inlineMacroMode);
break;
case LINK_NODE:
final String link = childNode.attr(HREF_ATTRIBUTE);
sb.append("link:");
sb.append(link);
final StringBuilder caption = new StringBuilder();
appendHtml(caption, childNode);
appendHtml(caption, childNode, inlineMacroMode);
sb.append(String.format(LINK_ATTRIBUTE_FORMAT, trim(caption)));
break;
case CODE_NODE:
sb.append(BACKTICK);
appendHtml(sb, childNode);
appendHtml(sb, childNode, inlineMacroMode);
sb.append(BACKTICK);
break;
case BOLD_NODE:
case STRONG_NODE:
sb.append(STAR);
appendHtml(sb, childNode);
appendHtml(sb, childNode, inlineMacroMode);
sb.append(STAR);
break;
case EMPHASIS_NODE:
case ITALICS_NODE:
sb.append(UNDERSCORE);
appendHtml(sb, childNode);
appendHtml(sb, childNode, inlineMacroMode);
sb.append(UNDERSCORE);
break;
case UNDERLINE_NODE:
sb.append(UNDERLINE_ASCIDOC_STYLE);
sb.append(HASH);
appendHtml(sb, childNode);
appendHtml(sb, childNode, inlineMacroMode);
sb.append(HASH);
break;
case SMALL_NODE:
sb.append(SMALL_ASCIDOC_STYLE);
sb.append(HASH);
appendHtml(sb, childNode);
appendHtml(sb, childNode, inlineMacroMode);
sb.append(HASH);
break;
case BIG_NODE:
sb.append(BIG_ASCIDOC_STYLE);
sb.append(HASH);
appendHtml(sb, childNode);
appendHtml(sb, childNode, inlineMacroMode);
sb.append(HASH);
break;
case SUB_SCRIPT_NODE:
sb.append(SUB_SCRIPT_ASCIDOC_STYLE);
appendHtml(sb, childNode);
appendHtml(sb, childNode, inlineMacroMode);
sb.append(SUB_SCRIPT_ASCIDOC_STYLE);
break;
case SUPER_SCRIPT_NODE:
sb.append(SUPER_SCRIPT_ASCIDOC_STYLE);
appendHtml(sb, childNode);
appendHtml(sb, childNode, inlineMacroMode);
sb.append(SUPER_SCRIPT_ASCIDOC_STYLE);
break;
case DEL_NODE:
case S_NODE:
case STRIKE_NODE:
sb.append(LINE_THROUGH_ASCIDOC_STYLE);
sb.append(HASH);
appendHtml(sb, childNode);
appendHtml(sb, childNode, inlineMacroMode);
sb.append(HASH);
break;
case NEW_LINE_NODE:
Expand All @@ -352,10 +246,10 @@ private void appendHtml(StringBuilder sb, Node node) {
text = startingSpaceMatcher.replaceFirst("");
}

appendEscapedAsciiDoc(sb, text);
appendEscapedAsciiDoc(sb, text, inlineMacroMode);
break;
default:
appendHtml(sb, childNode);
appendHtml(sb, childNode, inlineMacroMode);
break;
}
}
Expand Down Expand Up @@ -431,7 +325,7 @@ private static StringBuilder trimText(StringBuilder sb, String charsToTrim) {
return sb;
}

private StringBuilder unescapeHtmlEntities(StringBuilder sb, String text) {
private static StringBuilder unescapeHtmlEntities(StringBuilder sb, String text) {
int i = 0;
/* trim leading whitespace */
LOOP: while (i < text.length()) {
Expand Down Expand Up @@ -497,7 +391,7 @@ private StringBuilder unescapeHtmlEntities(StringBuilder sb, String text) {
return sb;
}

private StringBuilder appendEscapedAsciiDoc(StringBuilder sb, String text) {
private static StringBuilder appendEscapedAsciiDoc(StringBuilder sb, String text, boolean inlineMacroMode) {
boolean escaping = false;
for (int i = 0; i < text.length(); i++) {
final char ch = text.charAt(i);
Expand Down
Loading

0 comments on commit f9530d6

Please sign in to comment.