Create emoji plugin
							
								
								
									
										1
									
								
								markwon-emoji/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1 @@
 | 
				
			|||||||
 | 
					/build
 | 
				
			||||||
							
								
								
									
										50
									
								
								markwon-emoji/build.gradle
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,50 @@
 | 
				
			|||||||
 | 
					plugins {
 | 
				
			||||||
 | 
					    id 'com.android.library'
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					android {
 | 
				
			||||||
 | 
					    compileSdkVersion 31
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    defaultConfig {
 | 
				
			||||||
 | 
					        minSdkVersion 21
 | 
				
			||||||
 | 
					        targetSdkVersion 31
 | 
				
			||||||
 | 
					        versionCode 1
 | 
				
			||||||
 | 
					        versionName "1.0"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
 | 
				
			||||||
 | 
					        consumerProguardFiles "consumer-rules.pro"
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    buildTypes {
 | 
				
			||||||
 | 
					        release {
 | 
				
			||||||
 | 
					            minifyEnabled false
 | 
				
			||||||
 | 
					            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    compileOptions {
 | 
				
			||||||
 | 
					        sourceCompatibility JavaVersion.VERSION_1_8
 | 
				
			||||||
 | 
					        targetCompatibility JavaVersion.VERSION_1_8
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					dependencies {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    api project(':markwon-core')
 | 
				
			||||||
 | 
					    implementation 'com.google.code.gson:gson:2.8.6'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    deps.with {
 | 
				
			||||||
 | 
					        // add a compileOnly dependency, so if this artifact is present
 | 
				
			||||||
 | 
					        // we will try to obtain a SpanFactory for a Strikethrough node and use
 | 
				
			||||||
 | 
					        // it to be consistent with markdown (please note that we do not use markwon plugin
 | 
				
			||||||
 | 
					        // for that in case if different implementation is used)
 | 
				
			||||||
 | 
					        compileOnly it['commonmark-strikethrough']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        testImplementation it['ix-java']
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    deps.test.with {
 | 
				
			||||||
 | 
					        testImplementation it['junit']
 | 
				
			||||||
 | 
					        testImplementation it['robolectric']
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -0,0 +1,26 @@
 | 
				
			|||||||
 | 
					package io.noties.markwon.emoji.ext;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import android.content.Context;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import androidx.test.platform.app.InstrumentationRegistry;
 | 
				
			||||||
 | 
					import androidx.test.ext.junit.runners.AndroidJUnit4;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import org.junit.Test;
 | 
				
			||||||
 | 
					import org.junit.runner.RunWith;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import static org.junit.Assert.*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Instrumented test, which will execute on an Android device.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					@RunWith(AndroidJUnit4.class)
 | 
				
			||||||
 | 
					public class ExampleInstrumentedTest {
 | 
				
			||||||
 | 
					    @Test
 | 
				
			||||||
 | 
					    public void useAppContext() {
 | 
				
			||||||
 | 
					        // Context of the app under test.
 | 
				
			||||||
 | 
					        Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
 | 
				
			||||||
 | 
					        assertEquals("io.noties.markwon.emoji.ext.test", appContext.getPackageName());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										5
									
								
								markwon-emoji/src/main/AndroidManifest.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,5 @@
 | 
				
			|||||||
 | 
					<?xml version="1.0" encoding="utf-8"?>
 | 
				
			||||||
 | 
					<manifest xmlns:android="http://schemas.android.com/apk/res/android"
 | 
				
			||||||
 | 
					    package="io.noties.markwon.emoji.ext">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					</manifest>
 | 
				
			||||||
							
								
								
									
										26819
									
								
								markwon-emoji/src/main/assets/emoji.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,55 @@
 | 
				
			|||||||
 | 
					package io.noties.markwon.emoji.ext;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import android.content.Context;
 | 
				
			||||||
 | 
					import android.graphics.Canvas;
 | 
				
			||||||
 | 
					import android.graphics.Paint;
 | 
				
			||||||
 | 
					import android.graphics.Rect;
 | 
				
			||||||
 | 
					import android.graphics.drawable.Drawable;
 | 
				
			||||||
 | 
					import android.text.style.ImageSpan;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.lang.ref.WeakReference;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public class CenterSpan extends ImageSpan {
 | 
				
			||||||
 | 
					    private WeakReference<Drawable> mDrawableRef;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public CenterSpan(Context context, final int drawableRes) {
 | 
				
			||||||
 | 
					        super(context, drawableRes);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public CenterSpan(Drawable drawable) {
 | 
				
			||||||
 | 
					        super(drawable);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public int getSize(Paint paint, CharSequence text, int start, int end,
 | 
				
			||||||
 | 
					                       Paint.FontMetricsInt fontMetricsInt) {
 | 
				
			||||||
 | 
					        Drawable drawable = getDrawable();
 | 
				
			||||||
 | 
					        Rect rect = drawable.getBounds();
 | 
				
			||||||
 | 
					        if (fontMetricsInt != null) {
 | 
				
			||||||
 | 
					            Paint.FontMetricsInt fmPaint = paint.getFontMetricsInt();
 | 
				
			||||||
 | 
					            int fontHeight = fmPaint.descent - fmPaint.ascent;
 | 
				
			||||||
 | 
					            int drHeight = rect.bottom - rect.top;
 | 
				
			||||||
 | 
					            int centerY = fmPaint.ascent + fontHeight / 2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            fontMetricsInt.ascent = centerY - drHeight / 2;
 | 
				
			||||||
 | 
					            fontMetricsInt.top = fontMetricsInt.ascent;
 | 
				
			||||||
 | 
					            fontMetricsInt.bottom = centerY + drHeight / 2;
 | 
				
			||||||
 | 
					            fontMetricsInt.descent = fontMetricsInt.bottom;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return rect.right;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public void draw(Canvas canvas, CharSequence text, int start, int end,
 | 
				
			||||||
 | 
					                     float x, int top, int y, int bottom, Paint paint) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Drawable drawable = getDrawable();
 | 
				
			||||||
 | 
					        canvas.save();
 | 
				
			||||||
 | 
					        Paint.FontMetricsInt fmPaint = paint.getFontMetricsInt();
 | 
				
			||||||
 | 
					        int fontHeight = fmPaint.descent - fmPaint.ascent;
 | 
				
			||||||
 | 
					        int centerY = y + fmPaint.descent - fontHeight / 2;
 | 
				
			||||||
 | 
					        int transY = centerY - (drawable.getBounds().bottom - drawable.getBounds().top) / 2;
 | 
				
			||||||
 | 
					        canvas.translate(x, transY);
 | 
				
			||||||
 | 
					        drawable.draw(canvas);
 | 
				
			||||||
 | 
					        canvas.restore();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -0,0 +1,62 @@
 | 
				
			|||||||
 | 
					package io.noties.markwon.emoji.ext;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.util.List;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public class EmojiCode {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private String unicode;
 | 
				
			||||||
 | 
					    private String unicode_alternates;
 | 
				
			||||||
 | 
					    private String name;
 | 
				
			||||||
 | 
					    private String shortname;
 | 
				
			||||||
 | 
					    private String category;
 | 
				
			||||||
 | 
					    private String emoji_order;
 | 
				
			||||||
 | 
					    private List<Object> aliases;
 | 
				
			||||||
 | 
					    private List<Object> aliases_ascii;
 | 
				
			||||||
 | 
					    private List<String> keywords;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public enum EMOJI_SIZE{
 | 
				
			||||||
 | 
					        SMALL, MEDIDUM, LARGE;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public String getImageName(){
 | 
				
			||||||
 | 
					        String code = unicode.replace("-", "_");
 | 
				
			||||||
 | 
					        code = "tw_" + code;
 | 
				
			||||||
 | 
					        return code;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public String getUnicode() {
 | 
				
			||||||
 | 
					        return unicode;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public String getUnicode_alternates() {
 | 
				
			||||||
 | 
					        return unicode_alternates;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public String getName() {
 | 
				
			||||||
 | 
					        return name;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public String getShortname() {
 | 
				
			||||||
 | 
					        return shortname;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public String getCategory() {
 | 
				
			||||||
 | 
					        return category;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public String getEmoji_order() {
 | 
				
			||||||
 | 
					        return emoji_order;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public List<Object> getAliases() {
 | 
				
			||||||
 | 
					        return aliases;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public List<Object> getAliases_ascii() {
 | 
				
			||||||
 | 
					        return aliases_ascii;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public List<String> getKeywords() {
 | 
				
			||||||
 | 
					        return keywords;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -0,0 +1,8 @@
 | 
				
			|||||||
 | 
					package io.noties.markwon.emoji.ext;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import org.commonmark.node.CustomNode;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@SuppressWarnings("WeakerAccess")
 | 
				
			||||||
 | 
					public class EmojiGroupNode extends CustomNode {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										37
									
								
								markwon-emoji/src/main/java/io/noties/markwon/emoji/ext/EmojiNode.java
									
									
									
									
									
										Executable file
									
								
							
							
						
						@ -0,0 +1,37 @@
 | 
				
			|||||||
 | 
					package io.noties.markwon.emoji.ext;
 | 
				
			||||||
 | 
					import androidx.annotation.NonNull;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import org.commonmark.node.CustomNode;
 | 
				
			||||||
 | 
					import org.commonmark.node.Delimited;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@SuppressWarnings("WeakerAccess")
 | 
				
			||||||
 | 
					public class EmojiNode extends CustomNode implements Delimited {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public static final char DELIMITER = ':';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public static final String DELIMITER_STRING = "" + DELIMITER;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private final String colonCode;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public EmojiNode(@NonNull String colonCode) {
 | 
				
			||||||
 | 
					        this.colonCode = colonCode;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @NonNull
 | 
				
			||||||
 | 
					    public String getColonCode() {
 | 
				
			||||||
 | 
					        return colonCode;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public String getOpeningDelimiter() {
 | 
				
			||||||
 | 
					        return DELIMITER_STRING;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public String getClosingDelimiter() {
 | 
				
			||||||
 | 
					        return DELIMITER_STRING;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										53
									
								
								markwon-emoji/src/main/java/io/noties/markwon/emoji/ext/EmojiPlugin.java
									
									
									
									
									
										Executable file
									
								
							
							
						
						@ -0,0 +1,53 @@
 | 
				
			|||||||
 | 
					package io.noties.markwon.emoji.ext;
 | 
				
			||||||
 | 
					import android.text.TextUtils;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import androidx.annotation.NonNull;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import org.commonmark.parser.Parser;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import io.noties.markwon.AbstractMarkwonPlugin;
 | 
				
			||||||
 | 
					import io.noties.markwon.MarkwonVisitor;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public class EmojiPlugin extends AbstractMarkwonPlugin {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @NonNull
 | 
				
			||||||
 | 
					    public static EmojiPlugin create(@NonNull EmojiSpanProvider emojiSpanProvider) {
 | 
				
			||||||
 | 
					        return new EmojiPlugin(emojiSpanProvider);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private final EmojiSpanProvider emojiSpanProvider;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    EmojiPlugin(@NonNull EmojiSpanProvider emojiSpanProvider) {
 | 
				
			||||||
 | 
					        this.emojiSpanProvider = emojiSpanProvider;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public void configureParser(@NonNull Parser.Builder builder) {
 | 
				
			||||||
 | 
					        builder.customDelimiterProcessor(EmojiProcessor.create());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public void configureVisitor(@NonNull MarkwonVisitor.Builder builder) {
 | 
				
			||||||
 | 
					        builder.on(EmojiNode.class, new MarkwonVisitor.NodeVisitor<EmojiNode>() {
 | 
				
			||||||
 | 
					            @Override
 | 
				
			||||||
 | 
					            public void visit(@NonNull MarkwonVisitor visitor, @NonNull EmojiNode emojiNode) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                final String colonCode = emojiNode.getColonCode();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if (!TextUtils.isEmpty(colonCode)) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    final int length = visitor.length();
 | 
				
			||||||
 | 
					                    visitor.builder().append(colonCode);
 | 
				
			||||||
 | 
					                    visitor.setSpans(length, emojiSpanProvider.provide(colonCode));
 | 
				
			||||||
 | 
					                    visitor.builder().append(' ');
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @NonNull
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public String processMarkdown(@NonNull String markdown) {
 | 
				
			||||||
 | 
					        return EmojiProcessor.prepare(markdown);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										158
									
								
								markwon-emoji/src/main/java/io/noties/markwon/emoji/ext/EmojiProcessor.java
									
									
									
									
									
										Executable file
									
								
							
							
						
						@ -0,0 +1,158 @@
 | 
				
			|||||||
 | 
					package io.noties.markwon.emoji.ext;
 | 
				
			||||||
 | 
					import android.text.TextUtils;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import androidx.annotation.NonNull;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import org.commonmark.node.Node;
 | 
				
			||||||
 | 
					import org.commonmark.node.Text;
 | 
				
			||||||
 | 
					import org.commonmark.parser.delimiter.DelimiterProcessor;
 | 
				
			||||||
 | 
					import org.commonmark.parser.delimiter.DelimiterRun;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.util.regex.Matcher;
 | 
				
			||||||
 | 
					import java.util.regex.Pattern;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@SuppressWarnings("WeakerAccess")
 | 
				
			||||||
 | 
					public class EmojiProcessor implements DelimiterProcessor {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @NonNull
 | 
				
			||||||
 | 
					    public static EmojiProcessor create() {
 | 
				
			||||||
 | 
					        return new EmojiProcessor();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // ic-home-black-24
 | 
				
			||||||
 | 
					    private static final Pattern PATTERN = Pattern.compile("[a-z]{2,50}|[a-z]{2,50}[_][a-z]{2,50}|[a-z]{2,50}[_][a-z]{2,50}[_][a-z]{2,50}]");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private static final String TO_FIND = EmojiNode.DELIMITER_STRING;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Should be used when input string does not wrap icon definition with `@` from both ends.
 | 
				
			||||||
 | 
					     * So, `@ic-home-white-24` would become `@ic-home-white-24@`. This way parsing is easier
 | 
				
			||||||
 | 
					     * and more predictable (cannot specify multiple ending delimiters, as we would require them:
 | 
				
			||||||
 | 
					     * space, newline, end of a document, and a lot of more)
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param input to process
 | 
				
			||||||
 | 
					     * @return processed string
 | 
				
			||||||
 | 
					     * @see #prepare(StringBuilder)
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    @NonNull
 | 
				
			||||||
 | 
					    public static String prepare(@NonNull String input) {
 | 
				
			||||||
 | 
					        final StringBuilder builder = new StringBuilder(input);
 | 
				
			||||||
 | 
					        prepare(builder);
 | 
				
			||||||
 | 
					        return builder.toString();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public static void prepare(@NonNull StringBuilder builder) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//        int start = builder.indexOf(TO_FIND);
 | 
				
			||||||
 | 
					//        int end;
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//        while (start > -1) {
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//            end = iconDefinitionEnd(start + TO_FIND.length(), builder);
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//            // if we match our pattern, append `@` else ignore
 | 
				
			||||||
 | 
					//            if (iconDefinitionValid(builder.subSequence(start + 1, end))) {
 | 
				
			||||||
 | 
					//                builder.insert(end, '@');
 | 
				
			||||||
 | 
					//            }
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//            // move to next
 | 
				
			||||||
 | 
					//            start = builder.indexOf(TO_FIND, end);
 | 
				
			||||||
 | 
					//        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public char getOpeningCharacter() {
 | 
				
			||||||
 | 
					        return EmojiNode.DELIMITER;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public char getClosingCharacter() {
 | 
				
			||||||
 | 
					        return EmojiNode.DELIMITER;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public int getMinLength() {
 | 
				
			||||||
 | 
					        return 1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public int getDelimiterUse(DelimiterRun opener, DelimiterRun closer) {
 | 
				
			||||||
 | 
					        return opener.length() >= 1 && closer.length() >= 1 ? 1 : 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public void process(Text opener, Text closer, int delimiterUse) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        final EmojiGroupNode emojiGroupNode = new EmojiGroupNode();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        final Node next = opener.getNext();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        boolean handled = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // process only if we have exactly one Text node
 | 
				
			||||||
 | 
					        if (next instanceof Text && next.getNext() == closer) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            final String text = ((Text) next).getLiteral();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (!TextUtils.isEmpty(text)) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                // attempt to match
 | 
				
			||||||
 | 
					                final Matcher matcher = PATTERN.matcher(text);
 | 
				
			||||||
 | 
					                if (matcher.matches()) {
 | 
				
			||||||
 | 
					                    final EmojiNode emojiNode = new EmojiNode(
 | 
				
			||||||
 | 
					                        text
 | 
				
			||||||
 | 
					                    );
 | 
				
			||||||
 | 
					                    emojiGroupNode.appendChild(emojiNode);
 | 
				
			||||||
 | 
					                    next.unlink();
 | 
				
			||||||
 | 
					                    handled = true;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!handled) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // restore delimiters if we didn't match
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            emojiGroupNode.appendChild(new Text(EmojiNode.DELIMITER_STRING));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            Node node;
 | 
				
			||||||
 | 
					            for (Node tmp = opener.getNext(); tmp != null && tmp != closer; tmp = node) {
 | 
				
			||||||
 | 
					                node = tmp.getNext();
 | 
				
			||||||
 | 
					                // append a child anyway
 | 
				
			||||||
 | 
					                emojiGroupNode.appendChild(tmp);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            emojiGroupNode.appendChild(new Text(EmojiNode.DELIMITER_STRING));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        opener.insertBefore(emojiGroupNode);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private static int iconDefinitionEnd(int index, @NonNull StringBuilder builder) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // all spaces, new lines, non-words or digits,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        char c;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        int end = -1;
 | 
				
			||||||
 | 
					        for (int i = index; i < builder.length(); i++) {
 | 
				
			||||||
 | 
					            c = builder.charAt(i);
 | 
				
			||||||
 | 
					            if (Character.isWhitespace(c)
 | 
				
			||||||
 | 
					                    || !(Character.isLetterOrDigit(c) || c == '-' || c == '_')) {
 | 
				
			||||||
 | 
					                end = i;
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (end == -1) {
 | 
				
			||||||
 | 
					            end = builder.length();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return end;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private static boolean iconDefinitionValid(@NonNull CharSequence cs) {
 | 
				
			||||||
 | 
					        final Matcher matcher = PATTERN.matcher(cs);
 | 
				
			||||||
 | 
					        return matcher.matches();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -0,0 +1,91 @@
 | 
				
			|||||||
 | 
					package io.noties.markwon.emoji.ext;
 | 
				
			||||||
 | 
					import android.content.Context;
 | 
				
			||||||
 | 
					import android.graphics.drawable.Drawable;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import androidx.annotation.NonNull;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import com.google.gson.Gson;
 | 
				
			||||||
 | 
					import com.google.gson.reflect.TypeToken;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.io.IOException;
 | 
				
			||||||
 | 
					import java.io.InputStream;
 | 
				
			||||||
 | 
					import java.lang.reflect.Type;
 | 
				
			||||||
 | 
					import java.util.Map;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@SuppressWarnings("WeakerAccess")
 | 
				
			||||||
 | 
					public abstract class EmojiSpanProvider {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @SuppressWarnings("SameParameterValue")
 | 
				
			||||||
 | 
					    @NonNull
 | 
				
			||||||
 | 
					    public static EmojiSpanProvider create(@NonNull Context context, float textSize) {
 | 
				
			||||||
 | 
					        return new Impl(context, textSize);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @NonNull
 | 
				
			||||||
 | 
					    public abstract Object provide(@NonNull String text);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private static class Impl extends EmojiSpanProvider {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private final Context context;
 | 
				
			||||||
 | 
					        private float textSize;
 | 
				
			||||||
 | 
					        private Map<String, EmojiCode> emojiMap;
 | 
				
			||||||
 | 
					        Impl(@NonNull Context context, float textSize) {
 | 
				
			||||||
 | 
					            this.context = context;
 | 
				
			||||||
 | 
					            this.textSize = textSize;
 | 
				
			||||||
 | 
					            this.emojiMap = loadEmojiMapFromAssets();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private Map<String, EmojiCode> loadEmojiMapFromAssets(){
 | 
				
			||||||
 | 
					        try{
 | 
				
			||||||
 | 
					            InputStream is = this.context.getAssets().open("emoji.json");
 | 
				
			||||||
 | 
					            int size = is.available();
 | 
				
			||||||
 | 
					            byte[] buffer = new byte[size];
 | 
				
			||||||
 | 
					            is.read(buffer);
 | 
				
			||||||
 | 
					            is.close();
 | 
				
			||||||
 | 
					            String jsonString = new String(buffer, "UTF-8");
 | 
				
			||||||
 | 
					            Gson gson = new Gson();
 | 
				
			||||||
 | 
					            Type mapType = new TypeToken<Map<String, EmojiCode>>(){}.getType();
 | 
				
			||||||
 | 
					            Map<String, EmojiCode> map = gson.fromJson(jsonString, mapType);
 | 
				
			||||||
 | 
					            return map;
 | 
				
			||||||
 | 
					        }catch (IOException e){
 | 
				
			||||||
 | 
					            e.printStackTrace();
 | 
				
			||||||
 | 
					            return  null;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        @NonNull
 | 
				
			||||||
 | 
					        @Override
 | 
				
			||||||
 | 
					        public Object provide(@NonNull String colonCode) {
 | 
				
			||||||
 | 
					            return new CenterSpan(getDrawable(colonCode));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        @NonNull
 | 
				
			||||||
 | 
					        private Drawable getDrawable(String colonCode) {
 | 
				
			||||||
 | 
					            EmojiCode emojiCode = emojiMap.get(colonCode);
 | 
				
			||||||
 | 
					            int drawbleId = -1;
 | 
				
			||||||
 | 
					            if (emojiCode != null){
 | 
				
			||||||
 | 
					                String imageName = emojiCode.getImageName();
 | 
				
			||||||
 | 
					                try{
 | 
				
			||||||
 | 
					                    drawbleId = context.getResources().getIdentifier(imageName, "drawable", context.getPackageName());
 | 
				
			||||||
 | 
					                }catch (Exception e){
 | 
				
			||||||
 | 
					                    e.printStackTrace();
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            Drawable emojiDrawable;
 | 
				
			||||||
 | 
					            if (drawbleId != -1) {
 | 
				
			||||||
 | 
					                emojiDrawable = context.getResources().getDrawable(drawbleId);
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                emojiDrawable = context.getResources().getDrawable(R.drawable.tw_1f30d);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            int emojiHeight = emojiDrawable.getIntrinsicHeight();
 | 
				
			||||||
 | 
					            int emojiWidth = emojiDrawable.getIntrinsicWidth();
 | 
				
			||||||
 | 
					            int requiredWidth = emojiWidth * (int)textSize / emojiHeight;
 | 
				
			||||||
 | 
					            emojiDrawable.setBounds(0, 0, requiredWidth, (int) textSize);
 | 
				
			||||||
 | 
					            return emojiDrawable;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										
											BIN
										
									
								
								markwon-emoji/src/main/res/drawable/tw_1f004.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 551 B  | 
							
								
								
									
										
											BIN
										
									
								
								markwon-emoji/src/main/res/drawable/tw_1f0cf.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 923 B  | 
							
								
								
									
										
											BIN
										
									
								
								markwon-emoji/src/main/res/drawable/tw_1f170.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 557 B  | 
							
								
								
									
										
											BIN
										
									
								
								markwon-emoji/src/main/res/drawable/tw_1f171.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 458 B  | 
							
								
								
									
										
											BIN
										
									
								
								markwon-emoji/src/main/res/drawable/tw_1f17e.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 562 B  | 
							
								
								
									
										
											BIN
										
									
								
								markwon-emoji/src/main/res/drawable/tw_1f17f.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 403 B  | 
							
								
								
									
										
											BIN
										
									
								
								markwon-emoji/src/main/res/drawable/tw_1f18e.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 682 B  | 
							
								
								
									
										
											BIN
										
									
								
								markwon-emoji/src/main/res/drawable/tw_1f191.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 561 B  | 
							
								
								
									
										
											BIN
										
									
								
								markwon-emoji/src/main/res/drawable/tw_1f192.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 603 B  | 
							
								
								
									
										
											BIN
										
									
								
								markwon-emoji/src/main/res/drawable/tw_1f193.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 517 B  | 
							
								
								
									
										
											BIN
										
									
								
								markwon-emoji/src/main/res/drawable/tw_1f194.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 495 B  | 
							
								
								
									
										
											BIN
										
									
								
								markwon-emoji/src/main/res/drawable/tw_1f195.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 668 B  | 
							
								
								
									
										
											BIN
										
									
								
								markwon-emoji/src/main/res/drawable/tw_1f196.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 670 B  | 
							
								
								
									
										
											BIN
										
									
								
								markwon-emoji/src/main/res/drawable/tw_1f197.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 640 B  | 
							
								
								
									
										
											BIN
										
									
								
								markwon-emoji/src/main/res/drawable/tw_1f198.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 722 B  | 
							
								
								
									
										
											BIN
										
									
								
								markwon-emoji/src/main/res/drawable/tw_1f199.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 553 B  | 
							
								
								
									
										
											BIN
										
									
								
								markwon-emoji/src/main/res/drawable/tw_1f19a.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 747 B  | 
							
								
								
									
										
											BIN
										
									
								
								markwon-emoji/src/main/res/drawable/tw_1f1e6.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 559 B  | 
							
								
								
									
										
											BIN
										
									
								
								markwon-emoji/src/main/res/drawable/tw_1f1e6_1f1e8.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 1.0 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								markwon-emoji/src/main/res/drawable/tw_1f1e6_1f1e9.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 697 B  | 
							
								
								
									
										
											BIN
										
									
								
								markwon-emoji/src/main/res/drawable/tw_1f1e6_1f1ea.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 287 B  | 
							
								
								
									
										
											BIN
										
									
								
								markwon-emoji/src/main/res/drawable/tw_1f1e6_1f1eb.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 1.1 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								markwon-emoji/src/main/res/drawable/tw_1f1e6_1f1ec.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 849 B  | 
							
								
								
									
										
											BIN
										
									
								
								markwon-emoji/src/main/res/drawable/tw_1f1e6_1f1ee.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 989 B  | 
							
								
								
									
										
											BIN
										
									
								
								markwon-emoji/src/main/res/drawable/tw_1f1e6_1f1f1.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 662 B  | 
							
								
								
									
										
											BIN
										
									
								
								markwon-emoji/src/main/res/drawable/tw_1f1e6_1f1f2.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 245 B  | 
							
								
								
									
										
											BIN
										
									
								
								markwon-emoji/src/main/res/drawable/tw_1f1e6_1f1f4.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 723 B  | 
							
								
								
									
										
											BIN
										
									
								
								markwon-emoji/src/main/res/drawable/tw_1f1e6_1f1f6.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 481 B  | 
							
								
								
									
										
											BIN
										
									
								
								markwon-emoji/src/main/res/drawable/tw_1f1e6_1f1f7.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 453 B  | 
							
								
								
									
										
											BIN
										
									
								
								markwon-emoji/src/main/res/drawable/tw_1f1e6_1f1f8.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 847 B  | 
							
								
								
									
										
											BIN
										
									
								
								markwon-emoji/src/main/res/drawable/tw_1f1e6_1f1f9.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 205 B  | 
							
								
								
									
										
											BIN
										
									
								
								markwon-emoji/src/main/res/drawable/tw_1f1e6_1f1fa.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 835 B  | 
							
								
								
									
										
											BIN
										
									
								
								markwon-emoji/src/main/res/drawable/tw_1f1e6_1f1fc.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 387 B  | 
							
								
								
									
										
											BIN
										
									
								
								markwon-emoji/src/main/res/drawable/tw_1f1e6_1f1fd.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 230 B  | 
							
								
								
									
										
											BIN
										
									
								
								markwon-emoji/src/main/res/drawable/tw_1f1e6_1f1ff.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 402 B  | 
							
								
								
									
										
											BIN
										
									
								
								markwon-emoji/src/main/res/drawable/tw_1f1e7.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 459 B  | 
							
								
								
									
										
											BIN
										
									
								
								markwon-emoji/src/main/res/drawable/tw_1f1e7_1f1e6.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 652 B  | 
							
								
								
									
										
											BIN
										
									
								
								markwon-emoji/src/main/res/drawable/tw_1f1e7_1f1e7.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 406 B  | 
							
								
								
									
										
											BIN
										
									
								
								markwon-emoji/src/main/res/drawable/tw_1f1e7_1f1e9.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 336 B  | 
							
								
								
									
										
											BIN
										
									
								
								markwon-emoji/src/main/res/drawable/tw_1f1e7_1f1ea.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 233 B  | 
							
								
								
									
										
											BIN
										
									
								
								markwon-emoji/src/main/res/drawable/tw_1f1e7_1f1eb.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 390 B  | 
							
								
								
									
										
											BIN
										
									
								
								markwon-emoji/src/main/res/drawable/tw_1f1e7_1f1ec.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 244 B  | 
							
								
								
									
										
											BIN
										
									
								
								markwon-emoji/src/main/res/drawable/tw_1f1e7_1f1ed.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 411 B  | 
							
								
								
									
										
											BIN
										
									
								
								markwon-emoji/src/main/res/drawable/tw_1f1e7_1f1ee.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 940 B  | 
							
								
								
									
										
											BIN
										
									
								
								markwon-emoji/src/main/res/drawable/tw_1f1e7_1f1ef.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 279 B  | 
							
								
								
									
										
											BIN
										
									
								
								markwon-emoji/src/main/res/drawable/tw_1f1e7_1f1f1.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 978 B  | 
							
								
								
									
										
											BIN
										
									
								
								markwon-emoji/src/main/res/drawable/tw_1f1e7_1f1f2.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 919 B  | 
							
								
								
									
										
											BIN
										
									
								
								markwon-emoji/src/main/res/drawable/tw_1f1e7_1f1f3.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 884 B  | 
							
								
								
									
										
											BIN
										
									
								
								markwon-emoji/src/main/res/drawable/tw_1f1e7_1f1f4.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 666 B  | 
							
								
								
									
										
											BIN
										
									
								
								markwon-emoji/src/main/res/drawable/tw_1f1e7_1f1f6.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 871 B  | 
							
								
								
									
										
											BIN
										
									
								
								markwon-emoji/src/main/res/drawable/tw_1f1e7_1f1f7.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 805 B  | 
							
								
								
									
										
											BIN
										
									
								
								markwon-emoji/src/main/res/drawable/tw_1f1e7_1f1f8.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 419 B  | 
							
								
								
									
										
											BIN
										
									
								
								markwon-emoji/src/main/res/drawable/tw_1f1e7_1f1f9.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 1000 B  | 
							
								
								
									
										
											BIN
										
									
								
								markwon-emoji/src/main/res/drawable/tw_1f1e7_1f1fb.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 270 B  | 
							
								
								
									
										
											BIN
										
									
								
								markwon-emoji/src/main/res/drawable/tw_1f1e7_1f1fc.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 214 B  | 
							
								
								
									
										
											BIN
										
									
								
								markwon-emoji/src/main/res/drawable/tw_1f1e7_1f1fe.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 669 B  | 
							
								
								
									
										
											BIN
										
									
								
								markwon-emoji/src/main/res/drawable/tw_1f1e7_1f1ff.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 1.1 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								markwon-emoji/src/main/res/drawable/tw_1f1e8.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 503 B  | 
							
								
								
									
										
											BIN
										
									
								
								markwon-emoji/src/main/res/drawable/tw_1f1e8_1f1e6.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 445 B  | 
							
								
								
									
										
											BIN
										
									
								
								markwon-emoji/src/main/res/drawable/tw_1f1e8_1f1e8.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 706 B  | 
							
								
								
									
										
											BIN
										
									
								
								markwon-emoji/src/main/res/drawable/tw_1f1e8_1f1e9.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 602 B  | 
							
								
								
									
										
											BIN
										
									
								
								markwon-emoji/src/main/res/drawable/tw_1f1e8_1f1eb.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 389 B  | 
							
								
								
									
										
											BIN
										
									
								
								markwon-emoji/src/main/res/drawable/tw_1f1e8_1f1ec.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 356 B  | 
							
								
								
									
										
											BIN
										
									
								
								markwon-emoji/src/main/res/drawable/tw_1f1e8_1f1ed.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 220 B  | 
							
								
								
									
										
											BIN
										
									
								
								markwon-emoji/src/main/res/drawable/tw_1f1e8_1f1ee.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 233 B  | 
							
								
								
									
										
											BIN
										
									
								
								markwon-emoji/src/main/res/drawable/tw_1f1e8_1f1f0.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 961 B  | 
							
								
								
									
										
											BIN
										
									
								
								markwon-emoji/src/main/res/drawable/tw_1f1e8_1f1f1.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 394 B  | 
							
								
								
									
										
											BIN
										
									
								
								markwon-emoji/src/main/res/drawable/tw_1f1e8_1f1f2.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 341 B  | 
							
								
								
									
										
											BIN
										
									
								
								markwon-emoji/src/main/res/drawable/tw_1f1e8_1f1f3.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 410 B  | 
							
								
								
									
										
											BIN
										
									
								
								markwon-emoji/src/main/res/drawable/tw_1f1e8_1f1f4.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 245 B  | 
							
								
								
									
										
											BIN
										
									
								
								markwon-emoji/src/main/res/drawable/tw_1f1e8_1f1f5.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 233 B  | 
							
								
								
									
										
											BIN
										
									
								
								markwon-emoji/src/main/res/drawable/tw_1f1e8_1f1f7.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 453 B  | 
							
								
								
									
										
											BIN
										
									
								
								markwon-emoji/src/main/res/drawable/tw_1f1e8_1f1fa.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 569 B  | 
							
								
								
									
										
											BIN
										
									
								
								markwon-emoji/src/main/res/drawable/tw_1f1e8_1f1fb.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 574 B  | 
							
								
								
									
										
											BIN
										
									
								
								markwon-emoji/src/main/res/drawable/tw_1f1e8_1f1fc.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 357 B  | 
							
								
								
									
										
											BIN
										
									
								
								markwon-emoji/src/main/res/drawable/tw_1f1e8_1f1fd.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 913 B  | 
							
								
								
									
										
											BIN
										
									
								
								markwon-emoji/src/main/res/drawable/tw_1f1e8_1f1fe.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 539 B  | 
							
								
								
									
										
											BIN
										
									
								
								markwon-emoji/src/main/res/drawable/tw_1f1e8_1f1ff.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 549 B  | 
							
								
								
									
										
											BIN
										
									
								
								markwon-emoji/src/main/res/drawable/tw_1f1e9.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 454 B  | 
							
								
								
									
										
											BIN
										
									
								
								markwon-emoji/src/main/res/drawable/tw_1f1e9_1f1ea.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 246 B  | 
							
								
								
									
										
											BIN
										
									
								
								markwon-emoji/src/main/res/drawable/tw_1f1e9_1f1ec.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 1.4 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								markwon-emoji/src/main/res/drawable/tw_1f1e9_1f1ef.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 643 B  | 
							
								
								
									
										
											BIN
										
									
								
								markwon-emoji/src/main/res/drawable/tw_1f1e9_1f1f0.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 251 B  | 
							
								
								
									
										
											BIN
										
									
								
								markwon-emoji/src/main/res/drawable/tw_1f1e9_1f1f2.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 696 B  | 
							
								
								
									
										
											BIN
										
									
								
								markwon-emoji/src/main/res/drawable/tw_1f1e9_1f1f4.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 584 B  | 
							
								
								
									
										
											BIN
										
									
								
								markwon-emoji/src/main/res/drawable/tw_1f1e9_1f1ff.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 524 B  | 
							
								
								
									
										
											BIN
										
									
								
								markwon-emoji/src/main/res/drawable/tw_1f1ea.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 368 B  | 
							
								
								
									
										
											BIN
										
									
								
								markwon-emoji/src/main/res/drawable/tw_1f1ea_1f1e6.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 362 B  |