-
Notifications
You must be signed in to change notification settings - Fork 42
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Use value classes for all markdown nodes
- Loading branch information
Showing
16 changed files
with
407 additions
and
13,290 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
133 changes: 96 additions & 37 deletions
133
markdown/core/src/main/kotlin/org/jetbrains/jewel/markdown/MarkdownBlock.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,62 +1,121 @@ | ||
package org.jetbrains.jewel.markdown | ||
|
||
import org.commonmark.node.Node | ||
import org.jetbrains.jewel.markdown.MarkdownBlock.BlockQuote | ||
import org.jetbrains.jewel.markdown.MarkdownBlock.CodeBlock | ||
import org.jetbrains.jewel.markdown.MarkdownBlock.CustomBlock | ||
import org.jetbrains.jewel.markdown.MarkdownBlock.Heading | ||
import org.jetbrains.jewel.markdown.MarkdownBlock.HtmlBlock | ||
import org.jetbrains.jewel.markdown.MarkdownBlock.LinkReferenceDefinition | ||
import org.jetbrains.jewel.markdown.MarkdownBlock.ListBlock | ||
import org.jetbrains.jewel.markdown.MarkdownBlock.ListItem | ||
import org.jetbrains.jewel.markdown.MarkdownBlock.Paragraph | ||
import org.jetbrains.jewel.markdown.MarkdownBlock.ThematicBreak | ||
import org.commonmark.node.Block as CMBlock | ||
import org.commonmark.node.BlockQuote as CMBlockQuote | ||
import org.commonmark.node.BulletList as CMBulletList | ||
import org.commonmark.node.CustomBlock as CMCustomBlock | ||
import org.commonmark.node.FencedCodeBlock as CMFencedCodeBlock | ||
import org.commonmark.node.Heading as CMHeading | ||
import org.commonmark.node.HtmlBlock as CMHtmlBlock | ||
import org.commonmark.node.IndentedCodeBlock as CMIndentedCodeBlock | ||
import org.commonmark.node.LinkReferenceDefinition as CMLinkReferenceDefinition | ||
import org.commonmark.node.ListItem as CMListItem | ||
import org.commonmark.node.OrderedList as CMOrderedList | ||
import org.commonmark.node.Paragraph as CMParagraph | ||
import org.commonmark.node.ThematicBreak as CMThematicBreak | ||
|
||
public sealed interface MarkdownBlock { | ||
|
||
public data class BlockQuote(val content: List<MarkdownBlock>) : MarkdownBlock | ||
public val value: CMBlock | ||
|
||
public interface CustomBlock : MarkdownBlock | ||
@JvmInline | ||
public value class BlockQuote(override val value: CMBlockQuote) : MarkdownBlock | ||
|
||
public sealed interface CodeBlock : MarkdownBlock { | ||
@JvmInline | ||
public value class FencedCodeBlock(override val value: CMFencedCodeBlock) : CodeBlock | ||
|
||
public val content: String | ||
@JvmInline | ||
public value class IndentedCodeBlock(override val value: CMIndentedCodeBlock) : CodeBlock | ||
} | ||
|
||
public data class IndentedCodeBlock( | ||
override val content: String, | ||
) : CodeBlock | ||
@JvmInline | ||
public value class CustomBlock(override val value: CMCustomBlock) : MarkdownBlock | ||
|
||
public data class FencedCodeBlock( | ||
override val content: String, | ||
val mimeType: MimeType?, | ||
) : CodeBlock | ||
} | ||
@JvmInline | ||
public value class Heading(override val value: CMHeading) : MarkdownBlock, BlockWithInlineMarkdown { | ||
|
||
public data class Heading( | ||
override val inlineContent: List<InlineMarkdown>, | ||
val level: Int, | ||
) : MarkdownBlock, BlockWithInlineMarkdown | ||
public val level: Int | ||
get() = value.level | ||
} | ||
|
||
public data class HtmlBlock(val content: String) : MarkdownBlock | ||
@JvmInline | ||
public value class HtmlBlock(override val value: CMHtmlBlock) : MarkdownBlock | ||
|
||
public sealed interface ListBlock : MarkdownBlock { | ||
@JvmInline | ||
public value class BulletList(override val value: CMBulletList) : MarkdownBlock | ||
|
||
public val items: List<ListItem> | ||
public val isTight: Boolean | ||
|
||
public data class BulletList( | ||
override val items: List<ListItem>, | ||
override val isTight: Boolean, | ||
val bulletMarker: Char, | ||
) : ListBlock | ||
|
||
public data class OrderedList( | ||
override val items: List<ListItem>, | ||
override val isTight: Boolean, | ||
val startFrom: Int, | ||
val delimiter: Char, | ||
) : ListBlock | ||
@JvmInline | ||
public value class OrderedList(override val value: CMOrderedList) : MarkdownBlock | ||
} | ||
|
||
public data class ListItem( | ||
val content: List<MarkdownBlock>, | ||
) : MarkdownBlock | ||
@JvmInline | ||
public value class ListItem(override val value: CMListItem) : MarkdownBlock | ||
|
||
public data class LinkReferenceDefinition(val payload: Node) : MarkdownBlock { | ||
override val value: CMBlock = object : CMCustomBlock() {} | ||
} | ||
|
||
public object ThematicBreak : MarkdownBlock | ||
@JvmInline | ||
public value class ThematicBreak(override val value: CMThematicBreak) : MarkdownBlock | ||
|
||
public data class Paragraph(override val inlineContent: List<InlineMarkdown>) : | ||
MarkdownBlock, BlockWithInlineMarkdown | ||
@JvmInline | ||
public value class Paragraph(override val value: CMParagraph) : MarkdownBlock, BlockWithInlineMarkdown | ||
|
||
public val children: Iterator<MarkdownBlock> | ||
get() = object : Iterator<MarkdownBlock> { | ||
var current = this@MarkdownBlock.value.firstChild | ||
|
||
override fun hasNext(): Boolean = current != null | ||
|
||
override fun next(): MarkdownBlock = | ||
if (hasNext()) { | ||
current.toMarkdownBlock().also { | ||
current = current.next | ||
} | ||
} else { | ||
throw NoSuchElementException() | ||
} | ||
} | ||
} | ||
|
||
public interface BlockWithInlineMarkdown { | ||
|
||
public val inlineContent: List<InlineMarkdown> | ||
get() = buildList { | ||
var child = (this@BlockWithInlineMarkdown as MarkdownBlock).value.firstChild | ||
|
||
while (child != null) { | ||
add(child.toInlineNode()) | ||
child = child.next | ||
} | ||
} | ||
} | ||
|
||
public fun Node.toMarkdownBlock(): MarkdownBlock = when (this) { | ||
is CMParagraph -> Paragraph(this) | ||
is CMHeading -> Heading(this) | ||
is CMHtmlBlock -> HtmlBlock(this) | ||
is CMBlockQuote -> BlockQuote(this) | ||
is CMFencedCodeBlock -> CodeBlock.FencedCodeBlock(this) | ||
is CMIndentedCodeBlock -> CodeBlock.IndentedCodeBlock(this) | ||
is CMBulletList -> ListBlock.BulletList(this) | ||
is CMOrderedList -> ListBlock.OrderedList(this) | ||
is CMListItem -> ListItem(this) | ||
is CMThematicBreak -> ThematicBreak(this) | ||
is CMCustomBlock -> CustomBlock(this) | ||
is CMLinkReferenceDefinition -> LinkReferenceDefinition(this) | ||
else -> error("Unexpected block $this") | ||
} |
5 changes: 5 additions & 0 deletions
5
markdown/core/src/main/kotlin/org/jetbrains/jewel/markdown/WithInlineMarkdown.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
package org.jetbrains.jewel.markdown | ||
|
||
public interface WithInlineMarkdown { | ||
public val inlineContent: InlineMarkdown | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.