diff options
6 files changed, 90 insertions, 25 deletions
diff --git a/core/src/main/kotlin/model/doc/DocTag.kt b/core/src/main/kotlin/model/doc/DocTag.kt index 94558ca7..8a9521ab 100644 --- a/core/src/main/kotlin/model/doc/DocTag.kt +++ b/core/src/main/kotlin/model/doc/DocTag.kt @@ -71,6 +71,7 @@ class Script(children: List<DocTag> = emptyList(), params: Map<String, String> = class Section(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params) class Small(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params) class Span(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params) +class Strikethrough(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params) class Strong(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params) class Sub(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params) class Sup(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params) diff --git a/core/src/main/kotlin/pages/ContentNodes.kt b/core/src/main/kotlin/pages/ContentNodes.kt index cfcd4069..c0576006 100644 --- a/core/src/main/kotlin/pages/ContentNodes.kt +++ b/core/src/main/kotlin/pages/ContentNodes.kt @@ -185,6 +185,8 @@ enum class TextStyle : Style { Bold, Italic, Strong, Strikethrough, Paragraph, Block, Monospace, Indented } +object CommentTable: Style + fun ContentNode.dfs(predicate: (ContentNode) -> Boolean): ContentNode? = if (predicate(this)) { this } else { @@ -194,3 +196,5 @@ fun ContentNode.dfs(predicate: (ContentNode) -> Boolean): ContentNode? = if (pre null } } + +fun ContentNode.hasStyle(style: Style) = this.style.contains(style) diff --git a/core/src/main/kotlin/parsers/MarkdownParser.kt b/core/src/main/kotlin/parsers/MarkdownParser.kt index 9354a6b6..145e085c 100644 --- a/core/src/main/kotlin/parsers/MarkdownParser.kt +++ b/core/src/main/kotlin/parsers/MarkdownParser.kt @@ -8,11 +8,14 @@ import org.intellij.markdown.ast.ASTNode import org.intellij.markdown.ast.CompositeASTNode import org.intellij.markdown.ast.LeafASTNode import org.intellij.markdown.ast.impl.ListItemCompositeNode -import org.intellij.markdown.flavours.commonmark.CommonMarkFlavourDescriptor +import org.intellij.markdown.flavours.gfm.GFMElementTypes +import org.intellij.markdown.flavours.gfm.GFMFlavourDescriptor +import org.intellij.markdown.flavours.gfm.GFMTokenTypes import org.jetbrains.dokka.analysis.DokkaResolutionFacade import org.jetbrains.dokka.links.DRI import org.jetbrains.dokka.parsers.factories.DocTagsFromIElementFactory import org.jetbrains.dokka.utilities.DokkaLogger +import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.idea.kdoc.resolveKDocLink import org.jetbrains.kotlin.kdoc.parser.KDocKnownTag @@ -106,15 +109,17 @@ class MarkdownParser( java.net.URL(link) null } catch (e: MalformedURLException) { - resolveKDocLink( - resolutionFacade.resolveSession.bindingContext, - resolutionFacade, - declarationDescriptor, - null, - link.split('.') - ).also { if (it.size > 1) logger.warn("Markdown link resolved more than one element: $it") } - .firstOrNull()//.single() - ?.let { DRI.from(it) } + try { + resolveKDocLink( + resolutionFacade.resolveSession.bindingContext, + resolutionFacade, + declarationDescriptor, + null, + link.split('.') + ).minBy { it is ClassDescriptor }?.let { DRI.from(it) } + } catch (e1: IllegalArgumentException) { + null + } } } @@ -249,9 +254,29 @@ class MarkdownParser( 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() + ) else -> defaultHandler(node) } + private fun List<ASTNode>.filterTabSeparators() = + this.filterNot { it.type == GFMTokenTypes.TABLE_SEPARATOR } + private fun List<ASTNode>.evaluateChildren(): List<DocTag> = this.removeUselessTokens().mergeLeafASTNodes().map { visitNode(it) } @@ -318,7 +343,7 @@ class MarkdownParser( private fun markdownToDocNode(text: String): DocTag { - val flavourDescriptor = CommonMarkFlavourDescriptor() + val flavourDescriptor = GFMFlavourDescriptor() val markdownAstRoot: ASTNode = IntellijMarkdownParser(flavourDescriptor).buildMarkdownTreeFromString(text) return MarkdownVisitor(text, getAllDestinationLinks(text, markdownAstRoot).toMap()).visitNode(markdownAstRoot) diff --git a/core/src/main/kotlin/parsers/factories/DocTagsFromIElementFactory.kt b/core/src/main/kotlin/parsers/factories/DocTagsFromIElementFactory.kt index e616b9e8..dda6c627 100644 --- a/core/src/main/kotlin/parsers/factories/DocTagsFromIElementFactory.kt +++ b/core/src/main/kotlin/parsers/factories/DocTagsFromIElementFactory.kt @@ -4,6 +4,7 @@ import org.jetbrains.dokka.model.doc.* import org.intellij.markdown.IElementType import org.intellij.markdown.MarkdownElementTypes import org.intellij.markdown.MarkdownTokenTypes +import org.intellij.markdown.flavours.gfm.GFMElementTypes import org.jetbrains.dokka.links.DRI import java.lang.NullPointerException @@ -33,6 +34,10 @@ object DocTagsFromIElementFactory { MarkdownTokenTypes.TEXT -> Text(body ?: throw NullPointerException("Text body should be at least empty string passed to DocNodes factory!"), children, params ) MarkdownTokenTypes.HORIZONTAL_RULE -> HorizontalRule MarkdownTokenTypes.HARD_LINE_BREAK -> Br + GFMElementTypes.STRIKETHROUGH -> Strikethrough(children, params) + GFMElementTypes.TABLE -> Table(children, params) + GFMElementTypes.HEADER -> Th(children, params) + GFMElementTypes.ROW -> Tr(children, params) else -> CustomDocTag(children, params) } }
\ No newline at end of file diff --git a/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt b/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt index 23ba0676..65441909 100644 --- a/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt +++ b/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt @@ -21,7 +21,7 @@ open class HtmlRenderer( private val pageList = mutableListOf<String>() override val preprocessors = context.plugin<DokkaBase>().query { htmlPreprocessors } + - context.plugin<DokkaBase>().querySingle { samplesTransformer } + context.plugin<DokkaBase>().querySingle { samplesTransformer } override fun FlowContent.wrapGroup( node: ContentGroup, @@ -37,8 +37,8 @@ open class HtmlRenderer( node.dci.kind == ContentKind.Symbol -> div("symbol $additionalClasses") { childrenCallback() } node.dci.kind == ContentKind.BriefComment -> div("brief $additionalClasses") { childrenCallback() } node.dci.kind == ContentKind.Cover -> div("cover $additionalClasses") { childrenCallback() } - node.style.contains(TextStyle.Paragraph) -> p(additionalClasses) { childrenCallback() } - node.style.contains(TextStyle.Block) -> div(additionalClasses) { childrenCallback() } + node.hasStyle(TextStyle.Paragraph) -> p(additionalClasses) { childrenCallback() } + node.hasStyle(TextStyle.Block) -> div(additionalClasses) { childrenCallback() } else -> childrenCallback() } } @@ -63,7 +63,7 @@ open class HtmlRenderer( override fun FlowContent.buildPlatformDependent(content: PlatformHintedContent, pageContext: ContentPage) { div("platform-hinted") { attributes["data-platform-hinted"] = "data-platform-hinted" - val contents = content.platforms.mapIndexed { index,platform -> + val contents = content.platforms.mapIndexed { index, platform -> platform to createHTML(prettyPrint = false).div(classes = "content") { if (index == 0) attributes["data-active"] = "" attributes["data-togglable"] = platform.targets.joinToString("-") @@ -71,10 +71,10 @@ open class HtmlRenderer( } } - if(contents.size != 1) { + if (contents.size != 1) { div("platform-bookmarks-row") { attributes["data-toggle-list"] = "data-toggle-list" - contents.forEachIndexed { index,pair -> + contents.forEachIndexed { index, pair -> button(classes = "platform-bookmark") { if (index == 0) attributes["data-active"] = "" attributes["data-toggle"] = pair.first.targets.joinToString("-") @@ -181,7 +181,7 @@ open class HtmlRenderer( pageContext: ContentPage, platformRestriction: PlatformData? ) { - table { + table(if (node.hasStyle(CommentTable)) "comment-table" else "") { thead { node.header.forEach { tr { @@ -256,8 +256,11 @@ open class HtmlRenderer( val iterator = code.iterator() while (iterator.hasNext()) { val element = iterator.next() - +((element as? ContentText)?.text - ?: run { context.logger.error("Cannot cast $element as ContentText!"); "" }) + +(when (element) { + is ContentText -> element.text + is ContentBreakLine -> "\n" + else -> run { context.logger.error("Cannot cast $element as ContentText!"); "" } + }) if (iterator.hasNext()) { buildNewLine() } @@ -278,7 +281,7 @@ open class HtmlRenderer( override fun FlowContent.buildText(textNode: ContentText) { when { - textNode.style.contains(TextStyle.Indented) -> consumer.onTagContentEntity(Entities.nbsp) + textNode.hasStyle(TextStyle.Indented) -> consumer.onTagContentEntity(Entities.nbsp) } text(textNode.text) } diff --git a/plugins/base/src/main/kotlin/transformers/pages/comments/DocTagToContentConverter.kt b/plugins/base/src/main/kotlin/transformers/pages/comments/DocTagToContentConverter.kt index 2eb63504..4e65bae9 100644 --- a/plugins/base/src/main/kotlin/transformers/pages/comments/DocTagToContentConverter.kt +++ b/plugins/base/src/main/kotlin/transformers/pages/comments/DocTagToContentConverter.kt @@ -3,7 +3,6 @@ package org.jetbrains.dokka.base.transformers.pages.comments import org.jetbrains.dokka.model.doc.* import org.jetbrains.dokka.model.properties.PropertyContainer import org.jetbrains.dokka.pages.* -import org.jetbrains.dokka.plugability.DokkaContext object DocTagToContentConverter : CommentsToContentConverter { override fun buildContent( @@ -19,6 +18,11 @@ object DocTagToContentConverter : CommentsToContentConverter { buildContent(it, dci, platforms, styles + newStyles, newExtras?.let { extra + it } ?: extra) } + fun buildTableRows(rows: List<DocTag>, newStyle: Style): List<ContentGroup> = + rows.flatMap { + buildContent(it, dci, platforms, styles + newStyle, extra) as List<ContentGroup> + } + fun buildHeader(level: Int) = listOf( ContentHeader( @@ -42,9 +46,11 @@ object DocTagToContentConverter : CommentsToContentConverter { ) ) - fun buildNewLine() = listOf(ContentBreakLine( - platforms - )) + fun buildNewLine() = listOf( + ContentBreakLine( + platforms + ) + ) return when (docTag) { is H1 -> buildHeader(1) @@ -125,6 +131,27 @@ object DocTagToContentConverter : CommentsToContentConverter { styles ) ) + is Strikethrough -> buildChildren(docTag, setOf(TextStyle.Strikethrough)) + is Table -> listOf( + ContentTable( + buildTableRows(docTag.children.filterIsInstance<Th>(), CommentTable), + buildTableRows(docTag.children.filterIsInstance<Tr>(), CommentTable), + dci, + platforms, + styles + CommentTable + ) + ) + is Th, + is Tr -> listOf( + ContentGroup( + docTag.children.map { + ContentGroup(buildChildren(it), dci, platforms, styles, extra) + }, + dci, + platforms, + styles + ) + ) else -> buildChildren(docTag) } } |