Skip to content

Commit

Permalink
Clean up Commonmark API conventions
Browse files Browse the repository at this point in the history
- use one node type for Heading
- rename 'content' to 'children' if it points to
other blocks

Also clean up tests to not use parenthesis,
becasue it breaks navigation in IDEA
  • Loading branch information
obask authored and Oleg Baskakov committed Mar 31, 2024
1 parent c3a1b5b commit 436fa49
Show file tree
Hide file tree
Showing 17 changed files with 807 additions and 1,004 deletions.
135 changes: 34 additions & 101 deletions markdown/core/api/core.api

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -7,44 +7,31 @@ public sealed interface MarkdownBlock {
public data class Paragraph(override val inlineContent: InlineMarkdown) :
MarkdownBlock, BlockWithInlineMarkdown

public sealed interface Heading : MarkdownBlock, BlockWithInlineMarkdown {
public data class Heading(override val inlineContent: InlineMarkdown, val level: Int) : MarkdownBlock, BlockWithInlineMarkdown

public data class H1(override val inlineContent: InlineMarkdown) : Heading

public data class H2(override val inlineContent: InlineMarkdown) : Heading

public data class H3(override val inlineContent: InlineMarkdown) : Heading

public data class H4(override val inlineContent: InlineMarkdown) : Heading

public data class H5(override val inlineContent: InlineMarkdown) : Heading

public data class H6(override val inlineContent: InlineMarkdown) : Heading
}

public data class BlockQuote(val content: List<MarkdownBlock>) : MarkdownBlock
public data class BlockQuote(val children: List<MarkdownBlock>) : MarkdownBlock

public sealed interface ListBlock : MarkdownBlock {

public val items: List<ListItem>
public val children: List<ListItem>
public val isTight: Boolean

public data class OrderedList(
override val items: List<ListItem>,
override val children: List<ListItem>,
override val isTight: Boolean,
val startFrom: Int,
val delimiter: Char,
) : ListBlock

public data class UnorderedList(
override val items: List<ListItem>,
override val children: List<ListItem>,
override val isTight: Boolean,
val bulletMarker: Char,
val marker: Char,
) : ListBlock
}

public data class ListItem(
val content: List<MarkdownBlock>,
val children: List<MarkdownBlock>,
) : MarkdownBlock

public sealed interface CodeBlock : MarkdownBlock {
Expand All @@ -67,7 +54,7 @@ public sealed interface MarkdownBlock {

public data class HtmlBlock(val content: String) : MarkdownBlock

public interface Extension : MarkdownBlock
public interface CustomBlock : MarkdownBlock
}

public interface BlockWithInlineMarkdown {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ public interface MarkdownBlockProcessorExtension {
public fun canProcess(block: CustomBlock): Boolean

/**
* Processes the [block] as a [MarkdownBlock.Extension], if possible. Note
* Processes the [block] as a [MarkdownBlock.CustomBlock], if possible. Note
* that you should always check that [canProcess] returns true for the same
* [block], as implementations might throw an exception for unsupported
* block types.
*/
public fun processMarkdownBlock(block: CustomBlock, processor: MarkdownProcessor): MarkdownBlock.Extension?
public fun processMarkdownBlock(block: CustomBlock, processor: MarkdownProcessor): MarkdownBlock.CustomBlock?
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,26 @@ package org.jetbrains.jewel.markdown.extensions

import androidx.compose.runtime.Composable
import org.jetbrains.jewel.markdown.MarkdownBlock
import org.jetbrains.jewel.markdown.MarkdownBlock.Extension
import org.jetbrains.jewel.markdown.MarkdownBlock.CustomBlock
import org.jetbrains.jewel.markdown.rendering.InlineMarkdownRenderer
import org.jetbrains.jewel.markdown.rendering.MarkdownBlockRenderer

/**
* An extension for [MarkdownBlockRenderer] that can render one or more
* [MarkdownBlock.Extension]s.
* [MarkdownBlock.CustomBlock]s.
*/
public interface MarkdownBlockRendererExtension {

/** Check whether the provided [block] can be rendered by this extension. */
public fun canRender(block: Extension): Boolean
public fun canRender(block: CustomBlock): Boolean

/**
* Render a [MarkdownBlock.Extension] as a native Composable. Note that if
* Render a [MarkdownBlock.CustomBlock] as a native Composable. Note that if
* [canRender] returns `false` for [block], the implementation might throw.
*/
@Composable
public fun render(
block: Extension,
block: CustomBlock,
blockRenderer: MarkdownBlockRenderer,
inlineRenderer: InlineMarkdownRenderer,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public interface MarkdownProcessorExtension {
* An extension for
* [`MarkdownParser`][org.jetbrains.jewel.markdown.parsing.MarkdownParser]
* that will transform a supported [CustomBlock] into the corresponding
* [MarkdownBlock.Extension].
* [MarkdownBlock.CustomBlock].
*/
public val processorExtension: MarkdownBlockProcessorExtension
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ public interface MarkdownRendererExtension {
* An extension for
* [`MarkdownBlockRenderer`][org.jetbrains.jewel.markdown.rendering.MarkdownBlockRenderer]
* that will render a supported
* [`Extension`][org.jetbrains.jewel.markdown.MarkdownBlock.Extension] into
* [`CustomBlock`][org.jetbrains.jewel.markdown.MarkdownBlock.CustomBlock] into
* a native Jewel UI.
*/
public val blockRenderer: MarkdownBlockRendererExtension
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import org.commonmark.node.HtmlInline
import org.commonmark.node.Image
import org.commonmark.node.IndentedCodeBlock
import org.commonmark.node.Link
import org.commonmark.node.ListBlock
import org.commonmark.node.ListItem
import org.commonmark.node.Node
import org.commonmark.node.OrderedList
Expand All @@ -34,16 +33,11 @@ import org.jetbrains.jewel.foundation.ExperimentalJewelApi
import org.jetbrains.jewel.markdown.InlineMarkdown
import org.jetbrains.jewel.markdown.MarkdownBlock
import org.jetbrains.jewel.markdown.MarkdownBlock.CodeBlock
import org.jetbrains.jewel.markdown.MarkdownBlock.Heading.H1
import org.jetbrains.jewel.markdown.MarkdownBlock.Heading.H2
import org.jetbrains.jewel.markdown.MarkdownBlock.Heading.H3
import org.jetbrains.jewel.markdown.MarkdownBlock.Heading.H4
import org.jetbrains.jewel.markdown.MarkdownBlock.Heading.H5
import org.jetbrains.jewel.markdown.MarkdownBlock.Heading.H6
import org.jetbrains.jewel.markdown.MarkdownBlock.ListBlock.UnorderedList
import org.jetbrains.jewel.markdown.MarkdownBlock.ListBlock
import org.jetbrains.jewel.markdown.MimeType
import org.jetbrains.jewel.markdown.extensions.MarkdownProcessorExtension
import org.jetbrains.jewel.markdown.rendering.DefaultInlineMarkdownRenderer
import org.commonmark.node.ListBlock as CMListBlock

/**
* @param optimizeEdits Optional. Indicates whether the processing should only update the changed blocks
Expand Down Expand Up @@ -221,16 +215,10 @@ public class MarkdownProcessor(
private fun BlockQuote.toMarkdownBlockQuote(): MarkdownBlock.BlockQuote =
MarkdownBlock.BlockQuote(processChildren(this))

private fun Heading.toMarkdownHeadingOrNull(): MarkdownBlock.Heading? =
when (level) {
1 -> H1(contentsAsInlineMarkdown())
2 -> H2(contentsAsInlineMarkdown())
3 -> H3(contentsAsInlineMarkdown())
4 -> H4(contentsAsInlineMarkdown())
5 -> H5(contentsAsInlineMarkdown())
6 -> H6(contentsAsInlineMarkdown())
else -> null
}
private fun Heading.toMarkdownHeadingOrNull(): MarkdownBlock.Heading? {
if (level < 1 || level > 6) return null
return MarkdownBlock.Heading(contentsAsInlineMarkdown(), level)
}

private fun Paragraph.toMarkdownParagraphOrNull(): MarkdownBlock.Paragraph? {
val inlineMarkdown = contentsAsInlineMarkdown()
Expand All @@ -254,21 +242,21 @@ public class MarkdownProcessor(
return MarkdownBlock.Image(destination.trim(), title.trim())
}

private fun BulletList.toMarkdownListOrNull(): UnorderedList? {
private fun BulletList.toMarkdownListOrNull(): ListBlock.UnorderedList? {
val children = processListItems()
if (children.isEmpty()) return null

return UnorderedList(children, isTight, bulletMarker)
return ListBlock.UnorderedList(children, isTight, bulletMarker)
}

private fun OrderedList.toMarkdownListOrNull(): MarkdownBlock.ListBlock.OrderedList? {
private fun OrderedList.toMarkdownListOrNull(): ListBlock.OrderedList? {
val children = processListItems()
if (children.isEmpty()) return null

return MarkdownBlock.ListBlock.OrderedList(children, isTight, startNumber, delimiter)
}

private fun ListBlock.processListItems() = buildList {
private fun CMListBlock.processListItems() = buildList {
forEachChild { child ->
if (child !is ListItem) return@forEachChild
add(MarkdownBlock.ListItem(processChildren(child)))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,14 +55,8 @@ import org.jetbrains.jewel.markdown.MarkdownBlock.BlockQuote
import org.jetbrains.jewel.markdown.MarkdownBlock.CodeBlock
import org.jetbrains.jewel.markdown.MarkdownBlock.CodeBlock.FencedCodeBlock
import org.jetbrains.jewel.markdown.MarkdownBlock.CodeBlock.IndentedCodeBlock
import org.jetbrains.jewel.markdown.MarkdownBlock.Extension
import org.jetbrains.jewel.markdown.MarkdownBlock.CustomBlock
import org.jetbrains.jewel.markdown.MarkdownBlock.Heading
import org.jetbrains.jewel.markdown.MarkdownBlock.Heading.H1
import org.jetbrains.jewel.markdown.MarkdownBlock.Heading.H2
import org.jetbrains.jewel.markdown.MarkdownBlock.Heading.H3
import org.jetbrains.jewel.markdown.MarkdownBlock.Heading.H4
import org.jetbrains.jewel.markdown.MarkdownBlock.Heading.H5
import org.jetbrains.jewel.markdown.MarkdownBlock.Heading.H6
import org.jetbrains.jewel.markdown.MarkdownBlock.HtmlBlock
import org.jetbrains.jewel.markdown.MarkdownBlock.Image
import org.jetbrains.jewel.markdown.MarkdownBlock.ListBlock
Expand Down Expand Up @@ -99,20 +93,15 @@ public open class DefaultMarkdownBlockRenderer(
is BlockQuote -> render(block, rootStyling.blockQuote)
is FencedCodeBlock -> render(block, rootStyling.code.fenced)
is IndentedCodeBlock -> render(block, rootStyling.code.indented)
is H1 -> render(block, rootStyling.heading.h1)
is H2 -> render(block, rootStyling.heading.h2)
is H3 -> render(block, rootStyling.heading.h3)
is H4 -> render(block, rootStyling.heading.h4)
is H5 -> render(block, rootStyling.heading.h5)
is H6 -> render(block, rootStyling.heading.h6)
is Heading -> render(block, rootStyling.heading)
is HtmlBlock -> render(block, rootStyling.htmlBlock)
is Image -> render(block, rootStyling.image)
is OrderedList -> render(block, rootStyling.list.ordered)
is UnorderedList -> render(block, rootStyling.list.unordered)
is ListItem -> render(block)
is Paragraph -> render(block, rootStyling.paragraph)
ThematicBreak -> renderThematicBreak(rootStyling.thematicBreak)
is Extension -> {
is CustomBlock -> {
rendererExtensions.find { it.blockRenderer.canRender(block) }
?.blockRenderer?.render(block, this, inlineRenderer)
}
Expand All @@ -127,83 +116,19 @@ public open class DefaultMarkdownBlockRenderer(

@Composable
override fun render(block: Heading, styling: MarkdownStyling.Heading) {
when (block) {
is H1 -> render(block, styling)
is H2 -> render(block, styling)
is H3 -> render(block, styling)
is H4 -> render(block, styling)
is H5 -> render(block, styling)
is H6 -> render(block, styling)
when (block.level) {
1 -> render(block, styling.h1)
2 -> render(block, styling.h2)
3 -> render(block, styling.h3)
4 -> render(block, styling.h4)
5 -> render(block, styling.h5)
6 -> render(block, styling.h6)
else -> error("Heading level ${block.level} not supported:\n$block")
}
}

@Composable
override fun render(block: H1, styling: MarkdownStyling.Heading.H1) {
val renderedContent = rememberRenderedContent(block, styling.inlinesStyling)
Heading(
renderedContent,
styling.inlinesStyling.textStyle,
styling.padding,
styling.underlineWidth,
styling.underlineColor,
styling.underlineGap,
)
}

@Composable
override fun render(block: H2, styling: MarkdownStyling.Heading.H2) {
val renderedContent = rememberRenderedContent(block, styling.inlinesStyling)
Heading(
renderedContent,
styling.inlinesStyling.textStyle,
styling.padding,
styling.underlineWidth,
styling.underlineColor,
styling.underlineGap,
)
}

@Composable
override fun render(block: H3, styling: MarkdownStyling.Heading.H3) {
val renderedContent = rememberRenderedContent(block, styling.inlinesStyling)
Heading(
renderedContent,
styling.inlinesStyling.textStyle,
styling.padding,
styling.underlineWidth,
styling.underlineColor,
styling.underlineGap,
)
}

@Composable
override fun render(block: H4, styling: MarkdownStyling.Heading.H4) {
val renderedContent = rememberRenderedContent(block, styling.inlinesStyling)
Heading(
renderedContent,
styling.inlinesStyling.textStyle,
styling.padding,
styling.underlineWidth,
styling.underlineColor,
styling.underlineGap,
)
}

@Composable
override fun render(block: H5, styling: MarkdownStyling.Heading.H5) {
val renderedContent = rememberRenderedContent(block, styling.inlinesStyling)
Heading(
renderedContent,
styling.inlinesStyling.textStyle,
styling.padding,
styling.underlineWidth,
styling.underlineColor,
styling.underlineGap,
)
}

@Composable
override fun render(block: H6, styling: MarkdownStyling.Heading.H6) {
override fun render(block: Heading, styling: MarkdownStyling.Heading.HN) {
val renderedContent = rememberRenderedContent(block, styling.inlinesStyling)
Heading(
renderedContent,
Expand Down Expand Up @@ -258,7 +183,7 @@ public open class DefaultMarkdownBlockRenderer(
verticalArrangement = Arrangement.spacedBy(rootStyling.blockVerticalSpacing),
) {
CompositionLocalProvider(LocalContentColor provides styling.textColor) {
render(block.content)
render(block.children)
}
}
}
Expand All @@ -284,7 +209,7 @@ public open class DefaultMarkdownBlockRenderer(
modifier = Modifier.padding(styling.padding),
verticalArrangement = Arrangement.spacedBy(itemSpacing),
) {
for ((index, item) in block.items.withIndex()) {
for ((index, item) in block.children.withIndex()) {
Row {
val number = block.startFrom + index
Text(
Expand Down Expand Up @@ -316,7 +241,7 @@ public open class DefaultMarkdownBlockRenderer(
modifier = Modifier.padding(styling.padding),
verticalArrangement = Arrangement.spacedBy(itemSpacing),
) {
for (item in block.items) {
for (item in block.children) {
Row {
Text(
text = styling.bullet.toString(),
Expand All @@ -335,7 +260,7 @@ public open class DefaultMarkdownBlockRenderer(
@Composable
override fun render(block: ListItem) {
Column(verticalArrangement = Arrangement.spacedBy(rootStyling.blockVerticalSpacing)) {
render(block.content)
render(block.children)
}
}

Expand Down
Loading

0 comments on commit 436fa49

Please sign in to comment.