reduce vertical whitespace in rendered KDoc comments
This commit is contained in:
@@ -130,7 +130,13 @@ public class KotlinQuickDocumentationProvider : AbstractDocumentationProvider()
|
||||
}
|
||||
val comment = KDocFinder.findKDoc(declarationDescriptor)
|
||||
if (comment != null) {
|
||||
renderedDecl = renderedDecl + "<br/>" + KDocRenderer.renderKDoc(comment)
|
||||
val renderedComment = KDocRenderer.renderKDoc(comment)
|
||||
if (renderedComment.startsWith("<p>")) {
|
||||
renderedDecl += renderedComment
|
||||
}
|
||||
else {
|
||||
renderedDecl = "$renderedDecl<br/>$renderedComment"
|
||||
}
|
||||
}
|
||||
|
||||
return renderedDecl
|
||||
|
||||
@@ -29,8 +29,8 @@ import org.jetbrains.kotlin.kdoc.psi.impl.KDocTag
|
||||
object KDocRenderer {
|
||||
fun renderKDoc(docComment: KDocTag): String {
|
||||
val content = docComment.getContent()
|
||||
val result = StringBuilder("<p>")
|
||||
result.append(markdownToHtml(content))
|
||||
val result = StringBuilder()
|
||||
result.append(markdownToHtml(content, allowSingleParagraph = true))
|
||||
if (docComment is KDocSection) {
|
||||
result.append("\n")
|
||||
val paramTags = docComment.findTagsByName("param").filter { it.getSubjectName() != null }
|
||||
@@ -47,7 +47,6 @@ object KDocRenderer {
|
||||
|
||||
renderSeeAlso(docComment, result)
|
||||
}
|
||||
result.append("</p>")
|
||||
return result.toString()
|
||||
}
|
||||
|
||||
@@ -85,13 +84,13 @@ object KDocRenderer {
|
||||
}
|
||||
}
|
||||
|
||||
fun markdownToHtml(markdown: String): String {
|
||||
fun markdownToHtml(markdown: String, allowSingleParagraph: Boolean = false): String {
|
||||
val markdownTree = MarkdownParser(CommonMarkMarkerProcessor.Factory).buildMarkdownTreeFromString(markdown)
|
||||
val markdownNode = MarkdownNode(markdownTree, null, markdown)
|
||||
|
||||
// Avoid wrapping the entire converted contents in a <p> tag if it's just a single paragraph
|
||||
val maybeSingleParagraph = markdownNode.children.filter { it.type != MarkdownTokenTypes.EOL }.singleOrNull()
|
||||
if (maybeSingleParagraph != null) {
|
||||
if (maybeSingleParagraph != null && !allowSingleParagraph) {
|
||||
return maybeSingleParagraph.children.map { it.toHtml() }.join("")
|
||||
} else {
|
||||
return markdownNode.toHtml()
|
||||
@@ -120,7 +119,6 @@ object KDocRenderer {
|
||||
visit { node, processChildren ->
|
||||
fun wrapChildren(tag: String, newline: Boolean = false) {
|
||||
sb.append("<$tag>")
|
||||
if (newline) sb.appendln()
|
||||
processChildren()
|
||||
sb.append("</$tag>")
|
||||
if (newline) sb.appendln()
|
||||
@@ -142,13 +140,13 @@ object KDocRenderer {
|
||||
MarkdownElementTypes.ATX_6 -> wrapChildren("h6")
|
||||
MarkdownElementTypes.BLOCK_QUOTE -> wrapChildren("blockquote")
|
||||
MarkdownElementTypes.PARAGRAPH -> {
|
||||
sb.trimTrailing()
|
||||
sb.trimEnd()
|
||||
wrapChildren("p", newline = true)
|
||||
}
|
||||
MarkdownElementTypes.CODE_SPAN -> wrapChildren("code")
|
||||
MarkdownElementTypes.CODE_BLOCK,
|
||||
MarkdownElementTypes.CODE_FENCE -> {
|
||||
sb.trimTrailing()
|
||||
sb.trimEnd()
|
||||
sb.append("<pre><code>")
|
||||
processChildren()
|
||||
sb.append("</code><pre>")
|
||||
@@ -168,7 +166,7 @@ object KDocRenderer {
|
||||
val label = node.child(MarkdownElementTypes.LINK_TEXT)?.child(MarkdownTokenTypes.TEXT)?.text
|
||||
val destination = node.child(MarkdownElementTypes.LINK_DESTINATION)?.text
|
||||
if (label != null && destination != null) {
|
||||
sb.append("a href=\"${destination}\">${label.htmlEscape()}</a>")
|
||||
sb.append("<a href=\"$destination\">${label.htmlEscape()}</a>")
|
||||
}
|
||||
else {
|
||||
sb.append(node.text)
|
||||
@@ -202,10 +200,10 @@ object KDocRenderer {
|
||||
}
|
||||
}
|
||||
}
|
||||
return sb.toString()
|
||||
return sb.toString().trimEnd()
|
||||
}
|
||||
|
||||
fun StringBuilder.trimTrailing() {
|
||||
fun StringBuilder.trimEnd() {
|
||||
while (length() > 0 && this[length() - 1] == ' ') {
|
||||
deleteCharAt(length() - 1)
|
||||
}
|
||||
|
||||
@@ -6,5 +6,4 @@ class KotlinClassUsedFromJava {
|
||||
}
|
||||
}
|
||||
|
||||
//INFO: <b>internal</b> <b>final</b> <b>class</b> Test <i>defined in</i> testing<br/><p>Some comment
|
||||
//INFO: </p>
|
||||
//INFO: <b>internal</b> <b>final</b> <b>class</b> Test <i>defined in</i> testing<p>Some comment</p>
|
||||
|
||||
+1
-2
@@ -2,5 +2,4 @@ fun test() {
|
||||
listOf(1, 2, 4).<caret>filter { it > 0 }
|
||||
}
|
||||
|
||||
//INFO: inline <b>public</b> <b>fun</b> <T> Iterable<T>.filter(predicate: (T) → Boolean): List<T> <i>defined in</i> kotlin<br/><p>Returns a list containing all elements matching the given <a href="psi_element://predicate">predicate</a>.
|
||||
//INFO: </p>
|
||||
//INFO: inline <b>public</b> <b>fun</b> <T> Iterable<T>.filter(predicate: (T) → Boolean): List<T> <i>defined in</i> kotlin<p>Returns a list containing all elements matching the given <a href="psi_element://predicate">predicate</a>.</p>
|
||||
|
||||
@@ -3,5 +3,4 @@
|
||||
*/
|
||||
class <caret>Some
|
||||
|
||||
//INFO: <b>internal</b> <b>final</b> <b>class</b> Some <i>defined in</i> root package<br/><p>Usefull comment
|
||||
//INFO: </p>
|
||||
//INFO: <b>internal</b> <b>final</b> <b>class</b> Some <i>defined in</i> root package<p>Usefull comment</p>
|
||||
|
||||
@@ -12,6 +12,5 @@ package test
|
||||
*/
|
||||
fun <caret>testFun(first: String, second: Int) = 12
|
||||
|
||||
//INFO: <b>internal</b> <b>fun</b> testFun(first: String, second: Int): Int <i>defined in</i> test<br/><p>Test function
|
||||
//INFO: <b>internal</b> <b>fun</b> testFun(first: String, second: Int): Int <i>defined in</i> test<p>Test function</p>
|
||||
//INFO: <dl><dt><b>Parameters:</b></dt><dd><code>first</code> - Some</dd><dd><code>second</code> - Other</dd></dl>
|
||||
//INFO: </p>
|
||||
|
||||
+1
-2
@@ -14,5 +14,4 @@ fun test() {
|
||||
D().f<caret>oo()
|
||||
}
|
||||
|
||||
//INFO: <b>internal</b> <b>open</b> <b>fun</b> foo(): Int <i>defined in</i> D<br/><p>This method returns zero.
|
||||
//INFO: </p>
|
||||
//INFO: <b>internal</b> <b>open</b> <b>fun</b> foo(): Int <i>defined in</i> D<p>This method returns zero.</p>
|
||||
|
||||
@@ -14,5 +14,4 @@ fun test() {
|
||||
D().f<caret>oo
|
||||
}
|
||||
|
||||
//INFO: <b>internal</b> <b>open</b> <b>val</b> foo: Int <i>defined in</i> D<br/><p>This property returns zero.
|
||||
//INFO: </p>
|
||||
//INFO: <b>internal</b> <b>open</b> <b>val</b> foo: Int <i>defined in</i> D<p>This property returns zero.</p>
|
||||
|
||||
+1
-2
@@ -12,6 +12,5 @@ fun test() {
|
||||
<caret>testMethod(1, "value")
|
||||
}
|
||||
|
||||
//INFO: <b>internal</b> <b>fun</b> testMethod(a: Int, b: String): Unit <i>defined in</i> root package<br/><p>Some documentation
|
||||
//INFO: <b>internal</b> <b>fun</b> testMethod(a: Int, b: String): Unit <i>defined in</i> root package<p>Some documentation</p>
|
||||
//INFO: <dl><dt><b>Parameters:</b></dt><dd><code>a</code> - Some int</dd><dd><code>b</code> - String</dd></dl>
|
||||
//INFO: </p>
|
||||
|
||||
+1
-2
@@ -10,5 +10,4 @@ fun test() {
|
||||
<caret>testMethod()
|
||||
}
|
||||
|
||||
//INFO: <b>internal</b> <b>fun</b> testMethod(): Unit <i>defined in</i> root package<br/><p>Some documentation on two lines.
|
||||
//INFO: </p>
|
||||
//INFO: <b>internal</b> <b>fun</b> testMethod(): Unit <i>defined in</i> root package<p>Some documentation on two lines.</p>
|
||||
|
||||
@@ -12,6 +12,5 @@ fun test() {
|
||||
<caret>testMethod(1, "value")
|
||||
}
|
||||
|
||||
//INFO: <b>internal</b> <b>fun</b> testMethod(a: Int, b: String): Unit <i>defined in</i> root package<br/><p>Some documentation
|
||||
//INFO: <b>internal</b> <b>fun</b> testMethod(a: Int, b: String): Unit <i>defined in</i> root package<p>Some documentation</p>
|
||||
//INFO: <dl><dt><b>Parameters:</b></dt><dd><code>a</code> - Some int</dd><dd><code>b</code> - String</dd></dl>
|
||||
//INFO: </p>
|
||||
|
||||
@@ -17,10 +17,8 @@ fun test() {
|
||||
<caret>testMethod(1, "value")
|
||||
}
|
||||
|
||||
//INFO: <b>internal</b> <b>fun</b> testMethod(): Unit <i>defined in</i> root package<br/><p><p>
|
||||
//INFO: Some documentation.</p>
|
||||
//INFO: <pre><code>
|
||||
//INFO: <b>internal</b> <b>fun</b> testMethod(): Unit <i>defined in</i> root package<p>Some documentation.</p>
|
||||
//INFO: <pre><code>
|
||||
//INFO: Code block
|
||||
//INFO: Second line
|
||||
//INFO: </code><pre>
|
||||
//INFO: </p>
|
||||
|
||||
+4
-10
@@ -18,13 +18,7 @@ fun test() {
|
||||
<caret>testMethod(1, "value")
|
||||
}
|
||||
|
||||
//INFO: <b>internal</b> <b>fun</b> testMethod(): Unit <i>defined in</i> root package<br/><p><p>
|
||||
//INFO: Some documentation. <strong>Bold</strong> <em>underline</em> <code>code</code> foo: bar (baz) <a href="psi_element://quux">quux</a> 'apos'</p>
|
||||
//INFO: <p>
|
||||
//INFO: a href="http://www.kotlinlang.org">Kotlin</a></p>
|
||||
//INFO: <p>
|
||||
//INFO: <a href="psi_element://C">C</a></p>
|
||||
//INFO: <p>
|
||||
//INFO: <a href="psi_element://C">See this class</a></p>
|
||||
//INFO:
|
||||
//INFO: </p>
|
||||
//INFO: <b>internal</b> <b>fun</b> testMethod(): Unit <i>defined in</i> root package<p>Some documentation. <strong>Bold</strong> <em>underline</em> <code>code</code> foo: bar (baz) <a href="psi_element://quux">quux</a> 'apos'</p>
|
||||
//INFO: <p><a href="http://www.kotlinlang.org">Kotlin</a></p>
|
||||
//INFO: <p><a href="psi_element://C">C</a></p>
|
||||
//INFO: <p><a href="psi_element://C">See this class</a></p>
|
||||
|
||||
@@ -14,8 +14,7 @@ fun test() {
|
||||
<caret>testMethod(1, "value")
|
||||
}
|
||||
|
||||
//INFO: <b>internal</b> <b>fun</b> testMethod(a: Int, b: String): Unit <i>defined in</i> root package<br/><p>Some documentation
|
||||
//INFO: <b>internal</b> <b>fun</b> testMethod(a: Int, b: String): Unit <i>defined in</i> root package<p>Some documentation</p>
|
||||
//INFO: <dl><dt><b>Parameters:</b></dt><dd><code>a</code> - Some int</dd><dd><code>b</code> - String</dd></dl>
|
||||
//INFO: <dl><dt><b>Returns:</b></dt><dd>Return value</dd></dl>
|
||||
//INFO: <dl><dt><b>Throws:</b></dt><dd><code>IllegalArgumentException</code> - if the weather is bad</dd></dl>
|
||||
//INFO: </p>
|
||||
|
||||
+2
-2
@@ -16,5 +16,5 @@ fun test() {
|
||||
<caret>testMethod(1, "value")
|
||||
}
|
||||
|
||||
//INFO: <b>internal</b> <b>fun</b> testMethod(): Unit <i>defined in</i> root package<br/><p>
|
||||
//INFO: <DD><DL><DT><b>See Also:</b><DD><a href="psi_element://C"><code>C</code></a>, <a href="psi_element://D"><code>D</code></a></DD></DL></DD></p>
|
||||
//INFO: <b>internal</b> <b>fun</b> testMethod(): Unit <i>defined in</i> root package<br/>
|
||||
//INFO: <DD><DL><DT><b>See Also:</b><DD><a href="psi_element://C"><code>C</code></a>, <a href="psi_element://D"><code>D</code></a></DD></DL></DD>
|
||||
|
||||
@@ -8,5 +8,4 @@ class Testing {
|
||||
}
|
||||
}
|
||||
|
||||
//INFO: <b>internal</b> <b>fun</b> foo(bar: Int): Unit <i>defined in</i> some<br/><p>KDoc foo
|
||||
//INFO: </p>
|
||||
//INFO: <b>internal</b> <b>fun</b> foo(bar: Int): Unit <i>defined in</i> some<p>KDoc foo</p>
|
||||
|
||||
Reference in New Issue
Block a user