Skip to content

Commit

Permalink
Render code blocks in KDoc
Browse files Browse the repository at this point in the history
  • Loading branch information
yole committed Jul 30, 2015
1 parent 909d094 commit b483713
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 8 deletions.
31 changes: 23 additions & 8 deletions idea/src/org/jetbrains/kotlin/idea/kdoc/KDocRenderer.kt
Expand Up @@ -90,7 +90,7 @@ object KDocRenderer {
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 == MarkdownElementTypes.PARAGRAPH }.singleOrNull()
val maybeSingleParagraph = markdownNode.children.filter { it.type != MarkdownTokenTypes.EOL }.singleOrNull()
if (maybeSingleParagraph != null) {
return maybeSingleParagraph.children.map { it.toHtml() }.join("")
} else {
Expand Down Expand Up @@ -142,13 +142,13 @@ object KDocRenderer {
MarkdownElementTypes.ATX_6 -> wrapChildren("h6")
MarkdownElementTypes.BLOCK_QUOTE -> wrapChildren("blockquote")
MarkdownElementTypes.PARAGRAPH -> {
while (sb.length() > 0 && sb[sb.length() - 1] == ' ') {
sb.deleteCharAt(sb.length() - 1)
}
sb.trimTrailing()
wrapChildren("p", newline = true)
}
MarkdownElementTypes.CODE_SPAN -> wrapChildren("code")
MarkdownElementTypes.CODE_BLOCK -> {
MarkdownElementTypes.CODE_BLOCK,
MarkdownElementTypes.CODE_FENCE -> {
sb.trimTrailing()
sb.append("<pre><code>")
processChildren()
sb.append("</code><pre>")
Expand All @@ -159,7 +159,8 @@ object KDocRenderer {
if (label != null) {
val linkText = node.child(MarkdownElementTypes.LINK_TEXT)?.child(MarkdownTokenTypes.TEXT)?.text ?: label
DocumentationManagerUtil.createHyperlink(sb, label, linkText, true)
} else {
}
else {
sb.append(node.text)
}
}
Expand All @@ -168,11 +169,13 @@ object KDocRenderer {
val destination = node.child(MarkdownElementTypes.LINK_DESTINATION)?.text
if (label != null && destination != null) {
sb.append("a href=\"${destination}\">${label.htmlEscape()}</a>")
} else {
}
else {
sb.append(node.text)
}
}
MarkdownTokenTypes.TEXT,
MarkdownTokenTypes.CODE,
MarkdownTokenTypes.WHITE_SPACE,
MarkdownTokenTypes.COLON,
MarkdownTokenTypes.SINGLE_QUOTE,
Expand All @@ -184,7 +187,13 @@ object KDocRenderer {
sb.append(nodeText)
}
MarkdownTokenTypes.EOL -> {
sb.append(" ")
val parentType = node.parent?.type
if (parentType == MarkdownElementTypes.CODE_BLOCK || parentType == MarkdownElementTypes.CODE_FENCE) {
sb.append("\n")
}
else {
sb.append(" ")
}
}
MarkdownTokenTypes.GT -> sb.append("&gt;")
MarkdownTokenTypes.LT -> sb.append("&lt;")
Expand All @@ -196,5 +205,11 @@ object KDocRenderer {
return sb.toString()
}

fun StringBuilder.trimTrailing() {
while (length() > 0 && this[length() - 1] == ' ') {
deleteCharAt(length() - 1)
}
}

fun String.htmlEscape(): String = replace("&", "&amp;").replace("<", "&lt;").replace(">", "&gt;")
}
26 changes: 26 additions & 0 deletions idea/testData/editor/quickDoc/OnMethodUsageWithCodeBlock.kt
@@ -0,0 +1,26 @@
/**
* Some documentation.
*
* ```
* Code block
* Second line
* ```
*/
fun testMethod() {

}

class C {
}

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: Code block
//INFO: Second line
//INFO: </code><pre>
//INFO: </p>
Expand Up @@ -125,6 +125,12 @@ public void testOnMethodUsageWithBracketsInParam() throws Exception {
doTest(fileName);
}

@TestMetadata("OnMethodUsageWithCodeBlock.kt")
public void testOnMethodUsageWithCodeBlock() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/editor/quickDoc/OnMethodUsageWithCodeBlock.kt");
doTest(fileName);
}

@TestMetadata("OnMethodUsageWithMarkdown.kt")
public void testOnMethodUsageWithMarkdown() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/editor/quickDoc/OnMethodUsageWithMarkdown.kt");
Expand Down

0 comments on commit b483713

Please sign in to comment.