diff options
-rw-r--r-- | core/src/main/kotlin/pages/ContentNodes.kt | 39 | ||||
-rw-r--r-- | core/src/main/kotlin/pages/NewContentBuilder.kt | 156 | ||||
-rw-r--r-- | core/src/main/kotlin/renderers/DefaultRenderer.kt | 20 | ||||
-rw-r--r-- | core/src/test/kotlin/markdownParser/MarkdownParserTest.kt | 28 |
4 files changed, 215 insertions, 28 deletions
diff --git a/core/src/main/kotlin/pages/ContentNodes.kt b/core/src/main/kotlin/pages/ContentNodes.kt index 6519c313..afb81995 100644 --- a/core/src/main/kotlin/pages/ContentNodes.kt +++ b/core/src/main/kotlin/pages/ContentNodes.kt @@ -20,28 +20,29 @@ data class ContentText(val text: String, ): ContentNode ///** Headers */ TODO for next iteration -//data class ContentHeader(val text: String, -// val level: Int, -// override val platforms: List<PlatformData>, -// override val annotations: List<Annotation> = emptyList() -//): ContentNode -// -///** Lists */ -//data class ContentList(val items: List<ContentNode>, -// val ordered: Boolean, -// override val platforms: List<PlatformData>, -// override val annotations: List<Annotation> = emptyList() -//): ContentNode -// -///** Styled elements, eg. bold, strikethrough, emphasis and so on **/ -//data class ContentStyle(val items: List<ContentNode>, -// val ordered: Boolean, -// override val platforms: List<PlatformData>, -// override val annotations: List<Annotation> = emptyList() -//): ContentNode +data class ContentHeader(val text: String, + val level: Int, + override val platforms: List<PlatformData>, + override val annotations: List<Annotation> = emptyList() +): ContentNode + +/** Lists */ +data class ContentList(val items: List<ContentNode>, + val ordered: Boolean, + override val platforms: List<PlatformData>, + override val annotations: List<Annotation> = emptyList() +): ContentNode + +/** Styled elements, eg. bold, strikethrough, emphasis and so on **/ +data class ContentStyle(val items: List<ContentNode>, + val style: ContentNode, + override val platforms: List<PlatformData>, + override val annotations: List<Annotation> = emptyList() +): ContentNode /** Code blocks */ data class ContentCode(val code: String, + val language: String, override val platforms: List<PlatformData>, override val annotations: List<Annotation> = emptyList() ): ContentNode diff --git a/core/src/main/kotlin/pages/NewContentBuilder.kt b/core/src/main/kotlin/pages/NewContentBuilder.kt new file mode 100644 index 00000000..05b649d1 --- /dev/null +++ b/core/src/main/kotlin/pages/NewContentBuilder.kt @@ -0,0 +1,156 @@ +package org.jetbrains.dokka.pages + +import org.intellij.markdown.MarkdownElementTypes +import org.intellij.markdown.MarkdownTokenTypes +import org.jetbrains.dokka.MarkdownNode + +fun buildContent(node: MarkdownNode, platforms: List<PlatformData>): List<ContentNode> { +// println(tree.toTestString()) + + fun buildChildren(node: MarkdownNode) = node.children.flatMap{ buildContent(it, platforms)} + + return when (node.type) { + MarkdownElementTypes.ATX_1 -> ContentHeader(node.text, 1, platforms) // TODO Header levels: ?? + MarkdownElementTypes.ATX_2 -> ContentHeader("", 2, platforms) + MarkdownElementTypes.ATX_3 -> ContentHeader("", 3, platforms) + MarkdownElementTypes.ATX_4 -> ContentHeader("", 4, platforms) + MarkdownElementTypes.ATX_5 -> ContentHeader("", 5, platforms) + MarkdownElementTypes.ATX_6 -> ContentHeader("", 6, platforms) + MarkdownElementTypes.UNORDERED_LIST -> ContentList(buildChildren(node), false, platforms) + MarkdownElementTypes.ORDERED_LIST -> ContentList(buildChildren(node), true, platforms) + MarkdownElementTypes.LIST_ITEM -> TODO() + MarkdownElementTypes.EMPH -> ContentStyle(buildChildren(node), ContentText("", platforms), platforms) // TODO + MarkdownElementTypes.STRONG -> ContentStyle(buildChildren(node), ContentText("", platforms), platforms) // TODO + MarkdownElementTypes.CODE_SPAN -> TODO() +// val startDelimiter = node.child(MarkdownTokenTypes.BACKTICK)?.text +// if (startDelimiter != null) { +// val text = node.text.substring(startDelimiter.length).removeSuffix(startDelimiter) +// val codeSpan = ContentCode().apply { append(ContentText(text)) } +// parent.append(codeSpan) +// } + + MarkdownElementTypes.CODE_BLOCK, + MarkdownElementTypes.CODE_FENCE -> { + val language = node.child(MarkdownTokenTypes.FENCE_LANG)?.text?.trim() ?: "" + ContentCode(buildChildren(node).toString(), language, platforms) // TODO + } + MarkdownElementTypes.PARAGRAPH -> ContentText(buildChildren(node).toString(), platforms) // TODO + + MarkdownElementTypes.INLINE_LINK -> { +// val linkTextNode = node.child(MarkdownElementTypes.LINK_TEXT) +// val destination = node.child(MarkdownElementTypes.LINK_DESTINATION) +// if (linkTextNode != null) { +// if (destination != null) { +// val link = ContentExternalLink(destination.text) +// renderLinkTextTo(linkTextNode, link, linkResolver) +// parent.append(link) +// } else { +// val link = ContentExternalLink(linkTextNode.getLabelText()) +// renderLinkTextTo(linkTextNode, link, linkResolver) +// parent.append(link) +// } +// } + //TODO: Linking!!! +// ContentLink() + TODO() + } + MarkdownElementTypes.SHORT_REFERENCE_LINK, + MarkdownElementTypes.FULL_REFERENCE_LINK -> { +// val labelElement = node.child(MarkdownElementTypes.LINK_LABEL) +// if (labelElement != null) { +// val linkInfo = linkResolver.getLinkInfo(labelElement.text) +// val labelText = labelElement.getLabelText() +// val link = +// linkInfo?.let { linkResolver.resolve(it.destination.toString()) } ?: linkResolver.resolve( +// labelText +// ) +// val linkText = node.child(MarkdownElementTypes.LINK_TEXT) +// if (linkText != null) { +// renderLinkTextTo(linkText, link, linkResolver) +// } else { +// link.append(ContentText(labelText)) +// } +// parent.append(link) +// } + TODO() + } + MarkdownTokenTypes.WHITE_SPACE -> { + // Don't append first space if start of header (it is added during formatting later) + // v + // #### Some Heading +// if (nodeStack.peek() !is ContentHeading || node.parent?.children?.first() != node) { +// parent.append(ContentText(node.text)) +// } + ContentText(" ", platforms) + } + MarkdownTokenTypes.EOL -> { +// if ((keepEol(nodeStack.peek()) && node.parent?.children?.last() != node) || +// // Keep extra blank lines when processing lists (affects Markdown formatting) +// (processingList(nodeStack.peek()) && node.previous?.type == MarkdownTokenTypes.EOL)) { +// parent.append(ContentText(node.text)) +// } + ContentText("\n", platforms) // TODO? + } + + MarkdownTokenTypes.CODE_LINE -> { + ContentText(node.text, platforms) // TODO check +// if (parent is ContentBlockCode) { +// parent.append(content) +// } else { +// parent.append(ContentBlockCode().apply { append(content) }) +// } + } + + MarkdownTokenTypes.TEXT -> +// fun createEntityOrText(text: String): ContentNode { +// if (text == "&" || text == """ || text == "<" || text == ">") { +// return ContentEntity(text) +// } +// if (text == "&") { +// return ContentEntity("&") +// } +// val decodedText = EntityConverter.replaceEntities(text, true, true) +// if (decodedText != text) { +// return ContentEntity(text) +// } +// return ContentText(text) +// } +// +// parent.append(createEntityOrText(node.text)) + ContentText(node.text, platforms) // TODO + + + MarkdownTokenTypes.EMPH -> +// val parentNodeType = node.parent?.type +// if (parentNodeType != MarkdownElementTypes.EMPH && parentNodeType != MarkdownElementTypes.STRONG) { +// parent.append(ContentText(node.text)) +// } + ContentStyle(buildChildren(node), ContentText("", platforms), platforms) // TODO + + + MarkdownTokenTypes.COLON, + MarkdownTokenTypes.SINGLE_QUOTE, + MarkdownTokenTypes.DOUBLE_QUOTE, + MarkdownTokenTypes.LT, + MarkdownTokenTypes.GT, + MarkdownTokenTypes.LPAREN, + MarkdownTokenTypes.RPAREN, + MarkdownTokenTypes.LBRACKET, + MarkdownTokenTypes.RBRACKET, + MarkdownTokenTypes.EXCLAMATION_MARK, + MarkdownTokenTypes.BACKTICK, + MarkdownTokenTypes.CODE_FENCE_CONTENT -> { + ContentText(node.text, platforms) + } + + MarkdownElementTypes.LINK_DEFINITION -> TODO() + + + MarkdownTokenTypes.EMAIL_AUTOLINK -> + ContentText(node.text, platforms) // TODO: create new ContentType for email to create mailto: links + + + else -> ContentText("", platforms) + + }.let {listOf(it)} +}
\ No newline at end of file diff --git a/core/src/main/kotlin/renderers/DefaultRenderer.kt b/core/src/main/kotlin/renderers/DefaultRenderer.kt index b2647d22..7dab7c5c 100644 --- a/core/src/main/kotlin/renderers/DefaultRenderer.kt +++ b/core/src/main/kotlin/renderers/DefaultRenderer.kt @@ -16,15 +16,17 @@ abstract class DefaultRenderer(val outputDir: String, val fileWriter: FileWriter protected open fun buildSymbol(parts: List<ContentNode>): String = parts.joinToString { it.build() } protected open fun buildBlock(name: String, content: List<ContentNode>) = buildHeader(2, name) + content.joinToString("\n") { it.build() } - protected open fun ContentNode.build(): String = - when(this) { - is ContentText -> buildText(this.text) - is ContentComment -> buildComment(this.parts) - is ContentSymbol -> buildSymbol(this.parts) - is ContentCode -> buildCode(this.code) - is ContentBlock -> buildBlock(this.name, this.children) - is ContentLink -> buildLink(this.text, locationProvider.resolve(this.address, this.platforms)) - is ContentGroup -> buildGroup(this.children) + protected open fun ContentNode.build(): String = buildContentNode(this) + + protected open fun buildContentNode(node: ContentNode) = + when(node) { + is ContentText -> buildText(node.text) + is ContentComment -> buildComment(node.parts) + is ContentSymbol -> buildSymbol(node.parts) + is ContentCode -> buildCode(node.code) + is ContentBlock -> buildBlock(node.name, node.children) + is ContentLink -> buildLink(node.text, locationProvider.resolve(node.address, node.platforms)) + is ContentGroup -> buildGroup(node.children) else -> "" } diff --git a/core/src/test/kotlin/markdownParser/MarkdownParserTest.kt b/core/src/test/kotlin/markdownParser/MarkdownParserTest.kt new file mode 100644 index 00000000..466d78a6 --- /dev/null +++ b/core/src/test/kotlin/markdownParser/MarkdownParserTest.kt @@ -0,0 +1,28 @@ +package org.jetbrains.dokka.tests.markdownParser + +import junit.framework.Assert.assertEquals +import junit.framework.Assert.assertTrue +import org.jetbrains.dokka.DokkaConfiguration +import org.jetbrains.dokka.links.DRI +import org.jetbrains.dokka.pages.buildContent +import org.jetbrains.dokka.parseMarkdown +import org.jetbrains.dokka.resolvers.ExternalLocationProvider +import org.junit.Test + + +class MarkdownParserTest { + + @Test fun basicTest() { + val markdown = """ + # Header 1 test + this is some text + more text + let's say there are some parentheses, like ( and ) + """.trimIndent() + val node = parseMarkdown(markdown) + val content = buildContent(node, emptyList()) + assertTrue(content.isNotEmpty()) + } + +} + |