Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add an autolink extension for Markdown #341

Merged
merged 1 commit into from
Apr 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ poko = "0.13.1"

[libraries]
commonmark-core = { module = "org.commonmark:commonmark", version.ref = "commonmark" }
commonmark-ext-autolink = { module = "org.commonmark:commonmark-ext-autolink", version.ref = "commonmark" }

filePicker = { module = "com.darkrockstudios:mpfilepicker", version = "3.1.0" }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,25 +9,28 @@ import org.jetbrains.jewel.markdown.MarkdownBlock
/** An extension for the Jewel Markdown processing engine. */
@ExperimentalJewelApi
public interface MarkdownProcessorExtension {

/**
* A CommonMark [ParserExtension] that will be used to parse the extended
* syntax represented by this extension instance.
* syntax represented by this extension instance. Null in the case where
* parsing is already handled by an existing [org.commonmark.parser.Parser].
*/
public val parserExtension: ParserExtension
public val parserExtension: ParserExtension?

/**
* A CommonMark [TextContentRendererExtension] that will be used to render
* the text content of the CommonMark [CustomBlock] produced by the
* [parserExtension].
* [parserExtension]. Null in the case where rendering is already
* handled by an existing [org.commonmark.renderer.Renderer].
*/
public val textRendererExtension: TextContentRendererExtension
public val textRendererExtension: TextContentRendererExtension?

/**
* An extension for
* [`MarkdownParser`][org.jetbrains.jewel.markdown.parsing.MarkdownParser]
* that will transform a supported [CustomBlock] into the corresponding
* [MarkdownBlock.CustomBlock].
* [MarkdownBlock.CustomBlock]. Null in the case where processing
* is already be handled by [org.jetbrains.jewel.markdown.processing.MarkdownProcessor]
* or another [org.jetbrains.jewel.markdown.extensions.MarkdownProcessorExtension].
*/
public val processorExtension: MarkdownBlockProcessorExtension
public val processorExtension: MarkdownBlockProcessorExtension?
}
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ public class MarkdownProcessor(
is ThematicBreak -> MarkdownBlock.ThematicBreak
is HtmlBlock -> toMarkdownHtmlBlockOrNull()
is CustomBlock -> {
extensions.find { it.processorExtension.canProcess(this) }
extensions.find { it.processorExtension?.canProcess(this) == true }
?.processorExtension?.processMarkdownBlock(this, this@MarkdownProcessor)
}
else -> null
Expand Down
8 changes: 8 additions & 0 deletions markdown/extension/autolink/api/autolink.api
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
public final class org/jetbrains/jewel/markdown/extension/autolink/AutolinkProcessorExtension : org/jetbrains/jewel/markdown/extensions/MarkdownProcessorExtension {
public static final field $stable I
public static final field INSTANCE Lorg/jetbrains/jewel/markdown/extension/autolink/AutolinkProcessorExtension;
public fun getParserExtension ()Lorg/commonmark/parser/Parser$ParserExtension;
public fun getProcessorExtension ()Lorg/jetbrains/jewel/markdown/extensions/MarkdownBlockProcessorExtension;
public fun getTextRendererExtension ()Lorg/commonmark/renderer/text/TextContentRenderer$TextContentRendererExtension;
}

17 changes: 17 additions & 0 deletions markdown/extension/autolink/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
plugins {
jewel
`jewel-publish`
`jewel-check-public-api`
alias(libs.plugins.composeDesktop)
}

dependencies {
implementation(projects.markdown.core)
implementation(libs.commonmark.ext.autolink)
testImplementation(compose.desktop.uiTestJUnit4)
}

publishing.publications.named<MavenPublication>("main") {
val ijpTarget = project.property("ijp.target") as String
artifactId = "jewel-markdown-extension-${project.name}-$ijpTarget"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package org.jetbrains.jewel.markdown.extension.autolink

import org.commonmark.ext.autolink.AutolinkExtension
import org.commonmark.parser.Parser.ParserExtension
import org.commonmark.renderer.text.TextContentRenderer
import org.jetbrains.jewel.markdown.extensions.MarkdownBlockProcessorExtension
import org.jetbrains.jewel.markdown.extensions.MarkdownProcessorExtension

public object AutolinkProcessorExtension : MarkdownProcessorExtension {
override val parserExtension: ParserExtension
get() = AutolinkExtension.create() as ParserExtension

/**
* Rendering and processing is already handled by [org.jetbrains.jewel.markdown.rendering.DefaultInlineMarkdownRenderer]
*/
override val textRendererExtension: TextContentRenderer.TextContentRendererExtension?
get() = null
override val processorExtension: MarkdownBlockProcessorExtension?
get() = null
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package org.jetbrains.jewel.markdown.extension.autolink

import org.jetbrains.jewel.markdown.InlineMarkdown
import org.jetbrains.jewel.markdown.MarkdownBlock
import org.jetbrains.jewel.markdown.processing.MarkdownProcessor
import org.junit.Assert.assertTrue
import org.junit.Test

class AutolinkProcessorExtensionTest {
// testing a simple case to assure wiring up our AutolinkProcessorExtension works correctly
@Test
fun `https text gets processed into a link`() {
val processor = MarkdownProcessor(listOf(AutolinkProcessorExtension))
val rawMarkDown = "https://commonmark.org"
val processed = processor.processMarkdownDocument(rawMarkDown)
val paragraph = processed[0] as MarkdownBlock.Paragraph

assertTrue(paragraph.inlineContent[0] is InlineMarkdown.Link)
}
}
2 changes: 1 addition & 1 deletion samples/standalone/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ dependencies {
implementation(projects.intUi.intUiDecoratedWindow)
implementation(projects.markdown.intUiStandaloneStyling)
implementation(projects.markdown.extension.gfmAlerts)

implementation(projects.markdown.extension.autolink)
implementation(compose.desktop.currentOs) {
exclude(group = "org.jetbrains.compose.material")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import org.jetbrains.jewel.intui.markdown.styling.extension.github.alerts.dark
import org.jetbrains.jewel.intui.markdown.styling.extension.github.alerts.light
import org.jetbrains.jewel.intui.markdown.styling.light
import org.jetbrains.jewel.markdown.MarkdownBlock
import org.jetbrains.jewel.markdown.extension.autolink.AutolinkProcessorExtension
import org.jetbrains.jewel.markdown.extensions.github.alerts.AlertStyling
import org.jetbrains.jewel.markdown.extensions.github.alerts.GitHubAlertProcessorExtension
import org.jetbrains.jewel.markdown.extensions.github.alerts.GitHubAlertRendererExtension
Expand All @@ -43,14 +44,17 @@ import java.awt.Desktop
import java.net.URI

@Composable
internal fun MarkdownPreview(rawMarkdown: String, modifier: Modifier = Modifier) {
internal fun MarkdownPreview(
rawMarkdown: String,
modifier: Modifier = Modifier,
) {
val isDark = JewelTheme.isDark

val markdownStyling =
remember(isDark) { if (isDark) MarkdownStyling.dark() else MarkdownStyling.light() }

var markdownBlocks by remember { mutableStateOf(emptyList<MarkdownBlock>()) }
val extensions = listOf(GitHubAlertProcessorExtension)
val extensions = listOf(GitHubAlertProcessorExtension, AutolinkProcessorExtension)
val processor = remember { MarkdownProcessor(extensions) }

LaunchedEffect(rawMarkdown) {
Expand Down
1 change: 1 addition & 0 deletions settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ include(
":int-ui:int-ui-decorated-window",
":int-ui:int-ui-standalone",
":markdown:core",
":markdown:extension:autolink",
":markdown:extension:gfm-alerts",
":markdown:int-ui-standalone-styling",
":markdown:ide-laf-bridge-styling",
Expand Down
Loading