sample, add copy code block
This commit is contained in:
parent
205ae7b47a
commit
2ea148c30a
@ -1,4 +1,19 @@
|
|||||||
[
|
[
|
||||||
|
{
|
||||||
|
"javaClassName": "io.noties.markwon.app.samples.CopyCodeBlockSample",
|
||||||
|
"id": "20210315112847",
|
||||||
|
"title": "Copy code block",
|
||||||
|
"description": "Copy contents of fenced code blocks",
|
||||||
|
"artifacts": [
|
||||||
|
"CORE"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"block",
|
||||||
|
"rendering",
|
||||||
|
"span",
|
||||||
|
"spanFactory"
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"javaClassName": "io.noties.markwon.app.samples.parser.RedditSuperscriptSample",
|
"javaClassName": "io.noties.markwon.app.samples.parser.RedditSuperscriptSample",
|
||||||
"id": "20210224091506",
|
"id": "20210224091506",
|
||||||
|
@ -0,0 +1,119 @@
|
|||||||
|
package io.noties.markwon.app.samples
|
||||||
|
|
||||||
|
import android.graphics.Canvas
|
||||||
|
import android.graphics.Paint
|
||||||
|
import android.graphics.drawable.Drawable
|
||||||
|
import android.text.Layout
|
||||||
|
import android.text.Spanned
|
||||||
|
import android.text.TextPaint
|
||||||
|
import android.text.style.ClickableSpan
|
||||||
|
import android.text.style.LeadingMarginSpan
|
||||||
|
import android.view.View
|
||||||
|
import android.widget.TextView
|
||||||
|
import io.noties.debug.Debug
|
||||||
|
import io.noties.markwon.AbstractMarkwonPlugin
|
||||||
|
import io.noties.markwon.Markwon
|
||||||
|
import io.noties.markwon.MarkwonSpansFactory
|
||||||
|
import io.noties.markwon.app.R
|
||||||
|
import io.noties.markwon.app.sample.ui.MarkwonTextViewSample
|
||||||
|
import io.noties.markwon.sample.annotations.MarkwonArtifact
|
||||||
|
import io.noties.markwon.sample.annotations.MarkwonSampleInfo
|
||||||
|
import io.noties.markwon.sample.annotations.Tag
|
||||||
|
import io.noties.markwon.utils.LeadingMarginUtils
|
||||||
|
import org.commonmark.node.FencedCodeBlock
|
||||||
|
|
||||||
|
@MarkwonSampleInfo(
|
||||||
|
id = "20210315112847",
|
||||||
|
title = "Copy code block",
|
||||||
|
description = "Copy contents of fenced code blocks",
|
||||||
|
artifacts = [MarkwonArtifact.CORE],
|
||||||
|
tags = [Tag.rendering, Tag.block, Tag.spanFactory, Tag.span]
|
||||||
|
)
|
||||||
|
class CopyCodeBlockSample : MarkwonTextViewSample() {
|
||||||
|
|
||||||
|
override fun render() {
|
||||||
|
val md = """
|
||||||
|
# Hello code blocks!
|
||||||
|
```java
|
||||||
|
final int i = 0;
|
||||||
|
final Type t = Type.init()
|
||||||
|
.filter(i -> i.even)
|
||||||
|
.first(null);
|
||||||
|
```
|
||||||
|
bye bye!
|
||||||
|
""".trimIndent()
|
||||||
|
|
||||||
|
val markwon = Markwon.builder(context)
|
||||||
|
.usePlugin(object : AbstractMarkwonPlugin() {
|
||||||
|
override fun configureSpansFactory(builder: MarkwonSpansFactory.Builder) {
|
||||||
|
builder.appendFactory(FencedCodeBlock::class.java) { _, _ ->
|
||||||
|
CopyContentsSpan()
|
||||||
|
}
|
||||||
|
builder.appendFactory(FencedCodeBlock::class.java) { _, _ ->
|
||||||
|
CopyIconSpan(context.getDrawable(R.drawable.ic_code_white_24dp)!!)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.build()
|
||||||
|
|
||||||
|
markwon.setMarkdown(textView, md)
|
||||||
|
}
|
||||||
|
|
||||||
|
class CopyContentsSpan : ClickableSpan() {
|
||||||
|
override fun onClick(widget: View) {
|
||||||
|
val spanned = (widget as? TextView)?.text as? Spanned ?: return
|
||||||
|
val start = spanned.getSpanStart(this)
|
||||||
|
val end = spanned.getSpanEnd(this)
|
||||||
|
// by default code blocks have new lines before and after content
|
||||||
|
val contents = spanned.subSequence(start, end).toString().trim()
|
||||||
|
// copy code here
|
||||||
|
Debug.i(contents)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun updateDrawState(ds: TextPaint) {
|
||||||
|
// do not apply link styling
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class CopyIconSpan(val icon: Drawable) : LeadingMarginSpan {
|
||||||
|
|
||||||
|
init {
|
||||||
|
if (icon.bounds.isEmpty) {
|
||||||
|
icon.setBounds(0, 0, icon.intrinsicWidth, icon.intrinsicHeight)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getLeadingMargin(first: Boolean): Int = 0
|
||||||
|
|
||||||
|
override fun drawLeadingMargin(
|
||||||
|
c: Canvas,
|
||||||
|
p: Paint,
|
||||||
|
x: Int,
|
||||||
|
dir: Int,
|
||||||
|
top: Int,
|
||||||
|
baseline: Int,
|
||||||
|
bottom: Int,
|
||||||
|
text: CharSequence,
|
||||||
|
start: Int,
|
||||||
|
end: Int,
|
||||||
|
first: Boolean,
|
||||||
|
layout: Layout
|
||||||
|
) {
|
||||||
|
|
||||||
|
// called for each line of text, we are interested only in first one
|
||||||
|
if (!LeadingMarginUtils.selfStart(start, text, this)) return
|
||||||
|
|
||||||
|
val save = c.save()
|
||||||
|
try {
|
||||||
|
// horizontal position for icon
|
||||||
|
val w = icon.bounds.width().toFloat()
|
||||||
|
// minus quarter width as padding
|
||||||
|
val left = layout.width - w - (w / 4F)
|
||||||
|
c.translate(left, top.toFloat())
|
||||||
|
icon.draw(c)
|
||||||
|
} finally {
|
||||||
|
c.restoreToCount(save)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -34,7 +34,7 @@ public class GithubUserIssueInlineParsingSample extends MarkwonTextViewSample {
|
|||||||
"# Custom Extension 2\n" +
|
"# Custom Extension 2\n" +
|
||||||
"\n" +
|
"\n" +
|
||||||
"This is an issue #1\n" +
|
"This is an issue #1\n" +
|
||||||
"Done by @noties";
|
"Done by @noties and other @dude";
|
||||||
|
|
||||||
final InlineParserFactory inlineParserFactory = MarkwonInlineParser.factoryBuilder()
|
final InlineParserFactory inlineParserFactory = MarkwonInlineParser.factoryBuilder()
|
||||||
// include all current defaults (otherwise will be empty - contain only our inline-processors)
|
// include all current defaults (otherwise will be empty - contain only our inline-processors)
|
||||||
|
@ -36,7 +36,7 @@ public class GithubUserIssueOnTextAddedSample extends MarkwonTextViewSample {
|
|||||||
"# Custom Extension 2\n" +
|
"# Custom Extension 2\n" +
|
||||||
"\n" +
|
"\n" +
|
||||||
"This is an issue #1\n" +
|
"This is an issue #1\n" +
|
||||||
"Done by @noties";
|
"Done by @noties and other @dude";
|
||||||
|
|
||||||
final Markwon markwon = Markwon.builder(context)
|
final Markwon markwon = Markwon.builder(context)
|
||||||
.usePlugin(new AbstractMarkwonPlugin() {
|
.usePlugin(new AbstractMarkwonPlugin() {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user