-
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 inline markdown
This classes wrap CommonMark's nodes and preserve a familiar API. Some tests were turned off because we don't use the same IR for string serialization. Changing dataclasses to values classes for blocks is coming in the next pull request.
- Loading branch information
Showing
21 changed files
with
563 additions
and
510 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
96 changes: 96 additions & 0 deletions
96
markdown/core/src/main/kotlin/org/jetbrains/jewel/markdown/InlineMarkdown.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,96 @@ | ||
package org.jetbrains.jewel.markdown | ||
|
||
import org.commonmark.node.Node | ||
import org.jetbrains.jewel.markdown.InlineMarkdown.Code | ||
import org.jetbrains.jewel.markdown.InlineMarkdown.CustomNode | ||
import org.jetbrains.jewel.markdown.InlineMarkdown.Emphasis | ||
import org.jetbrains.jewel.markdown.InlineMarkdown.HardLineBreak | ||
import org.jetbrains.jewel.markdown.InlineMarkdown.HtmlInline | ||
import org.jetbrains.jewel.markdown.InlineMarkdown.Image | ||
import org.jetbrains.jewel.markdown.InlineMarkdown.Link | ||
import org.jetbrains.jewel.markdown.InlineMarkdown.SoftLineBreak | ||
import org.jetbrains.jewel.markdown.InlineMarkdown.StrongEmphasis | ||
import org.jetbrains.jewel.markdown.InlineMarkdown.Text | ||
import org.commonmark.node.Code as CMCode | ||
import org.commonmark.node.CustomNode as CMCustomNode | ||
import org.commonmark.node.Emphasis as CMEmphasis | ||
import org.commonmark.node.HardLineBreak as CMHardLineBreak | ||
import org.commonmark.node.HtmlInline as CMHtmlInline | ||
import org.commonmark.node.Image as CMImage | ||
import org.commonmark.node.Link as CMLink | ||
import org.commonmark.node.Paragraph as CMParagraph | ||
import org.commonmark.node.SoftLineBreak as CMSoftLineBreak | ||
import org.commonmark.node.StrongEmphasis as CMStrongEmphasis | ||
import org.commonmark.node.Text as CMText | ||
|
||
/** | ||
* A run of inline Markdown used as content for | ||
* [block-level elements][MarkdownBlock]. | ||
*/ | ||
public sealed interface InlineMarkdown { | ||
|
||
public val value: Node | ||
|
||
@JvmInline | ||
public value class Emphasis(override val value: CMEmphasis) : InlineMarkdown | ||
|
||
@JvmInline | ||
public value class Image(override val value: CMImage) : InlineMarkdown | ||
|
||
@JvmInline | ||
public value class Code(override val value: CMCode) : InlineMarkdown | ||
|
||
@JvmInline | ||
public value class CustomNode(override val value: CMCustomNode) : InlineMarkdown | ||
|
||
@JvmInline | ||
public value class HardLineBreak(override val value: CMHardLineBreak) : InlineMarkdown | ||
|
||
@JvmInline | ||
public value class SoftLineBreak(override val value: CMSoftLineBreak) : InlineMarkdown | ||
|
||
@JvmInline | ||
public value class HtmlInline(override val value: CMHtmlInline) : InlineMarkdown | ||
|
||
@JvmInline | ||
public value class Link(override val value: CMLink) : InlineMarkdown | ||
|
||
@JvmInline | ||
public value class StrongEmphasis(override val value: CMStrongEmphasis) : InlineMarkdown | ||
|
||
@JvmInline | ||
public value class Paragraph(override val value: CMParagraph) : InlineMarkdown | ||
|
||
@JvmInline | ||
public value class Text(override val value: CMText) : InlineMarkdown | ||
|
||
public val children: Iterator<InlineMarkdown> | ||
get() = object : Iterator<InlineMarkdown> { | ||
var current = this@InlineMarkdown.value.firstChild | ||
|
||
override fun hasNext(): Boolean = current != null | ||
|
||
override fun next(): InlineMarkdown = | ||
if (hasNext()) { | ||
current.toInlineNode().also { | ||
current = current.next | ||
} | ||
} else { | ||
throw NoSuchElementException() | ||
} | ||
} | ||
} | ||
|
||
public fun Node.toInlineNode(): InlineMarkdown = when (this) { | ||
is CMText -> Text(this) | ||
is CMEmphasis -> Emphasis(this) | ||
is CMImage -> Image(this) | ||
is CMCode -> Code(this) | ||
is CMCustomNode -> CustomNode(this) | ||
is CMHardLineBreak -> HardLineBreak(this) | ||
is CMSoftLineBreak -> SoftLineBreak(this) | ||
is CMHtmlInline -> HtmlInline(this) | ||
is CMLink -> Link(this) | ||
is CMStrongEmphasis -> StrongEmphasis(this) | ||
else -> error("Unexpected block $this") | ||
} |
71 changes: 25 additions & 46 deletions
71
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,83 +1,62 @@ | ||
package org.jetbrains.jewel.markdown | ||
|
||
import org.intellij.lang.annotations.Language | ||
|
||
public sealed interface MarkdownBlock { | ||
|
||
public data class Paragraph(override val inlineContent: InlineMarkdown) : | ||
MarkdownBlock, BlockWithInlineMarkdown | ||
|
||
public sealed interface Heading : MarkdownBlock, BlockWithInlineMarkdown { | ||
|
||
public data class H1(override val inlineContent: InlineMarkdown) : Heading | ||
public data class BlockQuote(val content: List<MarkdownBlock>) : MarkdownBlock | ||
|
||
public data class H2(override val inlineContent: InlineMarkdown) : Heading | ||
public interface CustomBlock : MarkdownBlock | ||
|
||
public data class H3(override val inlineContent: InlineMarkdown) : Heading | ||
public sealed interface CodeBlock : MarkdownBlock { | ||
|
||
public data class H4(override val inlineContent: InlineMarkdown) : Heading | ||
public val content: String | ||
|
||
public data class H5(override val inlineContent: InlineMarkdown) : Heading | ||
public data class IndentedCodeBlock( | ||
override val content: String, | ||
) : CodeBlock | ||
|
||
public data class H6(override val inlineContent: InlineMarkdown) : Heading | ||
public data class FencedCodeBlock( | ||
override val content: String, | ||
val mimeType: MimeType?, | ||
) : CodeBlock | ||
} | ||
|
||
public data class BlockQuote(val content: List<MarkdownBlock>) : MarkdownBlock | ||
public data class Heading( | ||
override val inlineContent: List<InlineMarkdown>, | ||
val level: Int, | ||
) : MarkdownBlock, BlockWithInlineMarkdown | ||
|
||
public data class HtmlBlock(val content: String) : MarkdownBlock | ||
|
||
public sealed interface ListBlock : MarkdownBlock { | ||
|
||
public val items: List<ListItem> | ||
public val isTight: Boolean | ||
|
||
public data class OrderedList( | ||
public data class BulletList( | ||
override val items: List<ListItem>, | ||
override val isTight: Boolean, | ||
val startFrom: Int, | ||
val delimiter: Char, | ||
val bulletMarker: Char, | ||
) : ListBlock | ||
|
||
public data class UnorderedList( | ||
public data class OrderedList( | ||
override val items: List<ListItem>, | ||
override val isTight: Boolean, | ||
val bulletMarker: Char, | ||
val startFrom: Int, | ||
val delimiter: Char, | ||
) : ListBlock | ||
} | ||
|
||
public data class ListItem( | ||
val content: List<MarkdownBlock>, | ||
) : MarkdownBlock | ||
|
||
public sealed interface CodeBlock : MarkdownBlock { | ||
|
||
public val content: String | ||
|
||
public data class IndentedCodeBlock( | ||
override val content: String, | ||
) : CodeBlock | ||
|
||
public data class FencedCodeBlock( | ||
override val content: String, | ||
val mimeType: MimeType?, | ||
) : CodeBlock | ||
} | ||
|
||
public data class Image(val url: String, val altString: String?) : MarkdownBlock | ||
|
||
public object ThematicBreak : MarkdownBlock | ||
|
||
public data class HtmlBlock(val content: String) : MarkdownBlock | ||
|
||
public interface Extension : MarkdownBlock | ||
public data class Paragraph(override val inlineContent: List<InlineMarkdown>) : | ||
MarkdownBlock, BlockWithInlineMarkdown | ||
} | ||
|
||
public interface BlockWithInlineMarkdown { | ||
|
||
public val inlineContent: InlineMarkdown | ||
public val inlineContent: List<InlineMarkdown> | ||
} | ||
|
||
/** | ||
* A run of inline Markdown used as content for | ||
* [block-level elements][MarkdownBlock]. | ||
*/ | ||
@JvmInline | ||
public value class InlineMarkdown(@Language("Markdown") public val content: String) |
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
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
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
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
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.