Skip to content

Commit

Permalink
Merge branch 'main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
jeziellago authored Dec 18, 2024
2 parents baebc95 + 020e861 commit c4ef325
Show file tree
Hide file tree
Showing 5 changed files with 167 additions and 26 deletions.
1 change: 1 addition & 0 deletions markdowntext/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ dependencies {
implementation "com.github.jeziellago:Markwon:58aa5aba6a"

api("io.coil-kt:coil:2.6.0")
api("io.coil-kt:coil-gif:2.6.0")

// Jetpack Compose
implementation "androidx.compose.ui:ui:$compose_version"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,16 @@ package dev.jeziellago.compose.markdowntext

import android.content.Context
import android.graphics.drawable.ColorDrawable
import android.os.Build.VERSION.SDK_INT
import android.text.Spanned
import android.widget.TextView
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.toArgb
import coil.ImageLoader
import coil.imageLoader
import coil.decode.GifDecoder
import coil.decode.ImageDecoderDecoder
import dev.jeziellago.compose.markdowntext.plugins.core.MardownCorePlugin
import dev.jeziellago.compose.markdowntext.plugins.image.ImagesPlugin
import dev.jeziellago.compose.markdowntext.plugins.syntaxhighlight.SyntaxHighlightPlugin
import io.noties.markwon.AbstractMarkwonPlugin
import io.noties.markwon.Markwon
Expand Down Expand Up @@ -42,7 +45,16 @@ internal object MarkdownRender {
afterSetMarkdown: ((TextView) -> Unit)? = null,
onLinkClicked: ((String) -> Unit)? = null,
): Markwon {
val coilImageLoader = imageLoader ?: context.imageLoader
val coilImageLoader = imageLoader ?: ImageLoader.Builder(context)
.components {
if (SDK_INT >= 28) {
add(ImageDecoderDecoder.Factory())
} else {
add(GifDecoder.Factory())
}
}
.build()

return Markwon.builderNoCore(context)
.usePlugin(
MardownCorePlugin(
Expand All @@ -52,7 +64,7 @@ internal object MarkdownRender {
)
)
.usePlugin(HtmlPlugin.create())
.usePlugin(CoilImagesPlugin.create(context, coilImageLoader))
.usePlugin(ImagesPlugin.create(context, coilImageLoader))
.usePlugin(StrikethroughPlugin.create())
.usePlugin(TablePlugin.create(context))
.usePlugin(LinkifyPlugin.create(linkifyMask))
Expand All @@ -61,27 +73,7 @@ internal object MarkdownRender {
.usePlugin(JLatexMathPlugin.create(textSizePx) { builder ->
builder.inlinesEnabled(true)
builder.theme().backgroundProvider { ColorDrawable(backgroundColor.toArgb()) }

// text color of LaTeX content for both inlines and blocks
// or more specific: `inlineTextColor` & `blockTextColor`
builder.theme().textColor(textColor.toArgb());

// // should block fit the whole canvas width, by default true
// builder.theme().blockFitCanvas(true);

// // horizontal alignment for block, by default ALIGN_CENTER
// builder.theme().blockHorizontalAlignment(JLatexMathDrawable.ALIGN_CENTER);

// // padding for both inlines and blocks
// builder.theme().padding(JLatexMathTheme.Padding.all(8));
//
// // padding for inlines
// builder.theme().inlinePadding(JLatexMathTheme.Padding.symmetric(16, 8));
//
// // padding for blocks
// builder.theme().blockPadding(new JLatexMathTheme . Padding (0, 1, 2, 3));


})
.apply {
if (enableSoftBreakAddsNewLine) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package dev.jeziellago.compose.markdowntext.plugins.core
import androidx.annotation.VisibleForTesting
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.toArgb
import dev.jeziellago.compose.markdowntext.plugins.syntaxhighlight.SyntaxHighlight
import io.noties.markwon.MarkwonSpansFactory
import io.noties.markwon.MarkwonVisitor
import io.noties.markwon.core.CorePlugin
Expand Down Expand Up @@ -85,7 +84,6 @@ class MardownCorePlugin(
.setFactory(Emphasis::class.java, EmphasisSpanFactory())
.setFactory(BlockQuote::class.java, BlockQuoteSpanFactory())
.setFactory(Code::class.java, CodeSpanFactory())
// .setFactory(SyntaxHighlight::class.java, CodeSpanFactory())
.setFactory(FencedCodeBlock::class.java, codeBlockSpanFactory)
.setFactory(IndentedCodeBlock::class.java, codeBlockSpanFactory)
.setFactory(ListItem::class.java, ListItemSpanFactory())
Expand All @@ -99,7 +97,6 @@ class MardownCorePlugin(
return this
}


private fun text(builder: MarkwonVisitor.Builder) {
builder.on(
Text::class.java
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
package dev.jeziellago.compose.markdowntext.plugins.image

import android.content.Context
import android.graphics.drawable.Animatable
import android.graphics.drawable.Drawable
import android.text.Spanned
import android.widget.TextView
import coil.ImageLoader
import coil.request.Disposable
import coil.request.ImageRequest
import coil.target.Target
import io.noties.markwon.AbstractMarkwonPlugin
import io.noties.markwon.MarkwonConfiguration
import io.noties.markwon.MarkwonSpansFactory
import io.noties.markwon.image.AsyncDrawable
import io.noties.markwon.image.AsyncDrawableLoader
import io.noties.markwon.image.AsyncDrawableScheduler
import io.noties.markwon.image.DrawableUtils
import io.noties.markwon.image.ImageSpanFactory
import java.util.concurrent.atomic.AtomicBoolean

class ImagesPlugin private constructor(
private val imageLoader: ImageLoader,
private val coilStore: CoilStore,
private val imageDrawableLoader: AnimatedImageDrawableLoader = AnimatedImageDrawableLoader(
coilStore,
imageLoader
)
) : AbstractMarkwonPlugin() {

override fun configureSpansFactory(builder: MarkwonSpansFactory.Builder) {
builder.setFactory(org.commonmark.node.Image::class.java, ImageSpanFactory())
}

override fun configureConfiguration(builder: MarkwonConfiguration.Builder) {
builder.asyncDrawableLoader(imageDrawableLoader)
}

override fun beforeSetText(textView: TextView, markdown: Spanned) {
AsyncDrawableScheduler.unschedule(textView)
}

override fun afterSetText(textView: TextView) {
AsyncDrawableScheduler.schedule(textView)
}

companion object {
private val cache: HashMap<AsyncDrawable, Disposable> = HashMap(2)

fun create(context: Context, imageLoader: ImageLoader): ImagesPlugin {
val coilStore = object : CoilStore {
override fun load(drawable: AsyncDrawable): ImageRequest {
return ImageRequest.Builder(context)
.data(drawable.destination)
.build()
}

override fun cancel(disposable: Disposable) {
disposable.dispose()
}
}
return ImagesPlugin(imageLoader, coilStore)
}

class AnimatedImageDrawableLoader(
private val coilStore: CoilStore,
private val imageLoader: ImageLoader,
) : AsyncDrawableLoader() {

override fun load(drawable: AsyncDrawable) {
val loaded = AtomicBoolean(false)
val target: Target = AnimatedDrawableTarget(drawable, loaded)
val request = coilStore.load(drawable).newBuilder()
.target(target)
.build()

val disposable = imageLoader.enqueue(request)
if (!loaded.get()) {
loaded.set(true)
cache[drawable] = disposable
}
}

override fun cancel(drawable: AsyncDrawable) {
val disposable = cache.remove(drawable)
if (disposable != null) {
coilStore.cancel(disposable)
}
}

override fun placeholder(drawable: AsyncDrawable): Drawable? = null

class AnimatedDrawableTarget(
private val drawable: AsyncDrawable,
private val loaded: AtomicBoolean
) : Target {
override fun onSuccess(result: Drawable) {
if (cache.remove(drawable) != null || !loaded.get()) {
loaded.set(true)
if (drawable.isAttached) {
DrawableUtils.applyIntrinsicBoundsIfEmpty(result)
drawable.result = result

if (result is Animatable) {
(result as Animatable).start()
}
}
}
}

override fun onStart(placeholder: Drawable?) {
if (placeholder != null && drawable.isAttached) {
DrawableUtils.applyIntrinsicBoundsIfEmpty(placeholder)
drawable.result = placeholder
}
}

override fun onError(error: Drawable?) {
if (cache.remove(drawable) != null) {
if (error != null && drawable.isAttached) {
DrawableUtils.applyIntrinsicBoundsIfEmpty(error)
drawable.result = error
}
}
}
}
}
}

interface CoilStore {
fun load(drawable: AsyncDrawable): ImageRequest
fun cancel(disposable: Disposable)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,26 @@ class MainActivity : AppCompatActivity() {
) {
item {
MarkdownText(
modifier = Modifier
.padding(8.dp)
.fillMaxWidth(),
markdown = """
## Gif Images
![Image](https://user-images.githubusercontent.com/14011726/94132137-7d4fc100-fe7c-11ea-8512-69f90cb65e48.gif)
---
""".trimIndent()
)
}
item {
MarkdownText(
markdown = """
## Checks
- [x] Review #123
- [ ] Complete XYZ
- [ ] Add delight to the experience when all tasks are complete :tada:
---
""".trimIndent(),
)
}
Expand All @@ -48,6 +64,7 @@ class MainActivity : AppCompatActivity() {
syntaxHighlightColor = Color.Black,
syntaxHighlightTextColor = Color.White,
markdown = """
## Text highlight
Sometimes we need to ==highlight== a text in `different` ways.
---
Expand Down

0 comments on commit c4ef325

Please sign in to comment.