Skip to content

Commit b0ba3c3

Browse files
author
Oleg Baskakov
committed
[JEWEL-TBD] Load markdown images using Coil3
It supports every image as an inline node
1 parent c64d343 commit b0ba3c3

File tree

10 files changed

+224
-32
lines changed

10 files changed

+224
-32
lines changed

.idea/runConfigurations/IDEA.xml

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

platform/jewel/gradle/libs.versions.toml

+7
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
[versions]
2+
coil = "3.0.4"
23
commonmark = "0.24.0"
34
composeDesktop = "1.7.1"
45
detekt = "1.23.6"
@@ -17,6 +18,11 @@ ktfmtGradlePlugin = "0.20.1"
1718
poko = "0.17.1"
1819

1920
[libraries]
21+
coil-compose = { module = "io.coil-kt.coil3:coil-compose", version.ref = "coil" }
22+
# network is only needed in a standalone non-ide version
23+
coil-network-ktor2 = { module = "io.coil-kt.coil3:coil-network-ktor2", version.ref = "coil" }
24+
coil-svg = { module = "io.coil-kt.coil3:coil-svg", version.ref = "coil" }
25+
2026
commonmark-core = { module = "org.commonmark:commonmark", version.ref = "commonmark" }
2127
commonmark-ext-autolink = { module = "org.commonmark:commonmark-ext-autolink", version.ref = "commonmark" }
2228

@@ -25,6 +31,7 @@ filePicker = { module = "com.darkrockstudios:mpfilepicker", version = "3.1.0" }
2531
kotlinSarif = { module = "io.github.detekt.sarif4k:sarif4k", version.ref = "kotlinSarif" }
2632
kotlin-reflect = { module = "org.jetbrains.kotlin:kotlin-reflect", version.ref = "kotlin" }
2733
kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kotlinxSerialization" }
34+
ktor-client-java = { module = "io.ktor:ktor-client-java", version = "2.3.12" }
2835

2936
jna-core = { module = "net.java.dev.jna:jna", version.ref = "jna" }
3037

platform/jewel/markdown/core/build.gradle.kts

+4
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ plugins {
99
dependencies {
1010
api(projects.ui)
1111
api(libs.commonmark.core)
12+
runtimeOnly(libs.ktor.client.java)
13+
implementation(libs.coil.compose)
14+
implementation(libs.coil.network.ktor2)
15+
implementation(libs.coil.svg)
1216

1317
testImplementation(compose.desktop.uiTestJUnit4)
1418
testImplementation(projects.ui)

platform/jewel/markdown/core/intellij.platform.jewel.markdown.core.iml

+90
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,96 @@
5656
</SOURCES>
5757
</library>
5858
</orderEntry>
59+
<orderEntry type="module-library">
60+
<library name="io.coil.kt.coil3.core.jvm" type="repository">
61+
<properties include-transitive-deps="false" maven-id="io.coil-kt.coil3:coil-core-jvm:3.0.4">
62+
<verification>
63+
<artifact url="file://$MAVEN_REPOSITORY$/io/coil-kt/coil3/coil-core-jvm/3.0.4/coil-core-jvm-3.0.4.jar">
64+
<sha256sum>635860bca98d3709b5714e3356100cb20af825a28d2f930bfcb448d7f78cfbdf</sha256sum>
65+
</artifact>
66+
</verification>
67+
</properties>
68+
<CLASSES>
69+
<root url="jar://$MAVEN_REPOSITORY$/io/coil-kt/coil3/coil-core-jvm/3.0.4/coil-core-jvm-3.0.4.jar!/" />
70+
</CLASSES>
71+
<JAVADOC />
72+
<SOURCES>
73+
<root url="jar://$MAVEN_REPOSITORY$/io/coil-kt/coil3/coil-core-jvm/3.0.4/coil-core-jvm-3.0.4-sources.jar!/" />
74+
</SOURCES>
75+
</library>
76+
</orderEntry>
77+
<orderEntry type="module-library">
78+
<library name="io.coil.kt.coil3.jvm" type="repository">
79+
<properties include-transitive-deps="false" maven-id="io.coil-kt.coil3:coil-jvm:3.0.4">
80+
<verification>
81+
<artifact url="file://$MAVEN_REPOSITORY$/io/coil-kt/coil3/coil-jvm/3.0.4/coil-jvm-3.0.4.jar">
82+
<sha256sum>cca25e168e69956d01c5581a6523582f1809805d74c478e91802a15e321906e4</sha256sum>
83+
</artifact>
84+
</verification>
85+
</properties>
86+
<CLASSES>
87+
<root url="jar://$MAVEN_REPOSITORY$/io/coil-kt/coil3/coil-jvm/3.0.4/coil-jvm-3.0.4.jar!/" />
88+
</CLASSES>
89+
<JAVADOC />
90+
<SOURCES>
91+
<root url="jar://$MAVEN_REPOSITORY$/io/coil-kt/coil3/coil-jvm/3.0.4/coil-jvm-3.0.4-sources.jar!/" />
92+
</SOURCES>
93+
</library>
94+
</orderEntry>
95+
<orderEntry type="module-library" exported="">
96+
<library name="io.coil.kt.coil3.compose.core.jvm" type="repository">
97+
<properties include-transitive-deps="false" maven-id="io.coil-kt.coil3:coil-compose-core-jvm:3.0.4">
98+
<verification>
99+
<artifact url="file://$MAVEN_REPOSITORY$/io/coil-kt/coil3/coil-compose-core-jvm/3.0.4/coil-compose-core-jvm-3.0.4.jar">
100+
<sha256sum>a0c8585e76bf426025d509e57fa09a7f9cc030327d641b93555714646b28721b</sha256sum>
101+
</artifact>
102+
</verification>
103+
</properties>
104+
<CLASSES>
105+
<root url="jar://$MAVEN_REPOSITORY$/io/coil-kt/coil3/coil-compose-core-jvm/3.0.4/coil-compose-core-jvm-3.0.4.jar!/" />
106+
</CLASSES>
107+
<JAVADOC />
108+
<SOURCES>
109+
<root url="jar://$MAVEN_REPOSITORY$/io/coil-kt/coil3/coil-compose-core-jvm/3.0.4/coil-compose-core-jvm-3.0.4-sources.jar!/" />
110+
</SOURCES>
111+
</library>
112+
</orderEntry>
113+
<orderEntry type="module-library" exported="">
114+
<library name="io.coil.kt.coil3.compose.jvm" type="repository">
115+
<properties include-transitive-deps="false" maven-id="io.coil-kt.coil3:coil-compose-jvm:3.0.4">
116+
<verification>
117+
<artifact url="file://$MAVEN_REPOSITORY$/io/coil-kt/coil3/coil-compose-jvm/3.0.4/coil-compose-jvm-3.0.4.jar">
118+
<sha256sum>fdff25fb0065a29130ef4fc2276c91c11fd69ea8df8b1c241f648ce1b161b5a3</sha256sum>
119+
</artifact>
120+
</verification>
121+
</properties>
122+
<CLASSES>
123+
<root url="jar://$MAVEN_REPOSITORY$/io/coil-kt/coil3/coil-compose-jvm/3.0.4/coil-compose-jvm-3.0.4.jar!/" />
124+
</CLASSES>
125+
<JAVADOC />
126+
<SOURCES>
127+
<root url="jar://$MAVEN_REPOSITORY$/io/coil-kt/coil3/coil-compose-jvm/3.0.4/coil-compose-jvm-3.0.4-sources.jar!/" />
128+
</SOURCES>
129+
</library>
130+
</orderEntry>
131+
<orderEntry type="module-library" exported="">
132+
<library name="io.coil.kt.coil3.svg.jvm" type="repository">
133+
<properties include-transitive-deps="false" maven-id="io.coil-kt.coil3:coil-svg-jvm:3.0.4">
134+
<verification>
135+
<artifact url="file://$MAVEN_REPOSITORY$/io/coil-kt/coil3/coil-svg-jvm/3.0.4/coil-svg-jvm-3.0.4.jar">
136+
<sha256sum>ce0c4898911033bc28eb1483ce48b6f87ec76d01fc04574b79a8e9dfd56aa311</sha256sum>
137+
</artifact>
138+
</verification>
139+
</properties>
140+
<CLASSES>
141+
<root url="jar://$MAVEN_REPOSITORY$/io/coil-kt/coil3/coil-svg-jvm/3.0.4/coil-svg-jvm-3.0.4.jar!/" />
142+
</CLASSES>
143+
<JAVADOC />
144+
<SOURCES>
145+
<root url="jar://$MAVEN_REPOSITORY$/io/coil-kt/coil3/coil-svg-jvm/3.0.4/coil-svg-jvm-3.0.4-sources.jar!/" />
146+
</SOURCES>
147+
</library>
148+
</orderEntry>
59149
<orderEntry type="module-library" scope="TEST">
60150
<library name="org.jetbrains.compose.ui.ui.test.junit4" type="repository">
61151
<properties include-transitive-deps="false" maven-id="org.jetbrains.compose.ui:ui-test-junit4:1.7.1">

platform/jewel/markdown/core/src/main/kotlin/org/jetbrains/jewel/markdown/Markdown.kt

+22
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ import androidx.compose.runtime.setValue
1717
import androidx.compose.ui.Modifier
1818
import androidx.compose.ui.semantics.semantics
1919
import androidx.compose.ui.unit.dp
20+
import coil3.ImageLoader
21+
import coil3.PlatformContext
22+
import coil3.compose.setSingletonImageLoaderFactory
23+
import coil3.memory.MemoryCache
2024
import kotlinx.coroutines.CoroutineDispatcher
2125
import kotlinx.coroutines.Dispatchers
2226
import kotlinx.coroutines.withContext
@@ -76,6 +80,8 @@ public fun Markdown(
7680
markdownStyling: MarkdownStyling = JewelTheme.markdownStyling,
7781
blockRenderer: MarkdownBlockRenderer = DefaultMarkdownBlockRenderer(markdownStyling),
7882
) {
83+
// TODO: delete this once Jewel is moved to intellij-community repo
84+
setSingletonImageLoaderFactory(::createImageLoader)
7985
if (selectable) {
8086
SelectionContainer(modifier.semantics { rawMarkdown = markdown }) {
8187
Column(verticalArrangement = Arrangement.spacedBy(markdownStyling.blockVerticalSpacing)) {
@@ -110,6 +116,8 @@ public fun LazyMarkdown(
110116
markdownStyling: MarkdownStyling = JewelTheme.markdownStyling,
111117
blockRenderer: MarkdownBlockRenderer = JewelTheme.markdownBlockRenderer,
112118
) {
119+
// TODO: delete this once Jewel is moved to intellij-community repo
120+
setSingletonImageLoaderFactory(::createImageLoader)
113121
if (selectable) {
114122
SelectionContainer(modifier) {
115123
LazyColumn(
@@ -131,3 +139,17 @@ public fun LazyMarkdown(
131139
}
132140
}
133141
}
142+
143+
private const val IMAGES_MEMORY_CACHE_SIZE = 24L * 1024 * 1024 // 24mb
144+
145+
/**
146+
* This method sets up an image loader with a memory cache but disables the disk cache. Disabling the disk cache is
147+
* necessary because Coil crashes when attempting to use the file system cache with IDEA platform.
148+
*
149+
* Otherwise Coil3 will throw java.lang.NoSuchMethodError: kotlinx.coroutines.CoroutineDispatcher.limitedParallelism
150+
*/
151+
private fun createImageLoader(context: PlatformContext) =
152+
ImageLoader.Builder(context)
153+
.memoryCache { MemoryCache.Builder().maxSizeBytes(IMAGES_MEMORY_CACHE_SIZE).build() }
154+
.diskCache(null)
155+
.build()

platform/jewel/markdown/core/src/main/kotlin/org/jetbrains/jewel/markdown/processing/MarkdownProcessor.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,7 @@ public class MarkdownProcessor(
236236
}
237237

238238
private fun Node.tryProcessMarkdownBlock(): MarkdownBlock? =
239-
// Non-Block children are ignored
239+
// Nodes that are not blocks or unsupported types are ignored
240240
when (this) {
241241
is Paragraph -> toMarkdownParagraph()
242242
is Heading -> toMarkdownHeadingOrNull()

platform/jewel/markdown/core/src/main/kotlin/org/jetbrains/jewel/markdown/rendering/DefaultInlineMarkdownRenderer.kt

+1-11
Original file line numberDiff line numberDiff line change
@@ -77,17 +77,7 @@ public open class DefaultInlineMarkdownRenderer(private val rendererExtensions:
7777
}
7878

7979
is InlineMarkdown.Image -> {
80-
appendInlineContent(
81-
INLINE_IMAGE,
82-
buildString {
83-
appendLine(child.source)
84-
append(child.alt)
85-
if (!child.title.isNullOrBlank()) {
86-
appendLine()
87-
append(child.title)
88-
}
89-
},
90-
)
80+
appendInlineContent(child.source, "![${child.title}](...)")
9181
}
9282

9383
is InlineMarkdown.CustomNode ->

0 commit comments

Comments
 (0)