sample, add reddit spoiler sample
This commit is contained in:
parent
55e640af9c
commit
06413aaf36
@ -84,7 +84,7 @@ and [3.x.x](https://github.com/noties/Markwon/tree/3.x.x) branches
|
||||
|
||||
## Screenshots
|
||||
|
||||
Taken with default configuration (except for image loading):
|
||||
Taken with default configuration (except for image loading) in [sample app](./app-sample/):
|
||||
|
||||
<a href="./art/mw_light_01.png"><img src="./art/mw_light_01.png" width="30%" /></a>
|
||||
<a href="./art/mw_light_02.png"><img src="./art/mw_light_02.png" width="30%" /></a>
|
||||
|
@ -1,4 +1,16 @@
|
||||
[
|
||||
{
|
||||
"javaClassName": "io.noties.markwon.app.samples.RedditSpoilerSample",
|
||||
"id": "20200813145316",
|
||||
"title": "Reddit spoiler",
|
||||
"description": "An attempt to implement Reddit spoiler syntax `\u003e! !\u003c`",
|
||||
"artifacts": [
|
||||
"CORE"
|
||||
],
|
||||
"tags": [
|
||||
"parsing"
|
||||
]
|
||||
},
|
||||
{
|
||||
"javaClassName": "io.noties.markwon.app.samples.image.CoilRecyclerViewSample",
|
||||
"id": "20200803132053",
|
||||
|
@ -0,0 +1,126 @@
|
||||
package io.noties.markwon.app.samples;
|
||||
|
||||
import android.graphics.Color;
|
||||
import android.text.Spannable;
|
||||
import android.text.Spanned;
|
||||
import android.text.TextPaint;
|
||||
import android.text.style.CharacterStyle;
|
||||
import android.text.style.ClickableSpan;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import io.noties.markwon.AbstractMarkwonPlugin;
|
||||
import io.noties.markwon.Markwon;
|
||||
import io.noties.markwon.app.sample.Tags;
|
||||
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.utils.ColorUtils;
|
||||
|
||||
@MarkwonSampleInfo(
|
||||
id = "20200813145316",
|
||||
title = "Reddit spoiler",
|
||||
description = "An attempt to implement Reddit spoiler syntax `>! !<`",
|
||||
artifacts = MarkwonArtifact.CORE,
|
||||
tags = Tags.parsing
|
||||
)
|
||||
public class RedditSpoilerSample extends MarkwonTextViewSample {
|
||||
@Override
|
||||
public void render() {
|
||||
final String md = "" +
|
||||
"# Reddit spolier\n\n" +
|
||||
"Hello >!ugly so **ugly** !<, how are you?\n\n" +
|
||||
">!a blockquote?!< should not be >!present!< yeah" +
|
||||
"";
|
||||
|
||||
final Markwon markwon = Markwon.builder(context)
|
||||
.usePlugin(new RedditSpoilerPlugin())
|
||||
.build();
|
||||
|
||||
markwon.setMarkdown(textView, md);
|
||||
}
|
||||
}
|
||||
|
||||
class RedditSpoilerPlugin extends AbstractMarkwonPlugin {
|
||||
|
||||
private static final Pattern RE = Pattern.compile(">!.+?!<");
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public String processMarkdown(@NonNull String markdown) {
|
||||
// replace all `>!` with `>!` so no blockquote would be parsed (when spoiler starts at new line)
|
||||
return markdown.replaceAll(">!", ">!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeSetText(@NonNull TextView textView, @NonNull Spanned markdown) {
|
||||
applySpoilerSpans((Spannable) markdown);
|
||||
}
|
||||
|
||||
private static void applySpoilerSpans(@NonNull Spannable spannable) {
|
||||
final String text = spannable.toString();
|
||||
final Matcher matcher = RE.matcher(text);
|
||||
|
||||
while (matcher.find()) {
|
||||
|
||||
final RedditSpoilerSpan spoilerSpan = new RedditSpoilerSpan();
|
||||
final ClickableSpan clickableSpan = new ClickableSpan() {
|
||||
@Override
|
||||
public void onClick(@NonNull View widget) {
|
||||
spoilerSpan.setRevealed(true);
|
||||
widget.postInvalidateOnAnimation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateDrawState(@NonNull TextPaint ds) {
|
||||
// no op
|
||||
}
|
||||
};
|
||||
|
||||
final int s = matcher.start();
|
||||
final int e = matcher.end();
|
||||
spannable.setSpan(spoilerSpan, s, e, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
spannable.setSpan(clickableSpan, s, e, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
|
||||
// we also can hide original syntax
|
||||
spannable.setSpan(new HideSpoilerSyntaxSpan(), s, s + 2, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
spannable.setSpan(new HideSpoilerSyntaxSpan(), e - 2, e, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
}
|
||||
}
|
||||
|
||||
private static class RedditSpoilerSpan extends CharacterStyle {
|
||||
|
||||
private boolean revealed;
|
||||
|
||||
@Override
|
||||
public void updateDrawState(TextPaint tp) {
|
||||
if (!revealed) {
|
||||
// use the same text color
|
||||
tp.bgColor = Color.BLACK;
|
||||
tp.setColor(Color.BLACK);
|
||||
} else {
|
||||
// for example keep a bit of black background to remind that it is a spoiler
|
||||
tp.bgColor = ColorUtils.applyAlpha(Color.BLACK, 25);
|
||||
}
|
||||
}
|
||||
|
||||
public void setRevealed(boolean revealed) {
|
||||
this.revealed = revealed;
|
||||
}
|
||||
}
|
||||
|
||||
// we also could make text size smaller (but then MetricAffectingSpan should be used)
|
||||
private static class HideSpoilerSyntaxSpan extends CharacterStyle {
|
||||
|
||||
@Override
|
||||
public void updateDrawState(TextPaint tp) {
|
||||
// set transparent color
|
||||
tp.setColor(0);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user