aboutsummaryrefslogtreecommitdiff
path: root/plugins/base
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/base')
-rw-r--r--plugins/base/src/main/kotlin/parsers/MarkdownParser.kt83
-rw-r--r--plugins/base/src/main/kotlin/parsers/factories/DocTagsFromIElementFactory.kt4
-rw-r--r--plugins/base/src/test/kotlin/markdown/ParserTest.kt119
3 files changed, 174 insertions, 32 deletions
diff --git a/plugins/base/src/main/kotlin/parsers/MarkdownParser.kt b/plugins/base/src/main/kotlin/parsers/MarkdownParser.kt
index 8c7f9257..a74f2b05 100644
--- a/plugins/base/src/main/kotlin/parsers/MarkdownParser.kt
+++ b/plugins/base/src/main/kotlin/parsers/MarkdownParser.kt
@@ -1,9 +1,7 @@
package org.jetbrains.dokka.base.parsers
import com.intellij.psi.PsiElement
-import org.intellij.markdown.MarkdownElementType
import org.intellij.markdown.MarkdownElementTypes
-import org.intellij.markdown.MarkdownElementTypes.LINK_DESTINATION
import org.intellij.markdown.MarkdownTokenTypes
import org.intellij.markdown.ast.ASTNode
import org.intellij.markdown.ast.CompositeASTNode
@@ -208,6 +206,46 @@ class MarkdownParser(
}
}
+ private fun codeLineHandler(node: ASTNode) = DocTagsFromIElementFactory.getInstance(
+ MarkdownElementTypes.CODE_BLOCK,
+ body = text.substring(node.startOffset, node.endOffset)
+ )
+
+ private fun textHandler(node: ASTNode) = DocTagsFromIElementFactory.getInstance(
+ MarkdownTokenTypes.TEXT,
+ body = text.substring(node.startOffset, node.endOffset).transform()
+ )
+
+ private fun markdownFileHandler(node: ASTNode) = if (node.children.size == 1)
+ visitNode(node.children.first())
+ else
+ defaultHandler(node)
+
+ private fun strikeThroughHandler(node: ASTNode) = DocTagsFromIElementFactory.getInstance(
+ GFMElementTypes.STRIKETHROUGH,
+ body = text.substring(node.startOffset, node.endOffset).transform()
+ )
+
+ private fun tableHandler(node: ASTNode) = DocTagsFromIElementFactory.getInstance(
+ GFMElementTypes.TABLE,
+ children = node.children.filterTabSeparators().evaluateChildren()
+ )
+
+ private fun headerHandler(node: ASTNode) = DocTagsFromIElementFactory.getInstance(
+ GFMElementTypes.HEADER,
+ children = node.children.filterTabSeparators().evaluateChildren()
+ )
+
+ private fun rowHandler(node: ASTNode) = DocTagsFromIElementFactory.getInstance(
+ GFMElementTypes.ROW,
+ children = node.children.filterTabSeparators().evaluateChildren()
+ )
+
+ private fun cellHandler(node: ASTNode) = DocTagsFromIElementFactory.getInstance(
+ GFMTokenTypes.CELL,
+ children = node.children.filterTabSeparators().evaluateChildren().trimSurroundingTokensIfText()
+ )
+
private fun String.isRemoteLink() = try {
URL(this)
true
@@ -304,34 +342,14 @@ class MarkdownParser(
MarkdownElementTypes.IMAGE -> imagesHandler(node)
MarkdownTokenTypes.HARD_LINE_BREAK -> DocTagsFromIElementFactory.getInstance(node.type)
MarkdownTokenTypes.CODE_FENCE_CONTENT,
- MarkdownTokenTypes.CODE_LINE -> DocTagsFromIElementFactory.getInstance(
- MarkdownElementTypes.CODE_BLOCK,
- body = text.substring(node.startOffset, node.endOffset)
- )
- MarkdownTokenTypes.TEXT -> DocTagsFromIElementFactory.getInstance(
- MarkdownTokenTypes.TEXT,
- body = text.substring(node.startOffset, node.endOffset).transform()
- )
- MarkdownElementTypes.MARKDOWN_FILE -> if (node.children.size == 1) visitNode(node.children.first()) else defaultHandler(
- node
- )
- GFMElementTypes.STRIKETHROUGH -> DocTagsFromIElementFactory.getInstance(
- GFMElementTypes.STRIKETHROUGH,
- body = text
- .substring(node.startOffset, node.endOffset).transform()
- )
- GFMElementTypes.TABLE -> DocTagsFromIElementFactory.getInstance(
- GFMElementTypes.TABLE,
- children = node.children.filterTabSeparators().evaluateChildren()
- )
- GFMElementTypes.HEADER -> DocTagsFromIElementFactory.getInstance(
- GFMElementTypes.HEADER,
- children = node.children.filterTabSeparators().evaluateChildren()
- )
- GFMElementTypes.ROW -> DocTagsFromIElementFactory.getInstance(
- GFMElementTypes.ROW,
- children = node.children.filterTabSeparators().evaluateChildren()
- )
+ MarkdownTokenTypes.CODE_LINE -> codeLineHandler(node)
+ MarkdownTokenTypes.TEXT -> textHandler(node)
+ MarkdownElementTypes.MARKDOWN_FILE -> markdownFileHandler(node)
+ GFMElementTypes.STRIKETHROUGH -> strikeThroughHandler(node)
+ GFMElementTypes.TABLE -> tableHandler(node)
+ GFMElementTypes.HEADER -> headerHandler(node)
+ GFMElementTypes.ROW -> rowHandler(node)
+ GFMTokenTypes.CELL -> cellHandler(node)
else -> defaultHandler(node)
}
@@ -349,6 +367,11 @@ class MarkdownParser(
))
}
+ private fun List<DocTag>.trimSurroundingTokensIfText() = mapIndexed { index, elem ->
+ val elemTransformed = if (index == 0 && elem is Text) elem.copy(elem.body.trimStart()) else elem
+ if (index == size - 1 && elemTransformed is Text) elemTransformed.copy(elemTransformed.body.trimEnd()) else elemTransformed
+ }
+
private val notLeafNodes = listOf(MarkdownTokenTypes.HORIZONTAL_RULE, MarkdownTokenTypes.HARD_LINE_BREAK)
private fun List<ASTNode>.isNotLeaf(index: Int): Boolean =
diff --git a/plugins/base/src/main/kotlin/parsers/factories/DocTagsFromIElementFactory.kt b/plugins/base/src/main/kotlin/parsers/factories/DocTagsFromIElementFactory.kt
index 277fd35e..58b4b223 100644
--- a/plugins/base/src/main/kotlin/parsers/factories/DocTagsFromIElementFactory.kt
+++ b/plugins/base/src/main/kotlin/parsers/factories/DocTagsFromIElementFactory.kt
@@ -5,6 +5,7 @@ import org.intellij.markdown.IElementType
import org.intellij.markdown.MarkdownElementTypes
import org.intellij.markdown.MarkdownTokenTypes
import org.intellij.markdown.flavours.gfm.GFMElementTypes
+import org.intellij.markdown.flavours.gfm.GFMTokenTypes
import org.jetbrains.dokka.links.DRI
import java.lang.NullPointerException
@@ -38,6 +39,7 @@ object DocTagsFromIElementFactory {
GFMElementTypes.TABLE -> Table(children, params)
GFMElementTypes.HEADER -> Th(children, params)
GFMElementTypes.ROW -> Tr(children, params)
+ GFMTokenTypes.CELL -> Td(children, params)
else -> CustomDocTag(children, params)
}
-} \ No newline at end of file
+}
diff --git a/plugins/base/src/test/kotlin/markdown/ParserTest.kt b/plugins/base/src/test/kotlin/markdown/ParserTest.kt
index e127afc2..268af405 100644
--- a/plugins/base/src/test/kotlin/markdown/ParserTest.kt
+++ b/plugins/base/src/test/kotlin/markdown/ParserTest.kt
@@ -1169,7 +1169,7 @@ class ParserTest : KDocTest() {
}
@Test
- fun image(){
+ fun image() {
val kdoc = "![Sample image](https://www.google.pl/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png)"
val expectedDocumentationNode = DocumentationNode(
listOf(
@@ -1190,5 +1190,122 @@ class ParserTest : KDocTest() {
)
executeTest(kdoc, expectedDocumentationNode)
}
+
+ @Test
+ fun `Bold + italic + link`() {
+ val kdoc = "It's very easy to make some words **bold** and other words *italic* with Markdown.\n" +
+ "You can even [link to Google!](http://google.com)"
+ val expectedDocumentationNode = DocumentationNode(
+ listOf(
+ Description(
+ P(
+ listOf(
+ Text("It's very easy to make some words "),
+ B(listOf(Text("bold"))),
+ Text(" and other words "),
+ I(listOf(Text("italic"))),
+ Text(" with Markdown. You can even "),
+ A(listOf(Text("link to Google!")), mapOf("href" to "http://google.com"))
+ )
+ )
+ )
+ )
+ )
+ executeTest(kdoc, expectedDocumentationNode)
+ }
+
+ @Test
+ fun `Codeblock from indent`() {
+ val kdoc = "Here is some example how to use conditional instructions:\n\n" +
+ " val x = 1\n" +
+ " val y = 2\n" +
+ " if (x == 1) {\n" +
+ " println(y)\n" +
+ " }"
+ val expectedDocumentationNode = DocumentationNode(
+ listOf(
+ Description(
+ P(
+ listOf(
+ P(listOf(Text("Here is some example how to use conditional instructions:"))),
+ CodeBlock(
+ listOf(
+ Text(
+ " val x = 1\n" +
+ " val y = 2\n" +
+ " if (x == 1) {\n" +
+ " println(y)\n" +
+ " }"
+ )
+ )
+ )
+ )
+ )
+ )
+ )
+ )
+ executeTest(kdoc, expectedDocumentationNode)
+ }
+
+ @Test
+ fun `Table`() {
+ val kdoc = "First Header | Second Header\n" +
+ "------------ | -------------\n" +
+ "Content from cell 1 | Content from cell 2\n" +
+ "Content in the first column | Content in the second column"
+ val expectedDocumentationNode = DocumentationNode(
+ listOf(
+ Description(
+ Table(
+ listOf(
+ Th(
+ listOf(
+ Td(
+ listOf(
+ Text("First Header")
+ )
+ ),
+ Td(
+ listOf(
+ Text("Second Header")
+ )
+ )
+ )
+ ),
+ Tr(
+ listOf(
+ Td(
+ listOf(
+ Text("Content from cell 1")
+ )
+ ),
+ Td(
+ listOf(
+ Text("Content from cell 2")
+ )
+ )
+ )
+ ),
+ Tr(
+ listOf(
+ Td(
+ listOf(
+ Text("Content in the first column")
+ )
+ ),
+ Td(
+ listOf(
+ Text("Content in the second column")
+ )
+ )
+ )
+ )
+ )
+ )
+ )
+ )
+ )
+ executeTest(kdoc, expectedDocumentationNode)
+ }
}