From 97b8f11669024874f01ffbc9e829fed7eed923dd Mon Sep 17 00:00:00 2001 From: shalousun <836575280@qq.com> Date: Sat, 11 Jul 2026 23:20:33 +0800 Subject: [PATCH] fix: extract first line as plain-text title from Javadoc comments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add DocUtil.getCommentFirstLine() to extract first line with HTML tags stripped, producing a clean plain-text title for headings - Update all template builders to use getCommentFirstLine for desc field instead of the full Javadoc comment - Fix detail fallback to use full comment when desc is now truncated - Conditionally render Description section in all HTML/Markdown templates — hidden when doc.detail is empty (no comment written) --- .../template/IJavadocDocTemplate.java | 2 +- .../smartdoc/template/IRestDocTemplate.java | 8 +++--- .../smartdoc/template/IWebSocketTemplate.java | 2 +- .../template/JavadocDocBuildTemplate.java | 2 +- .../template/RpcDocBuildTemplate.java | 2 +- .../io/github/smartdoc/utils/DocUtil.java | 25 +++++++++++++++++++ src/main/resources/template/AllInOne.html | 2 ++ src/main/resources/template/AllInOne.md | 2 ++ src/main/resources/template/ApiDoc.md | 2 ++ src/main/resources/template/debug-all.html | 2 ++ src/main/resources/template/dubbo/Dubbo.md | 2 ++ .../template/dubbo/DubboAllInOne.html | 2 ++ .../resources/template/dubbo/DubboAllInOne.md | 2 ++ src/main/resources/template/grpc/Grpc.md | 2 ++ .../resources/template/grpc/GrpcAllInOne.html | 2 ++ .../resources/template/grpc/GrpcAllInOne.md | 2 ++ src/main/resources/template/html/debug.html | 2 ++ src/main/resources/template/html/index.html | 2 ++ .../resources/template/javadoc/Javadoc.md | 2 ++ .../template/javadoc/JavadocAllInOne.html | 2 ++ .../template/javadoc/JavadocAllInOne.md | 2 ++ 21 files changed, 63 insertions(+), 8 deletions(-) diff --git a/src/main/java/io/github/smartdoc/template/IJavadocDocTemplate.java b/src/main/java/io/github/smartdoc/template/IJavadocDocTemplate.java index 6ef1a8d4..1e9ca011 100644 --- a/src/main/java/io/github/smartdoc/template/IJavadocDocTemplate.java +++ b/src/main/java/io/github/smartdoc/template/IJavadocDocTemplate.java @@ -99,7 +99,7 @@ default T convertToJavadocJavaMethod(ApiConfig apiConfig, JavaMethod method, Map javadocJavaMethod.setMethodDefinition(methodDefine); javadocJavaMethod.setEscapeMethodDefinition(scapeMethod); - javadocJavaMethod.setDesc(DocUtil.getEscapeAndCleanComment(method.getComment())); + javadocJavaMethod.setDesc(DocUtil.getCommentFirstLine(method.getComment())); // set detail String apiNoteValue = DocUtil.getNormalTagComments(method, DocTags.API_NOTE, cls.getName()); if (StringUtil.isEmpty(apiNoteValue)) { diff --git a/src/main/java/io/github/smartdoc/template/IRestDocTemplate.java b/src/main/java/io/github/smartdoc/template/IRestDocTemplate.java index 04e5f2d9..676447a4 100644 --- a/src/main/java/io/github/smartdoc/template/IRestDocTemplate.java +++ b/src/main/java/io/github/smartdoc/template/IRestDocTemplate.java @@ -283,10 +283,10 @@ default void handleApiDoc(JavaClass cls, List apiDocList, List apiDocList, Lis String name = DocUtil.generateId(apiDoc.getName()); apiDoc.setAlias(name); } - apiDoc.setDesc(DocUtil.getEscapeAndCleanComment(comment)); + apiDoc.setDesc(DocUtil.getCommentFirstLine(comment)); apiDoc.setList(apiMethodDocs); List docletTags = cls.getTags(); diff --git a/src/main/java/io/github/smartdoc/template/RpcDocBuildTemplate.java b/src/main/java/io/github/smartdoc/template/RpcDocBuildTemplate.java index 47cb49bf..6462b83b 100644 --- a/src/main/java/io/github/smartdoc/template/RpcDocBuildTemplate.java +++ b/src/main/java/io/github/smartdoc/template/RpcDocBuildTemplate.java @@ -204,7 +204,7 @@ private void handleJavaApiDoc(JavaClass cls, List apiDocList, List annotations = cls.getAnnotations(); diff --git a/src/main/java/io/github/smartdoc/utils/DocUtil.java b/src/main/java/io/github/smartdoc/utils/DocUtil.java index bd36998b..d09538af 100644 --- a/src/main/java/io/github/smartdoc/utils/DocUtil.java +++ b/src/main/java/io/github/smartdoc/utils/DocUtil.java @@ -1001,6 +1001,31 @@ public static String getEscapeAndCleanComment(String comment) { return comment; } + /** + * Gets the first line of a Javadoc comment as plain text (HTML tags stripped), for + * use as a title/heading. Javadoc convention: the first line is the summary/title, + * and subsequent lines provide the detailed description. + * @param comment the full Javadoc comment (may contain HTML) + * @return the first non-empty line with HTML tags removed, or empty string if + * null/empty + */ + public static String getCommentFirstLine(String comment) { + if (StringUtil.isEmpty(comment)) { + return ""; + } + String trimmed = comment.trim(); + int newlineIndex = trimmed.indexOf('\n'); + String firstLine; + if (newlineIndex > 0) { + firstLine = trimmed.substring(0, newlineIndex).trim(); + } + else { + firstLine = trimmed; + } + // Strip HTML tags to produce pure text title + return firstLine.replaceAll("<[^>]*>", "").trim(); + } + /** * Get the url from 'value' or 'path' attribute * @param classLoader classLoader diff --git a/src/main/resources/template/AllInOne.html b/src/main/resources/template/AllInOne.html index 408ddf98..d58ec4db 100644 --- a/src/main/resources/template/AllInOne.html +++ b/src/main/resources/template/AllInOne.html @@ -144,7 +144,9 @@ <%}%>

Content-Type: ${doc.contentType}

+<%if(isNotEmpty(doc.detail)){%>

Description: ${htmlEscape(doc.detail)}

+ <%}%> <%if(isNotEmpty(doc.requestHeaders)&&displayRequestParams){%>

Request-headers:

diff --git a/src/main/resources/template/AllInOne.md b/src/main/resources/template/AllInOne.md index b0032777..cb139df3 100644 --- a/src/main/resources/template/AllInOne.md +++ b/src/main/resources/template/AllInOne.md @@ -43,7 +43,9 @@ for(doc in api.list){ **Content-Type:** ${doc.contentType} +<%if(isNotEmpty(doc.detail)){%> **Description:** ${doc.detail} +<%}%> <%if(isNotEmpty(doc.requestHeaders)){%> **Request-headers:** diff --git a/src/main/resources/template/ApiDoc.md b/src/main/resources/template/ApiDoc.md index 543ebc27..f33a8423 100644 --- a/src/main/resources/template/ApiDoc.md +++ b/src/main/resources/template/ApiDoc.md @@ -19,7 +19,9 @@ for(doc in list){ **Content-Type:** `${doc.contentType}` +<%if(isNotEmpty(doc.detail)){%> **Description:** ${doc.detail} +<%}%> <%if(isNotEmpty(doc.requestHeaders)){%> **Request-headers:** diff --git a/src/main/resources/template/debug-all.html b/src/main/resources/template/debug-all.html index 86cc9166..f7a3b095 100644 --- a/src/main/resources/template/debug-all.html +++ b/src/main/resources/template/debug-all.html @@ -146,7 +146,9 @@ <%}%>

Content-Type: ${doc.contentType}

+<%if(isNotEmpty(doc.detail)){%>

Description: ${htmlEscape(doc.detail)}

+ <%}%> <%if(isNotEmpty(doc.requestHeaders)&&displayRequestParams){%>

Request-headers:

diff --git a/src/main/resources/template/dubbo/Dubbo.md b/src/main/resources/template/dubbo/Dubbo.md index 5b0ac9ba..69ddf774 100644 --- a/src/main/resources/template/dubbo/Dubbo.md +++ b/src/main/resources/template/dubbo/Dubbo.md @@ -28,7 +28,9 @@ for(doc in list){ **Author:** ${doc.author} <%}%> +<%if(isNotEmpty(doc.detail)){%> **Description:** ${doc.detail} +<%}%> <%if(isNotEmpty(doc.requestParams)){%> **Invoke-parameters:** diff --git a/src/main/resources/template/dubbo/DubboAllInOne.html b/src/main/resources/template/dubbo/DubboAllInOne.html index bf167270..41384ca5 100644 --- a/src/main/resources/template/dubbo/DubboAllInOne.html +++ b/src/main/resources/template/dubbo/DubboAllInOne.html @@ -121,7 +121,9 @@ href="#_${api.order+1}_${doc.order}_${doc.desc}">${api.order+1}.${doc.order}. ${htmlEscape(doc.desc)}<%}%>

Definition: ${doc.escapeMethodDefinition}

+<%if(isNotEmpty(doc.detail)){%>

Description: ${doc.detail}

+ <%}%> <%if(isNotEmpty(doc.requestParams)){%>

Invoke-parameters:

diff --git a/src/main/resources/template/dubbo/DubboAllInOne.md b/src/main/resources/template/dubbo/DubboAllInOne.md index a863e479..833733dd 100644 --- a/src/main/resources/template/dubbo/DubboAllInOne.md +++ b/src/main/resources/template/dubbo/DubboAllInOne.md @@ -71,7 +71,9 @@ ${consumerConfigExample} **Author:** ${doc.author} <%}%> +<%if(isNotEmpty(doc.detail)){%> **Description:** ${doc.detail} +<%}%> <%if(isNotEmpty(doc.requestParams)){%> **Invoke-parameters:** diff --git a/src/main/resources/template/grpc/Grpc.md b/src/main/resources/template/grpc/Grpc.md index eda45caf..85cb475a 100644 --- a/src/main/resources/template/grpc/Grpc.md +++ b/src/main/resources/template/grpc/Grpc.md @@ -26,7 +26,9 @@ **Author:** ${doc.author} <%}%> +<%if(isNotEmpty(doc.detail)){%> **Description:** ${doc.detail} +<%}%> **MethodType:** ${doc.methodType} diff --git a/src/main/resources/template/grpc/GrpcAllInOne.html b/src/main/resources/template/grpc/GrpcAllInOne.html index c1fbdc50..0f3ff552 100644 --- a/src/main/resources/template/grpc/GrpcAllInOne.html +++ b/src/main/resources/template/grpc/GrpcAllInOne.html @@ -88,7 +88,9 @@ href="#_${api.order}_${doc.order}_${htmlEscape(doc.desc)}">${api.order}.${doc.order}. ${htmlEscape(doc.desc)}<%}%>

Definition: ${doc.escapeMethodDefinition}

+<%if(isNotEmpty(doc.detail)){%>

Description: ${doc.detail}

+ <%}%>

MethodType: ${doc.methodType}

<%if(isNotEmpty(doc.requestParams)){%>

Invoke-parameters:

diff --git a/src/main/resources/template/grpc/GrpcAllInOne.md b/src/main/resources/template/grpc/GrpcAllInOne.md index 71d393db..f1d954ca 100644 --- a/src/main/resources/template/grpc/GrpcAllInOne.md +++ b/src/main/resources/template/grpc/GrpcAllInOne.md @@ -44,7 +44,9 @@ **Author:** ${doc.author} <%}%> +<%if(isNotEmpty(doc.detail)){%> **Description:** ${doc.detail} +<%}%> **MethodType:** ${doc.methodType} diff --git a/src/main/resources/template/html/debug.html b/src/main/resources/template/html/debug.html index 05669a6e..005dd1a1 100644 --- a/src/main/resources/template/html/debug.html +++ b/src/main/resources/template/html/debug.html @@ -82,7 +82,9 @@ <%}%>

Content-Type: ${doc.contentType}

+<%if(isNotEmpty(doc.detail)){%>

Description: ${lineBreaksToBr(doc.detail)}

+ <%}%> <%if(isNotEmpty(doc.requestHeaders)){%>

Request-headers:

diff --git a/src/main/resources/template/html/index.html b/src/main/resources/template/html/index.html index c90a6115..2fc284eb 100644 --- a/src/main/resources/template/html/index.html +++ b/src/main/resources/template/html/index.html @@ -75,7 +75,9 @@

Author: ${doc.author}

<%}%>

Content-Type: ${doc.contentType}

+<%if(isNotEmpty(doc.detail)){%>

Description: ${lineBreaksToBr(doc.detail)}

+ <%}%> <%if(isNotEmpty(doc.requestHeaders)){%>

Request-headers:

diff --git a/src/main/resources/template/javadoc/Javadoc.md b/src/main/resources/template/javadoc/Javadoc.md index 15f5824d..165a8c2b 100644 --- a/src/main/resources/template/javadoc/Javadoc.md +++ b/src/main/resources/template/javadoc/Javadoc.md @@ -24,7 +24,9 @@ for(doc in list){ **Author:** ${doc.author} <%}%> +<%if(isNotEmpty(doc.detail)){%> **Description:** ${doc.detail} +<%}%> <%if(isNotEmpty(doc.requestParams)){%> **Invoke-parameters:** diff --git a/src/main/resources/template/javadoc/JavadocAllInOne.html b/src/main/resources/template/javadoc/JavadocAllInOne.html index 71310ab3..7a7f4eae 100644 --- a/src/main/resources/template/javadoc/JavadocAllInOne.html +++ b/src/main/resources/template/javadoc/JavadocAllInOne.html @@ -119,7 +119,9 @@ href="#_${api.order+1}_${doc.order}_${doc.desc}">${api.order+1}.${doc.order}. ${htmlEscape(doc.desc)}<%}%>

Definition: ${doc.escapeMethodDefinition}

+<%if(isNotEmpty(doc.detail)){%>

Description: ${doc.detail}

+ <%}%> <%if(isNotEmpty(doc.requestParams)){%>

Invoke-parameters:

diff --git a/src/main/resources/template/javadoc/JavadocAllInOne.md b/src/main/resources/template/javadoc/JavadocAllInOne.md index 5c2bc899..b94cd91d 100644 --- a/src/main/resources/template/javadoc/JavadocAllInOne.md +++ b/src/main/resources/template/javadoc/JavadocAllInOne.md @@ -40,7 +40,9 @@ **Author:** ${doc.author} <%}%> +<%if(isNotEmpty(doc.detail)){%> **Description:** ${doc.detail} +<%}%> <%if(isNotEmpty(doc.requestParams)){%> **Invoke-parameters:**