package com.github.gotify import android.content.Context import android.graphics.Color import android.graphics.Typeface import android.text.style.BackgroundColorSpan import android.text.style.BulletSpan import android.text.style.QuoteSpan import android.text.style.RelativeSizeSpan import android.text.style.StyleSpan import android.text.style.TypefaceSpan import androidx.core.content.ContextCompat import com.squareup.picasso.Picasso import io.noties.markwon.AbstractMarkwonPlugin import io.noties.markwon.Markwon import io.noties.markwon.MarkwonSpansFactory import io.noties.markwon.MarkwonVisitor import io.noties.markwon.RenderProps import io.noties.markwon.core.CorePlugin import io.noties.markwon.core.CoreProps import io.noties.markwon.core.MarkwonTheme import io.noties.markwon.ext.strikethrough.StrikethroughPlugin import io.noties.markwon.ext.tables.TableAwareMovementMethod import io.noties.markwon.ext.tables.TablePlugin import io.noties.markwon.image.picasso.PicassoImagesPlugin import io.noties.markwon.movement.MovementMethodPlugin import org.commonmark.ext.gfm.tables.TableCell import org.commonmark.ext.gfm.tables.TablesExtension import org.commonmark.node.BlockQuote import org.commonmark.node.Code import org.commonmark.node.Emphasis import org.commonmark.node.Heading import org.commonmark.node.Link import org.commonmark.node.ListItem import org.commonmark.node.StrongEmphasis import org.commonmark.parser.Parser internal object MarkwonFactory { fun createForMessage(context: Context, picasso: Picasso): Markwon { return Markwon.builder(context) .usePlugin(CorePlugin.create()) .usePlugin(MovementMethodPlugin.create(TableAwareMovementMethod.create())) .usePlugin(PicassoImagesPlugin.create(picasso)) .usePlugin(StrikethroughPlugin.create()) .usePlugin(TablePlugin.create(context)) .usePlugin(object : AbstractMarkwonPlugin() { override fun configureTheme(builder: MarkwonTheme.Builder) { builder.linkColor(ContextCompat.getColor(context, R.color.hyperLink)) .isLinkUnderlined(true) } }) .build() } fun createForNotification(context: Context, picasso: Picasso): Markwon { val headingSizes = floatArrayOf(2f, 1.5f, 1.17f, 1f, .83f, .67f) val bulletGapWidth = (8 * context.resources.displayMetrics.density + 0.5f).toInt() return Markwon.builder(context) .usePlugin(CorePlugin.create()) .usePlugin(PicassoImagesPlugin.create(picasso)) .usePlugin(StrikethroughPlugin.create()) .usePlugin(object : AbstractMarkwonPlugin() { override fun configureSpansFactory(builder: MarkwonSpansFactory.Builder) { builder.setFactory(Heading::class.java) { _, props: RenderProps? -> arrayOf( RelativeSizeSpan( headingSizes[CoreProps.HEADING_LEVEL.require(props!!) - 1] ), StyleSpan(Typeface.BOLD) ) } .setFactory(Emphasis::class.java) { _, _ -> StyleSpan(Typeface.ITALIC) } .setFactory(StrongEmphasis::class.java) { _, _ -> StyleSpan(Typeface.BOLD) } .setFactory(BlockQuote::class.java) { _, _ -> QuoteSpan() } .setFactory(Code::class.java) { _, _ -> arrayOf( BackgroundColorSpan(Color.LTGRAY), TypefaceSpan("monospace") ) } .setFactory(ListItem::class.java) { _, _ -> BulletSpan(bulletGapWidth) } .setFactory(Link::class.java) { _, _ -> null } } override fun configureParser(builder: Parser.Builder) { builder.extensions(setOf(TablesExtension.create())) } override fun configureVisitor(builder: MarkwonVisitor.Builder) { builder.on(TableCell::class.java) { visitor: MarkwonVisitor, node: TableCell? -> visitor.visitChildren(node!!) visitor.builder().append(' ') } } }) .build() } }