diff options
-rw-r--r-- | .idea/libraries/jsoup.xml | 11 | ||||
-rw-r--r-- | dokka.iml | 1 | ||||
-rw-r--r-- | lib/jsoup-1.8.1-sources.jar | bin | 0 -> 124882 bytes | |||
-rw-r--r-- | lib/jsoup-1.8.1.jar | bin | 0 -> 300844 bytes | |||
-rw-r--r-- | src/Formats/MarkdownFormatService.kt | 4 | ||||
-rw-r--r-- | src/Java/JavaDocumentationBuilder.kt | 80 | ||||
-rw-r--r-- | test/data/format/javaDeprecated.html | 2 | ||||
-rw-r--r-- | test/data/format/javaLinkTag.html | 3 | ||||
-rw-r--r-- | test/data/format/javadocHtml.java | 16 | ||||
-rw-r--r-- | test/data/format/javadocHtml.md | 20 | ||||
-rw-r--r-- | test/src/format/MarkdownFormatTest.kt | 6 |
11 files changed, 121 insertions, 22 deletions
diff --git a/.idea/libraries/jsoup.xml b/.idea/libraries/jsoup.xml new file mode 100644 index 00000000..9e4803f4 --- /dev/null +++ b/.idea/libraries/jsoup.xml @@ -0,0 +1,11 @@ +<component name="libraryTable"> + <library name="jsoup"> + <CLASSES> + <root url="jar://$PROJECT_DIR$/lib/jsoup-1.8.1.jar!/" /> + </CLASSES> + <JAVADOC /> + <SOURCES> + <root url="jar://$PROJECT_DIR$/lib/jsoup-1.8.1-sources.jar!/" /> + </SOURCES> + </library> +</component>
\ No newline at end of file @@ -14,5 +14,6 @@ <orderEntry type="library" name="kotlin-compiler" level="project" /> <orderEntry type="library" name="junit:junit:4.11" level="project" /> <orderEntry type="library" name="markdown" level="project" /> + <orderEntry type="library" name="jsoup" level="project" /> </component> </module>
\ No newline at end of file diff --git a/lib/jsoup-1.8.1-sources.jar b/lib/jsoup-1.8.1-sources.jar Binary files differnew file mode 100644 index 00000000..3b7aea4a --- /dev/null +++ b/lib/jsoup-1.8.1-sources.jar diff --git a/lib/jsoup-1.8.1.jar b/lib/jsoup-1.8.1.jar Binary files differnew file mode 100644 index 00000000..ae717d45 --- /dev/null +++ b/lib/jsoup-1.8.1.jar diff --git a/src/Formats/MarkdownFormatService.kt b/src/Formats/MarkdownFormatService.kt index cc7d7170..8809fa96 100644 --- a/src/Formats/MarkdownFormatService.kt +++ b/src/Formats/MarkdownFormatService.kt @@ -27,9 +27,7 @@ public open class MarkdownFormatService(locationService: LocationService, return "`$code`" } - override public fun formatList(text: String): String { - return text - } + override public fun formatList(text: String): String = text + "\n" override fun formatListItem(text: String): String { return "* $text" diff --git a/src/Java/JavaDocumentationBuilder.kt b/src/Java/JavaDocumentationBuilder.kt index 8183df8f..8a5d8fb9 100644 --- a/src/Java/JavaDocumentationBuilder.kt +++ b/src/Java/JavaDocumentationBuilder.kt @@ -6,6 +6,10 @@ import com.intellij.psi.javadoc.PsiDocTag import com.intellij.psi.javadoc.PsiDocTagValue import com.intellij.psi.javadoc.PsiInlineDocTag import org.jetbrains.dokka.DocumentationNode.Kind +import org.jsoup.Jsoup +import org.jsoup.nodes.Element +import org.jsoup.nodes.Node +import org.jsoup.nodes.TextNode public class JavaDocumentationBuilder(private val options: DocumentationOptions, private val refGraph: NodeReferenceGraph) { @@ -46,21 +50,65 @@ public class JavaDocumentationBuilder(private val options: DocumentationOptions, } private fun ContentBlock.convertJavadocElements(elements: Iterable<PsiElement>) { + val htmlBuilder = StringBuilder() elements.forEach { if (it is PsiInlineDocTag) { - append(convertInlineDocTag(it)) + htmlBuilder.append(convertInlineDocTag(it)) } else { - val text = if (isEmpty()) it.getText().trimLeading() else it.getText() - append(ContentText(text)) + htmlBuilder.append(it.getText()) } } + val doc = Jsoup.parse(htmlBuilder.toString().trimLeading()) + doc.body().childNodes().forEach { + convertHtmlNode(it) + } + } + + private fun ContentBlock.convertHtmlNode(node: Node) { + if (node is TextNode) { + append(ContentText(node.text())) + } else if (node is Element) { + val childBlock = createBlock(node) + node.childNodes().forEach { + childBlock.convertHtmlNode(it) + } + append(childBlock) + } + } + + private fun createBlock(element: Element): ContentBlock = when(element.tagName()) { + "p" -> ContentParagraph() + "b", "strong" -> ContentStrong() + "i", "em" -> ContentEmphasis() + "s", "del" -> ContentStrikethrough() + "code" -> ContentCode() + "pre" -> ContentBlockCode() + "ul" -> ContentList() + "li" -> ContentListItem() + "a" -> createLink(element) + else -> ContentBlock() + } + + private fun createLink(element: Element): ContentBlock { + val href = element.attr("href") + if (href != null) { + if (href.startsWith("##")) { + val signature = href.substring(2) + return ContentNodeLazyLink(signature, {() -> refGraph.lookup(signature)}) + } else { + return ContentExternalLink(href) + } + } else { + return ContentBlock() + } } private fun MutableContent.convertSeeTag(tag: PsiDocTag) { val seeSection = findSectionByTag("See Also") ?: addSection("See Also", null) - val linkNode = resolveLink(tag.getValueElement()) + val linkSignature = resolveLink(tag.getValueElement()) val text = ContentText(tag.getValueElement()!!.getText()) - if (linkNode != null) { + if (linkSignature != null) { + val linkNode = ContentNodeLazyLink(tag.getValueElement()!!.getText(), {() -> refGraph.lookup(linkSignature)}) linkNode.append(text) seeSection.append(linkNode) } else { @@ -70,23 +118,23 @@ public class JavaDocumentationBuilder(private val options: DocumentationOptions, private fun convertInlineDocTag(tag: PsiInlineDocTag) = when (tag.getName()) { "link", "linkplain" -> { - val link = resolveLink(tag.getValueElement()) - if (link != null) { - link.append(ContentText(tag.getValueElement()!!.getText())) - link + val valueElement = tag.getValueElement() + val linkSignature = resolveLink(valueElement) + if (linkSignature != null) { + val link = "<a href=\"##$linkSignature\">${valueElement!!.getText().htmlEscape()}</a>" + if (tag.getName() == "link") "<code>$link</code>" else link + } + else { + valueElement!!.getText() } - else ContentText(tag.getValueElement()!!.getText()) } - else -> ContentText(tag.getText()) + else -> tag.getText() } - private fun resolveLink(valueElement: PsiDocTagValue?): ContentBlock? { + private fun resolveLink(valueElement: PsiDocTagValue?): String? { val target = valueElement?.getReference()?.resolve() if (target != null) { - val signature = getSignature(target) - if (signature != null) { - return ContentNodeLazyLink(valueElement!!.getText(), {() -> refGraph.lookup(signature)}) - } + return getSignature(target) } return null } diff --git a/test/data/format/javaDeprecated.html b/test/data/format/javaDeprecated.html index ca818bb7..f9376bf5 100644 --- a/test/data/format/javaDeprecated.html +++ b/test/data/format/javaDeprecated.html @@ -7,7 +7,7 @@ <br/> <h1>foo</h1> <code><span class="keyword">public</span> <span class="keyword">open</span> <span class="keyword">fun </span><s><span class="identifier">foo</span></s><span class="symbol">(</span><span class="symbol">)</span><span class="symbol">: </span><span class="identifier">Unit</span></code><br/> -<strong>Deprecated:</strong> use<a href="test/test/-foo/bar">#bar</a> instead <p></p> +<strong>Deprecated:</strong> use<code><a href="test/test/-foo/bar">#bar</a></code> instead <p></p> <br/> <br/> </BODY> diff --git a/test/data/format/javaLinkTag.html b/test/data/format/javaLinkTag.html index d6ced4ce..af63710d 100644 --- a/test/data/format/javaLinkTag.html +++ b/test/data/format/javaLinkTag.html @@ -7,8 +7,7 @@ <br/> <h1>Foo</h1> <code><span class="keyword">open</span> <span class="keyword">class </span><span class="identifier">Foo</span></code><br/> -<p>Call <a href="test/test/-foo/bar">#bar()</a> to do the job. - </p> +<p>Call <code><a href="test/test/-foo/bar">#bar()</a></code> to do the job. </p> <br/> <br/> <h3>Functions</h3> diff --git a/test/data/format/javadocHtml.java b/test/data/format/javadocHtml.java new file mode 100644 index 00000000..bcb2cf91 --- /dev/null +++ b/test/data/format/javadocHtml.java @@ -0,0 +1,16 @@ +package test; + +/** + * <b>Bold</b> + * <strong>Strong</strong> + * <i>Italic</i> + * <em>Emphasized</em> + * <p>Paragraph</p> + * <s>Strikethrough</s> + * <del>Deleted</del> + * <code>Code</code> + * <pre>Block code</pre> + * <ul><li>List Item</li></ul> + */ +public class C { +} diff --git a/test/data/format/javadocHtml.md b/test/data/format/javadocHtml.md new file mode 100644 index 00000000..303b102c --- /dev/null +++ b/test/data/format/javadocHtml.md @@ -0,0 +1,20 @@ +[test](test/index) / [test](test/test/index) / [C](test/test/-c) + + +# C + +`public open class C` + +**Bold** **Strong** *Italic* *Emphasized* +Paragraph + + ~~Strikethrough~~ ~~Deleted~~ `Code` +``` +Block code +``` + + * List Item + + + + diff --git a/test/src/format/MarkdownFormatTest.kt b/test/src/format/MarkdownFormatTest.kt index 4b207b75..7253ddb4 100644 --- a/test/src/format/MarkdownFormatTest.kt +++ b/test/src/format/MarkdownFormatTest.kt @@ -118,4 +118,10 @@ public class MarkdownFormatTest { markdownService.appendNodes(tempLocation, output, model.members.single().members) } } + + Test fun javadocHtml() { + verifyOutput("test/data/format/javadocHtml.java", ".md") { model, output -> + markdownService.appendNodes(tempLocation, output, model.members.single().members) + } + } } |