From bc6f5467b9b3dc17eb3e3f3a6e33d1fbca0a696f Mon Sep 17 00:00:00 2001 From: Dimitry Ivanov Date: Fri, 16 Feb 2018 17:16:50 +0300 Subject: [PATCH] Shaping up the custom extension module --- sample-custom-extension/build.gradle | 7 +- .../src/main/AndroidManifest.xml | 4 +- .../IconProcessor.java | 86 ---------- .../IconSpanProvider.java | 9 - .../IconSpanProviderImpl.java | 51 ------ .../IconUtils.java | 46 ----- .../MainActivity.java | 44 ----- .../sample/extension}/IconGroupNode.java | 3 +- .../markwon/sample/extension}/IconNode.java | 4 +- .../sample/extension/IconProcessor.java | 160 ++++++++++++++++++ .../markwon/sample/extension}/IconSpan.java | 5 +- .../sample/extension/IconSpanProvider.java | 67 ++++++++ .../sample/extension}/IconVisitor.java | 3 +- .../sample/extension/MainActivity.java | 66 ++++++++ .../ic_3d_rotation_white_24dp.png | Bin 631 -> 0 bytes .../ic_account_balance_white_26dp.png | Bin 336 -> 0 bytes .../res/drawable-hdpi/ic_home_black_24dp.png | Bin 231 -> 0 bytes .../ic_3d_rotation_white_24dp.png | Bin 399 -> 0 bytes .../ic_account_balance_white_26dp.png | Bin 216 -> 0 bytes .../res/drawable-mdpi/ic_home_black_24dp.png | Bin 184 -> 0 bytes .../ic_3d_rotation_white_24dp.png | Bin 835 -> 0 bytes .../ic_account_balance_white_26dp.png | Bin 297 -> 0 bytes .../res/drawable-xhdpi/ic_home_black_24dp.png | Bin 261 -> 0 bytes .../ic_3d_rotation_white_24dp.png | Bin 1258 -> 0 bytes .../ic_account_balance_white_26dp.png | Bin 432 -> 0 bytes .../drawable-xxhdpi/ic_home_black_24dp.png | Bin 327 -> 0 bytes .../ic_3d_rotation_white_24dp.png | Bin 1677 -> 0 bytes .../ic_account_balance_white_26dp.png | Bin 488 -> 0 bytes .../drawable-xxxhdpi/ic_home_black_24dp.png | Bin 401 -> 0 bytes .../res/drawable/ic_android_black_24dp.xml | 9 + .../main/res/drawable/ic_home_black_36dp.xml | 4 + .../res/drawable/ic_memory_black_48dp.xml | 4 + .../ic_sentiment_satisfied_red_64dp.xml | 6 + .../src/main/res/layout/activity_main.xml | 16 ++ .../src/main/res/values/colors.xml | 6 - .../src/main/res/values/strings.xml | 10 ++ .../src/main/res/values/styles.xml | 5 +- 37 files changed, 359 insertions(+), 256 deletions(-) delete mode 100644 sample-custom-extension/src/main/java/noties/ru/markwon_samplecustomextension/IconProcessor.java delete mode 100644 sample-custom-extension/src/main/java/noties/ru/markwon_samplecustomextension/IconSpanProvider.java delete mode 100644 sample-custom-extension/src/main/java/noties/ru/markwon_samplecustomextension/IconSpanProviderImpl.java delete mode 100644 sample-custom-extension/src/main/java/noties/ru/markwon_samplecustomextension/IconUtils.java delete mode 100644 sample-custom-extension/src/main/java/noties/ru/markwon_samplecustomextension/MainActivity.java rename sample-custom-extension/src/main/java/{noties/ru/markwon_samplecustomextension => ru/noties/markwon/sample/extension}/IconGroupNode.java (54%) rename sample-custom-extension/src/main/java/{noties/ru/markwon_samplecustomextension => ru/noties/markwon/sample/extension}/IconNode.java (93%) create mode 100644 sample-custom-extension/src/main/java/ru/noties/markwon/sample/extension/IconProcessor.java rename sample-custom-extension/src/main/java/{noties/ru/markwon_samplecustomextension => ru/noties/markwon/sample/extension}/IconSpan.java (95%) create mode 100644 sample-custom-extension/src/main/java/ru/noties/markwon/sample/extension/IconSpanProvider.java rename sample-custom-extension/src/main/java/{noties/ru/markwon_samplecustomextension => ru/noties/markwon/sample/extension}/IconVisitor.java (95%) create mode 100644 sample-custom-extension/src/main/java/ru/noties/markwon/sample/extension/MainActivity.java delete mode 100644 sample-custom-extension/src/main/res/drawable-hdpi/ic_3d_rotation_white_24dp.png delete mode 100644 sample-custom-extension/src/main/res/drawable-hdpi/ic_account_balance_white_26dp.png delete mode 100644 sample-custom-extension/src/main/res/drawable-hdpi/ic_home_black_24dp.png delete mode 100644 sample-custom-extension/src/main/res/drawable-mdpi/ic_3d_rotation_white_24dp.png delete mode 100644 sample-custom-extension/src/main/res/drawable-mdpi/ic_account_balance_white_26dp.png delete mode 100644 sample-custom-extension/src/main/res/drawable-mdpi/ic_home_black_24dp.png delete mode 100644 sample-custom-extension/src/main/res/drawable-xhdpi/ic_3d_rotation_white_24dp.png delete mode 100644 sample-custom-extension/src/main/res/drawable-xhdpi/ic_account_balance_white_26dp.png delete mode 100644 sample-custom-extension/src/main/res/drawable-xhdpi/ic_home_black_24dp.png delete mode 100644 sample-custom-extension/src/main/res/drawable-xxhdpi/ic_3d_rotation_white_24dp.png delete mode 100644 sample-custom-extension/src/main/res/drawable-xxhdpi/ic_account_balance_white_26dp.png delete mode 100644 sample-custom-extension/src/main/res/drawable-xxhdpi/ic_home_black_24dp.png delete mode 100644 sample-custom-extension/src/main/res/drawable-xxxhdpi/ic_3d_rotation_white_24dp.png delete mode 100644 sample-custom-extension/src/main/res/drawable-xxxhdpi/ic_account_balance_white_26dp.png delete mode 100644 sample-custom-extension/src/main/res/drawable-xxxhdpi/ic_home_black_24dp.png create mode 100644 sample-custom-extension/src/main/res/drawable/ic_android_black_24dp.xml create mode 100644 sample-custom-extension/src/main/res/drawable/ic_home_black_36dp.xml create mode 100644 sample-custom-extension/src/main/res/drawable/ic_memory_black_48dp.xml create mode 100644 sample-custom-extension/src/main/res/drawable/ic_sentiment_satisfied_red_64dp.xml create mode 100644 sample-custom-extension/src/main/res/layout/activity_main.xml delete mode 100644 sample-custom-extension/src/main/res/values/colors.xml diff --git a/sample-custom-extension/build.gradle b/sample-custom-extension/build.gradle index dc6139d7..baa37484 100644 --- a/sample-custom-extension/build.gradle +++ b/sample-custom-extension/build.gradle @@ -6,8 +6,11 @@ android { buildToolsVersion BUILD_TOOLS defaultConfig { - applicationId "noties.ru.markwon_samplecustomextension" - minSdkVersion MIN_SDK + + applicationId "ru.noties.markwon.sample.extension" + + // using 21 as minimum only to be able to vector assets + minSdkVersion 21 targetSdkVersion TARGET_SDK versionCode 1 versionName version diff --git a/sample-custom-extension/src/main/AndroidManifest.xml b/sample-custom-extension/src/main/AndroidManifest.xml index dadcdf93..1553a0a6 100644 --- a/sample-custom-extension/src/main/AndroidManifest.xml +++ b/sample-custom-extension/src/main/AndroidManifest.xml @@ -1,6 +1,6 @@ + package="ru.noties.markwon.sample.extension"> + - diff --git a/sample-custom-extension/src/main/java/noties/ru/markwon_samplecustomextension/IconProcessor.java b/sample-custom-extension/src/main/java/noties/ru/markwon_samplecustomextension/IconProcessor.java deleted file mode 100644 index 7ad68527..00000000 --- a/sample-custom-extension/src/main/java/noties/ru/markwon_samplecustomextension/IconProcessor.java +++ /dev/null @@ -1,86 +0,0 @@ -package noties.ru.markwon_samplecustomextension; - -import android.text.TextUtils; - -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; - -public class IconProcessor implements DelimiterProcessor { - - private static final Pattern PATTERN = Pattern.compile("material-icon-(\\w+)-(\\w+)-(\\w+)"); - - @Override - public char getOpeningCharacter() { - return IconNode.DELIMITER; - } - - @Override - public char getClosingCharacter() { - return IconNode.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 IconGroupNode iconGroupNode = new IconGroupNode(); - - 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 IconNode iconNode = new IconNode( - matcher.group(1), - matcher.group(2), - matcher.group(3) - ); - iconGroupNode.appendChild(iconNode); - next.unlink(); - handled = true; - } - } - } - - if (!handled) { - - // restore delimiters if we didn't match - - iconGroupNode.appendChild(new Text(IconNode.DELIMITER_STRING)); - - Node node; - for (Node tmp = opener.getNext(); tmp != null && tmp != closer; tmp = node) { - node = tmp.getNext(); - // append a child anyway - iconGroupNode.appendChild(tmp); - } - - iconGroupNode.appendChild(new Text(IconNode.DELIMITER_STRING)); - } - - opener.insertBefore(iconGroupNode); - } -} diff --git a/sample-custom-extension/src/main/java/noties/ru/markwon_samplecustomextension/IconSpanProvider.java b/sample-custom-extension/src/main/java/noties/ru/markwon_samplecustomextension/IconSpanProvider.java deleted file mode 100644 index 9f8d517e..00000000 --- a/sample-custom-extension/src/main/java/noties/ru/markwon_samplecustomextension/IconSpanProvider.java +++ /dev/null @@ -1,9 +0,0 @@ -package noties.ru.markwon_samplecustomextension; - -import android.support.annotation.NonNull; - -public interface IconSpanProvider { - - @NonNull - IconSpan provide(@NonNull String name, @NonNull String color, @NonNull String size); -} diff --git a/sample-custom-extension/src/main/java/noties/ru/markwon_samplecustomextension/IconSpanProviderImpl.java b/sample-custom-extension/src/main/java/noties/ru/markwon_samplecustomextension/IconSpanProviderImpl.java deleted file mode 100644 index 8f674a78..00000000 --- a/sample-custom-extension/src/main/java/noties/ru/markwon_samplecustomextension/IconSpanProviderImpl.java +++ /dev/null @@ -1,51 +0,0 @@ -package noties.ru.markwon_samplecustomextension; - -import android.content.Context; -import android.content.res.Resources; -import android.graphics.drawable.Drawable; -import android.os.Build; -import android.support.annotation.DrawableRes; -import android.support.annotation.NonNull; - -public class IconSpanProviderImpl implements IconSpanProvider { - - private static final boolean IS_L = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP; - - private final Context context; - private final Resources resources; - private final int fallBack; - - public IconSpanProviderImpl(@NonNull Context context, @DrawableRes int fallBack) { - this.context = context; - this.resources = context.getResources(); - this.fallBack = fallBack; - } - - @NonNull - @Override - public IconSpan provide(@NonNull String name, @NonNull String color, @NonNull String size) { - final String resName = materialIconName(name, color, size); - int resId = resources.getIdentifier(resName, "drawable", context.getPackageName()); - if (resId == 0) { - resId = fallBack; - } - return new IconSpan(getDrawable(resId), IconSpan.ALIGN_CENTER); - } - - @NonNull - private static String materialIconName(@NonNull String name, @NonNull String color, @NonNull String size) { - return "ic_" + name + "_" + color + "_" + size + "dp"; - } - - @NonNull - private Drawable getDrawable(int resId) { - final Drawable drawable; - if (IS_L) { - drawable = context.getDrawable(resId); - } else { - drawable = resources.getDrawable(resId); - } - //noinspection ConstantConditions - return drawable; - } -} diff --git a/sample-custom-extension/src/main/java/noties/ru/markwon_samplecustomextension/IconUtils.java b/sample-custom-extension/src/main/java/noties/ru/markwon_samplecustomextension/IconUtils.java deleted file mode 100644 index 03cef1c1..00000000 --- a/sample-custom-extension/src/main/java/noties/ru/markwon_samplecustomextension/IconUtils.java +++ /dev/null @@ -1,46 +0,0 @@ -package noties.ru.markwon_samplecustomextension; - -import android.support.annotation.NonNull; - -public abstract class IconUtils { - - private static final String TO_FIND = "@material-icon-"; - - 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); - builder.insert(end, '@'); - start = builder.indexOf(TO_FIND, end); - } - } - - 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 IconUtils() { - } -} diff --git a/sample-custom-extension/src/main/java/noties/ru/markwon_samplecustomextension/MainActivity.java b/sample-custom-extension/src/main/java/noties/ru/markwon_samplecustomextension/MainActivity.java deleted file mode 100644 index 07bca60e..00000000 --- a/sample-custom-extension/src/main/java/noties/ru/markwon_samplecustomextension/MainActivity.java +++ /dev/null @@ -1,44 +0,0 @@ -package noties.ru.markwon_samplecustomextension; - -import android.app.Activity; -import android.os.Bundle; -import android.widget.TextView; - -import org.commonmark.ext.gfm.strikethrough.StrikethroughExtension; -import org.commonmark.ext.gfm.tables.TablesExtension; -import org.commonmark.node.Node; -import org.commonmark.parser.Parser; - -import java.util.Arrays; - -import ru.noties.markwon.SpannableBuilder; -import ru.noties.markwon.SpannableConfiguration; -import ru.noties.markwon.tasklist.TaskListExtension; - -public class MainActivity extends Activity { - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(0); - - final TextView textView = findViewById(0); - - final Parser parser = new Parser.Builder() - // we will register all known to Markwon extensions - .extensions(Arrays.asList( - StrikethroughExtension.create(), - TablesExtension.create(), - TaskListExtension.create() - )) - // this is the handler for custom icons - .customDelimiterProcessor(new IconProcessor()) - .build(); - - final Node node = parser.parse("# Hello icons! @material-icon-home-black-24@\n\n Your account @material-icon-account_balance-white-26@ is 0.00003"); - final SpannableBuilder builder = new SpannableBuilder(); - final IconVisitor visitor = new IconVisitor(SpannableConfiguration.create(this), builder, new IconSpanProviderImpl(this, R.drawable.ic_home_black_24dp)); - node.accept(visitor); - textView.setText(builder.text()); - } -} diff --git a/sample-custom-extension/src/main/java/noties/ru/markwon_samplecustomextension/IconGroupNode.java b/sample-custom-extension/src/main/java/ru/noties/markwon/sample/extension/IconGroupNode.java similarity index 54% rename from sample-custom-extension/src/main/java/noties/ru/markwon_samplecustomextension/IconGroupNode.java rename to sample-custom-extension/src/main/java/ru/noties/markwon/sample/extension/IconGroupNode.java index 9438569c..193b33b8 100644 --- a/sample-custom-extension/src/main/java/noties/ru/markwon_samplecustomextension/IconGroupNode.java +++ b/sample-custom-extension/src/main/java/ru/noties/markwon/sample/extension/IconGroupNode.java @@ -1,7 +1,8 @@ -package noties.ru.markwon_samplecustomextension; +package ru.noties.markwon.sample.extension; import org.commonmark.node.CustomNode; +@SuppressWarnings("WeakerAccess") public class IconGroupNode extends CustomNode { } diff --git a/sample-custom-extension/src/main/java/noties/ru/markwon_samplecustomextension/IconNode.java b/sample-custom-extension/src/main/java/ru/noties/markwon/sample/extension/IconNode.java similarity index 93% rename from sample-custom-extension/src/main/java/noties/ru/markwon_samplecustomextension/IconNode.java rename to sample-custom-extension/src/main/java/ru/noties/markwon/sample/extension/IconNode.java index f7190883..3d40ec2f 100644 --- a/sample-custom-extension/src/main/java/noties/ru/markwon_samplecustomextension/IconNode.java +++ b/sample-custom-extension/src/main/java/ru/noties/markwon/sample/extension/IconNode.java @@ -1,13 +1,13 @@ -package noties.ru.markwon_samplecustomextension; +package ru.noties.markwon.sample.extension; import android.support.annotation.NonNull; import org.commonmark.node.CustomNode; import org.commonmark.node.Delimited; +@SuppressWarnings("WeakerAccess") public class IconNode extends CustomNode implements Delimited { - public static final char DELIMITER = '@'; public static final String DELIMITER_STRING = "" + DELIMITER; diff --git a/sample-custom-extension/src/main/java/ru/noties/markwon/sample/extension/IconProcessor.java b/sample-custom-extension/src/main/java/ru/noties/markwon/sample/extension/IconProcessor.java new file mode 100644 index 00000000..500726e0 --- /dev/null +++ b/sample-custom-extension/src/main/java/ru/noties/markwon/sample/extension/IconProcessor.java @@ -0,0 +1,160 @@ +package ru.noties.markwon.sample.extension; + +import android.support.annotation.NonNull; +import android.text.TextUtils; + +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 IconProcessor implements DelimiterProcessor { + + @NonNull + public static IconProcessor create() { + return new IconProcessor(); + } + + // ic-home-black-24 + private static final Pattern PATTERN = Pattern.compile("ic-(\\w+)-(\\w+)-(\\d+)"); + + private static final String TO_FIND = IconNode.DELIMITER_STRING + "ic-"; + + /** + * 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 IconNode.DELIMITER; + } + + @Override + public char getClosingCharacter() { + return IconNode.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 IconGroupNode iconGroupNode = new IconGroupNode(); + + 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 IconNode iconNode = new IconNode( + matcher.group(1), + matcher.group(2), + matcher.group(3) + ); + iconGroupNode.appendChild(iconNode); + next.unlink(); + handled = true; + } + } + } + + if (!handled) { + + // restore delimiters if we didn't match + + iconGroupNode.appendChild(new Text(IconNode.DELIMITER_STRING)); + + Node node; + for (Node tmp = opener.getNext(); tmp != null && tmp != closer; tmp = node) { + node = tmp.getNext(); + // append a child anyway + iconGroupNode.appendChild(tmp); + } + + iconGroupNode.appendChild(new Text(IconNode.DELIMITER_STRING)); + } + + opener.insertBefore(iconGroupNode); + } + + 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(); + } +} diff --git a/sample-custom-extension/src/main/java/noties/ru/markwon_samplecustomextension/IconSpan.java b/sample-custom-extension/src/main/java/ru/noties/markwon/sample/extension/IconSpan.java similarity index 95% rename from sample-custom-extension/src/main/java/noties/ru/markwon_samplecustomextension/IconSpan.java rename to sample-custom-extension/src/main/java/ru/noties/markwon/sample/extension/IconSpan.java index bc197492..690ba5b2 100644 --- a/sample-custom-extension/src/main/java/noties/ru/markwon_samplecustomextension/IconSpan.java +++ b/sample-custom-extension/src/main/java/ru/noties/markwon/sample/extension/IconSpan.java @@ -1,4 +1,4 @@ -package noties.ru.markwon_samplecustomextension; +package ru.noties.markwon.sample.extension; import android.graphics.Canvas; import android.graphics.Paint; @@ -12,10 +12,11 @@ import android.text.style.ReplacementSpan; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +@SuppressWarnings("WeakerAccess") public class IconSpan extends ReplacementSpan { @IntDef({ALIGN_BOTTOM, ALIGN_BASELINE, ALIGN_CENTER}) - @Retention(RetentionPolicy.SOURCE) + @Retention(RetentionPolicy.CLASS) @interface Alignment { } diff --git a/sample-custom-extension/src/main/java/ru/noties/markwon/sample/extension/IconSpanProvider.java b/sample-custom-extension/src/main/java/ru/noties/markwon/sample/extension/IconSpanProvider.java new file mode 100644 index 00000000..cd6e3bf3 --- /dev/null +++ b/sample-custom-extension/src/main/java/ru/noties/markwon/sample/extension/IconSpanProvider.java @@ -0,0 +1,67 @@ +package ru.noties.markwon.sample.extension; + +import android.content.Context; +import android.content.res.Resources; +import android.graphics.drawable.Drawable; +import android.os.Build; +import android.support.annotation.DrawableRes; +import android.support.annotation.NonNull; + +@SuppressWarnings("WeakerAccess") +public abstract class IconSpanProvider { + + @SuppressWarnings("SameParameterValue") + @NonNull + public static IconSpanProvider create(@NonNull Context context, @DrawableRes int fallBack) { + return new Impl(context, fallBack); + } + + + @NonNull + public abstract IconSpan provide(@NonNull String name, @NonNull String color, @NonNull String size); + + + private static class Impl extends IconSpanProvider { + + private static final boolean IS_L = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP; + + private final Context context; + private final Resources resources; + private final int fallBack; + + Impl(@NonNull Context context, @DrawableRes int fallBack) { + this.context = context; + this.resources = context.getResources(); + this.fallBack = fallBack; + } + + @NonNull + @Override + public IconSpan provide(@NonNull String name, @NonNull String color, @NonNull String size) { + final String resName = iconName(name, color, size); + int resId = resources.getIdentifier(resName, "drawable", context.getPackageName()); + if (resId == 0) { + resId = fallBack; + } + return new IconSpan(getDrawable(resId), IconSpan.ALIGN_CENTER); + } + + + @NonNull + private static String iconName(@NonNull String name, @NonNull String color, @NonNull String size) { + return "ic_" + name + "_" + color + "_" + size + "dp"; + } + + @NonNull + private Drawable getDrawable(int resId) { + final Drawable drawable; + if (IS_L) { + drawable = context.getDrawable(resId); + } else { + drawable = resources.getDrawable(resId); + } + //noinspection ConstantConditions + return drawable; + } + } +} diff --git a/sample-custom-extension/src/main/java/noties/ru/markwon_samplecustomextension/IconVisitor.java b/sample-custom-extension/src/main/java/ru/noties/markwon/sample/extension/IconVisitor.java similarity index 95% rename from sample-custom-extension/src/main/java/noties/ru/markwon_samplecustomextension/IconVisitor.java rename to sample-custom-extension/src/main/java/ru/noties/markwon/sample/extension/IconVisitor.java index ca047451..5ab65fed 100644 --- a/sample-custom-extension/src/main/java/noties/ru/markwon_samplecustomextension/IconVisitor.java +++ b/sample-custom-extension/src/main/java/ru/noties/markwon/sample/extension/IconVisitor.java @@ -1,4 +1,4 @@ -package noties.ru.markwon_samplecustomextension; +package ru.noties.markwon.sample.extension; import android.support.annotation.NonNull; import android.text.TextUtils; @@ -9,6 +9,7 @@ import ru.noties.markwon.SpannableBuilder; import ru.noties.markwon.SpannableConfiguration; import ru.noties.markwon.renderer.SpannableMarkdownVisitor; +@SuppressWarnings("WeakerAccess") public class IconVisitor extends SpannableMarkdownVisitor { private final SpannableBuilder builder; diff --git a/sample-custom-extension/src/main/java/ru/noties/markwon/sample/extension/MainActivity.java b/sample-custom-extension/src/main/java/ru/noties/markwon/sample/extension/MainActivity.java new file mode 100644 index 00000000..a81f8eb0 --- /dev/null +++ b/sample-custom-extension/src/main/java/ru/noties/markwon/sample/extension/MainActivity.java @@ -0,0 +1,66 @@ +package ru.noties.markwon.sample.extension; + +import android.app.Activity; +import android.os.Bundle; +import android.widget.TextView; + +import org.commonmark.ext.gfm.strikethrough.StrikethroughExtension; +import org.commonmark.ext.gfm.tables.TablesExtension; +import org.commonmark.node.Node; +import org.commonmark.parser.Parser; + +import java.util.Arrays; + +import ru.noties.markwon.SpannableBuilder; +import ru.noties.markwon.SpannableConfiguration; +import ru.noties.markwon.tasklist.TaskListExtension; + +public class MainActivity extends Activity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setContentView(R.layout.activity_main); + + final TextView textView = findViewById(R.id.text_view); + + // obtain an instance of parser + final Parser parser = new Parser.Builder() + // we will register all known to Markwon extensions + .extensions(Arrays.asList( + StrikethroughExtension.create(), + TablesExtension.create(), + TaskListExtension.create() + )) + // this is the handler for custom icons + .customDelimiterProcessor(IconProcessor.create()) + .build(); + + // we process input to wrap icon definitions with `@` on both ends + // if your input already does it, there is not need for `IconProcessor.prepare()` call. + final String markdown = IconProcessor.prepare(getString(R.string.input)); + + final Node node = parser.parse(markdown); + + final SpannableBuilder builder = new SpannableBuilder(); + + // please note that here I am passing `0` as fallback it means that if markdown references + // unknown icon, it will try to load fallback one and will fail with ResourceNotFound. It's + // better to provide a valid fallback option + final IconSpanProvider spanProvider = IconSpanProvider.create(this, 0); + + // create an instance of visitor to process parsed markdown + final IconVisitor visitor = new IconVisitor( + SpannableConfiguration.create(this), + builder, + spanProvider + ); + + // trigger visit + node.accept(visitor); + + // apply + textView.setText(builder.text()); + } +} diff --git a/sample-custom-extension/src/main/res/drawable-hdpi/ic_3d_rotation_white_24dp.png b/sample-custom-extension/src/main/res/drawable-hdpi/ic_3d_rotation_white_24dp.png deleted file mode 100644 index a243e01cab78d76a2813757569cd0841ac6d3431..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 631 zcmV--0*L*IP)>~bN6m9i8ni2%r`UN{ATAr-+a4{GiRZb6k`n0 zOB=P0O(Ds@GDs`s(V*ZX+w4)JOqsfyxDDzvH6(asP|v9>6?KFfQ@b2xQmFSVcWetg z7&p={vPbPCE!0KFzHrQF)o2fLc`VRd%Is0=$OyH2zV7AbiG_~c6=)!Q+5*n-MJtVQ zWBPb=5&esMY|8U)Qh$c(Fwiv(4Rel%s$b!Hp!@XkQuQSJ0^TvctM@=5W{IxA4;C9c zJ8`22TIQ`k&IGFiGx{`oy%4mJI#zl1Ex9!NL9)BD_bf2uqrrb}cZ6Pd_FCbFMfYZYIqcuLLH?2;YCmQ4K~rsB%3FS7qG iQ&($K@nl@>x9khAqT;4jmKQ|;0000|k0wldT1B8LpI!_nJkcwN$2@pq4D8*g+FH=cy$_Hqg8C^ZtdU*C~v>iy$ z4`^dKaB73dYD0w`EE?V_4^nTmUX~EJbM%07k6{u|`bR0|ru2qY91Nmu)-1h@2d#ey zYifM_t1k4&bIFDy?m9;%dQ23S-zea%iQzu0b3iHSg$GkCiCxvX`{;a diff --git a/sample-custom-extension/src/main/res/drawable-mdpi/ic_3d_rotation_white_24dp.png b/sample-custom-extension/src/main/res/drawable-mdpi/ic_3d_rotation_white_24dp.png deleted file mode 100644 index 9ebba4c05eb24df421461c0b92fc9201f7cc75fc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 399 zcmV;A0dW3_P)LLivZL_!vf(T+~Cn*jV)XCLRTk#i;(to1hQnWa@iHIN~D!3FuC<@|K z7s0`{s9^N-cJg}_xSxQK8dWIhZM)hh4A!XR<=Qs`brgr2sM9FA`dW_Xs3cZ@3jSDAEkHo>oJ zLMy#rHf}Mf2G0$!qLgL6Ni{R>Iraj**!1bSL&*S3X0*UfGh>e@f8{Cmd1cxIWT|#* zbwY(akn;d*K7b1OMl`^PR>NIp zc@%WZm|{oQ7bWKWRoilY*9s%~UMC&~u(e^AM8hD9YVj}}k`;30e!py!47y5{4^9Nu tf+7hW3&)(%pooFiwUrh9WF|Xj`~e8_6eFGdy2Sth002ovPDHLkV1jBftW*F1 diff --git a/sample-custom-extension/src/main/res/drawable-mdpi/ic_account_balance_white_26dp.png b/sample-custom-extension/src/main/res/drawable-mdpi/ic_account_balance_white_26dp.png deleted file mode 100644 index e685049a46a60a13f363f5bf932250b186792985..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 216 zcmV;}04M*6P)RLEYS5rJr~wKcND&$A*|mX8=rD51?9sv>4*&or*w*ZP S*?8^%0000Iqu;VH)tJOM2H0f{@B7s;@^H_&(-ly~NX zkh3MnK9*AnjCnlsH)^pTJkPW4#i_-Tbq_=Mn)XX9nlM$|_|M_hGA#cYLl-jEoZ865 iW%58w@~S}yBSUEZ#?W&Ixa@#VVeoYIb6Mw<&;$VXbU*9> diff --git a/sample-custom-extension/src/main/res/drawable-xhdpi/ic_3d_rotation_white_24dp.png b/sample-custom-extension/src/main/res/drawable-xhdpi/ic_3d_rotation_white_24dp.png deleted file mode 100644 index aa366a1481f02113dc6bd805a69baf8de87c6f72..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 835 zcmV-J1HAl+P) zO>B%o7{@2swh>>AZn0K^^k5|jdzAFRO-q$SCC>e%iJ}rjhc)hX4{df^x3_dIazsA+G>-L=PJATK$e= zi&ua&qKAK%;SiFH_=`5L020w^8-?+X5&zKQ6~NgSBC2*#Zw4Sxi3lTpV5J#=+{FkZ zp2BAaAg~^jj5uftAjq_A6R0)?@L`A%=S=|wxm)T}&oc!O%FlP_1_W^p@5ynJc!6$I zDCu;Y#7mrZiKA_-(U%Lb8eJ6L|Zusadt6TPAZEKV89TCGYt2|j-g=#NPC7!xb_#~Sd1rOGYSRG4OORrvW2%S_Q0 N002ovPDHLkV1jtVd13$n diff --git a/sample-custom-extension/src/main/res/drawable-xhdpi/ic_account_balance_white_26dp.png b/sample-custom-extension/src/main/res/drawable-xhdpi/ic_account_balance_white_26dp.png deleted file mode 100644 index eb565ec04d869fba7d3d22ac11ca2e18972fd75a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 297 zcmeAS@N?(olHy`uVBq!ia0vp^9w5xY0wn)GsXhawK6tt~hE&{odt)zeQ-DNkqI2Rx z(Yd;&d-)!)=q=#h(V+K$X;%Zc0VA_T!`f-LA_Fs=;yl-QaD4h)X!voDDC>mf4^^fg zbod+HbF(P%@C$JR=WBOUBCG&i5E zNy}oBos?dQ3YN8UT1*PsZ&Izd;h2xbheehC-+a~>*jWqRnx69hqpsPH#@K$b>Up;l zPS1K%`H(F-EdRW>*^NzE)p3cSB~l^;5z?kZ1kVB%DP5ta;^ pOYg|c|LP4?#d2wW&C)5Q`N~>7SD!oOoCW%w!PC{xWt~$(699|0ed7QC diff --git a/sample-custom-extension/src/main/res/drawable-xhdpi/ic_home_black_24dp.png b/sample-custom-extension/src/main/res/drawable-xhdpi/ic_home_black_24dp.png deleted file mode 100644 index 587efd5acc8c23133c1b5d9c48be3e03094fbf87..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 261 zcmV+g0s8)lP)jQ)tmt5+KND>$l_Bp|+LR4gOodyR@^M0}r7v5@igMa4qI=ZcDD zAU5umg6$4#XU=+5T&HLypB`kS_O#00000 LNkvXXu0mjf`{ZqO diff --git a/sample-custom-extension/src/main/res/drawable-xxhdpi/ic_3d_rotation_white_24dp.png b/sample-custom-extension/src/main/res/drawable-xxhdpi/ic_3d_rotation_white_24dp.png deleted file mode 100644 index 07cf86a4eb357692e493c5d46492ed988525d971..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1258 zcmV_@EK?otDMvxFN@)9KqLJ0B@(rSYUfe=$lNC1^bAciQkg%}&b z5Bh-*K*FPefF)prh@W_hL;@I^A}R$+dG@ybbC#Vw-MPKHJNITgyXPcrI?rEcXU?2+ zMu-putB^n=9^hY`!vSo;0t`boL?$W_j+P)<9^eo@!}C!Ar9!ghR}>&O3Lt?}c*+0x z0?(KS@?e36>y4Ca~zYKgQ5_m#iTpubrl6{(p1?ul}; zQ_XS;Dfk}Mg8ZjacKmr?hjn1N7 z9DuUv5^-c<9DpqA?OZ6=(J>A{0^4|visAv(lYDPms*n{2Ah%~QHC&)9McZok>&yFS zf4V?p@DmyR1lf-o9K%XHr_?6PZJeOneXz#36|zSH-SmMvV_%CY?_in_P_w@n6r0W9 zwuQPtPbtn7Tn@yfKp<9Y;U>^0~J?})sp zBU$^`9A4s0@c_!9sKD`jd&B`qP!t6XN7EqC(-fpRUe4=r0CERwXES}k4Hu|A{$!-D z;{arZeoY!C(jbsKn^i}5Rt$i0ahj2;(Jy)+%Z9WEz+4xSmDy1rw!fsZGP6L|bzAR3I?p){fz`6C%q)<=c-Qu}9IYRpI9h95 zWo2f8tWfZb;{841XcZc1x>f+P?9vuxH?@>fvp}}vdch=;-b33G3V^(;nlov=d2 z@~w=NPU9Tp;}?%TRT2e|t$nZ<2l#aYVTT8qc5IKKm`5ABf=t6T!fPO-urdsw$L!ak UM$SsRHvj+t07*qoM6N<$f+ng=VE_OC diff --git a/sample-custom-extension/src/main/res/drawable-xxhdpi/ic_account_balance_white_26dp.png b/sample-custom-extension/src/main/res/drawable-xxhdpi/ic_account_balance_white_26dp.png deleted file mode 100644 index a3931f6db8de994c3dbbeb1a7c3f764ecb5795d9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 432 zcmeAS@N?(olHy`uVBq!ia0vp^IUvlz0wh)Q=esd5FqV6|IEGZ*dV5PhkI7M@?ISN! zpa|b?srykvehn*^h`(T65p|t=3ilVLIStGO3_4RE1az1w=BuwUCM{Py_tY0qWd zH!0d1+puivF`V}2%H_R9sq>CM_D#FxRdv1F?QWy*){Ec$s;(K--k5vs*UrUayFA6s zu6a%0etq$;mj{dXzFMlZuNx!BZ=9_3a*=}PF*J;yt!mpQY zh*@lxxmZ&te7FCtEUwd6UrjcfeW+;a?Z`wyN|hC z$L)T;Jz5gRz|6)YVUTd0`SlS-FzdiB{?%V^zW*g+kZ_=Z5h9Du*ihdfDt=yN(()e< y`GJ}bG?dDPsT8aIDHQ|rAiDPTLvG_fN8f=l!QkoY=d#Wzp$P!AYO^l@ diff --git a/sample-custom-extension/src/main/res/drawable-xxhdpi/ic_home_black_24dp.png b/sample-custom-extension/src/main/res/drawable-xxhdpi/ic_home_black_24dp.png deleted file mode 100644 index b38dc4f345daaa28930d13c994c8cbf311a3cedd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 327 zcmV-N0l5B&P)x_;czz4jy;CSyznB8UOLrQ_(nMz9&;n~o>ObZDJ9E)N~g*_{lyC6X5%PlClzIxD0fI-b(5Fj%`StJ&HyhPvKq#i(n}vKrHVOlwusq=LkwMjOBX-r5MGs zDuPlBVp$hKDax^Iil7w5SbmG36s1^7A}FPIEZamdKrGuv&^VS|B4`-Pt`RhfWuFKd z#IkP$m1C(9LB&{VMNlc0nh`XLrG-MTQHVl+CZzipg(yTJ3Q>qc6rvD?eo=_yIF94S ZzALCQJSzuLJ_7&%002ovPDHLkV1nMle(3-J diff --git a/sample-custom-extension/src/main/res/drawable-xxxhdpi/ic_3d_rotation_white_24dp.png b/sample-custom-extension/src/main/res/drawable-xxxhdpi/ic_3d_rotation_white_24dp.png deleted file mode 100644 index aea49c26b5202eb30205185a1ce069c70b1e9313..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1677 zcmV;826Fj{P)t%{KkL?wRE_y*L9QWVn`s$gvaZPB(tiOL6JkkmwJ)fgH~G@u03 zV8voIH3f+eq#`C-0UHEu5d;*(Vw)niQ2YKn+uQD**~i`4dvEXEnfY*Ub{@OGotZP| zoH@(bkR?n*Gy2er4xGg?>_rt`!;?tEc(BN2hM~+E=!7-(p#g6r4-@?l;DiuJz4#W( zk?L;%hRh%cTI$Ajjv4P?0ER3V1TFoBrMTFy0CEVxpD0FxKLHr#N+AICNcSgzJOZ%Q zi+qY6fQHZ|iO`G%egyD>0Bpbr{{b+}vq5+sOK{ugdHY?9_0EDfZ-a) zk~qA;HCAyHGW`b-Jm;CVy$iTmEdYjl&?X=>;tI6@7`NTd3kbCsrWOFhOm2?S^oD8x zjEhilIcKN_z_7}+5|UH{h(oo2@Q!K#4C8S^K$xK#0K?tFO8AkFiedl^>x3~_s2;#r z{4Mw}E>aDEp->ouMd|^>;}8Kjs2%`AjxYvysRs~`dcpak9022XvynP5E+UD<1)jqcn|gLhtG^Sa?k2k_k3lQxXJKsRRIZCFXnbOm8G@ zKMNIL7(NX0NR7DO1Avx(z*W-sP8TN8=+FQ*yF5@MQak|w|8o0F?%oN)$Y+KEkWD%` zk2PFRnTlJm3=Iw%qmlMt8v1rteZBBnpWY~35&(KKvywNMbO(+}4%WO(N)jM7%380Nzx0AKykg4Zxab$POFZGVs zNCPl@px0=VIum$>^jR8NUFD38$>9!=6=Yr6)oE?o4!22II{RxOWbER z>9Z!1E_1_=_KfX5Q0~~)*b_dE<}qsm3i@*)e{cK9gH|}G63zhM6Zc^h0fyVEbLA%G zOa|a{y-q`H0lM)>5Ovxaz!1MjV?P2FnBW;;M{EER@l}7W!7u0`4|)Wbc?8%Un<+%| z1a6NRuJG@O?@R`uj@Sk<4EDH>$nyoB0GjnWRo(&ikXy_Q6Je{~(>4zPmy=m;lp=G>Vf3*h%cNQQiR_Be!s$fn|KJ4CJS5O7A2) zg6s&~=D3GT0!$|z{NdVQyTFlet{ zS}6sPM0Nn+{ZNDcsMj~wr9ldj_WOmH&v>jQ{mgX*NW@~CBBiG#jd~jZdit@+wF!O9 z7B2Q?aZ7dvH!$l2SC!pHwi_$@^RsvvpO~V9F5uSC<3{HT@4?N{HxfU&xT*dT0y$(- z3+@P2@&!%-X$)1GYok;$*RAP{>0P>~8p~?(tV--6-L02W<5uzaY!^oSu0;$4Pqo~V z3v2HQ{5(OrJjW-AOw*Cb<8r$mZCw1d;~1*39FwHn>wRd&VZI7hU~2dpSm5UpVGTj3xnLrD_1;F{-u_9#Rc};Vl8-KYuS~ zd#CMw0ii8)b0anYj2jqYC`W79KD#IbXx^H30igpqY5`~;>vWrzb4d^t?^^!>Ff2l^ z$(E{i*xE|DL6q%30EUI8QP2WB(rq3;5a5yRKLBkawOcIOH-!lDQWB#w&wl`#@3hJ0 zTgRe-4`)k->oGu(sWe&ex(%jZk%uzN)h@RW*J1&{FajH-KjMrsf|p34W=Vw3Xd-y2 zJdvD%xgliv5kSkc$bp0}5JCy@C=~qq&Ip0m9 z@ie}%=u8wL!`}dd-t8Q|Q~YcT(lN9Mk?n3QZbvc7@eyiq6fInj>fw{D(dkp#NaX(k XAygH^f{J%z00000NkvXXu0mjf$^8P> diff --git a/sample-custom-extension/src/main/res/drawable-xxxhdpi/ic_account_balance_white_26dp.png b/sample-custom-extension/src/main/res/drawable-xxxhdpi/ic_account_balance_white_26dp.png deleted file mode 100644 index 31a06f71b78cbb5579d24c918babab883c55e81d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 488 zcmeAS@N?(olHy`uVBq!ia0vp^6F``Q1xWh(YZ)^zFs}D>aSW-r_4d|AU#3Kcw!~z| zg;VG1n(pO0z@oQ+dq;!b1EyUK+y;%z77c5s-3koMaI)KIaIi(7MgGV8ca`gR|0zEj zTs!^F!A2F&TPx-~&n%leF`~uzgvS0}BL$=W%jc7q&CIvjeOdi;bMdV9n$*DgJI`ls zFZ3&#?m5kL=3I-HYUc{`jL&KH7EfNB_wY;6-2Okyzuy$zoA*HGnO1(}^6N3rHoUbF zuRN)?_sOEY7Kd$?yPTKYR;)aIjc@hu^KN>P(%-%{^~P*Ud;eBddS}YnJGZrSo=h^$ z&i|hbR3lkk-3yf5_5B+gP;%?Lx4q^?C$nzfK57P}Zr(m>UNrmLw`*oaKtraP7j6Fj ztcZe0|&Y)pt&qzI|Jw;LyOp$i%`S0A{S> z^_ZmMIVr?{sU1^xH9x8(TopbBP`8Tbs4_;uunK>+RLEflQ79M?XG$ z;JaQ;K~kcbZDFDSd!&cZkp{^L4C#3?2P9W5c#{1#b$NBwn*Y_}S>@fY%71kVIB_Vp z2+ZzDnPrvr^$+{ZlX_pZ|7IEZ8{MBj-+KD-Yv<~xy?^|3XZM#S3wu&4i|XD5#YI{E z4-FH4{(Rk~*=(QmUatnSp6dSkIe*j6%DQ)Mc1rW@C+0r?x%2jy(1}fJ8cU@8MZIX2tBrzB}%kVyERPpj@P26eY07k`gTMveA+TwHHvRX zUyv! diff --git a/sample-custom-extension/src/main/res/drawable/ic_android_black_24dp.xml b/sample-custom-extension/src/main/res/drawable/ic_android_black_24dp.xml new file mode 100644 index 00000000..401cbf63 --- /dev/null +++ b/sample-custom-extension/src/main/res/drawable/ic_android_black_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/sample-custom-extension/src/main/res/drawable/ic_home_black_36dp.xml b/sample-custom-extension/src/main/res/drawable/ic_home_black_36dp.xml new file mode 100644 index 00000000..c3b7e150 --- /dev/null +++ b/sample-custom-extension/src/main/res/drawable/ic_home_black_36dp.xml @@ -0,0 +1,4 @@ + + + diff --git a/sample-custom-extension/src/main/res/drawable/ic_memory_black_48dp.xml b/sample-custom-extension/src/main/res/drawable/ic_memory_black_48dp.xml new file mode 100644 index 00000000..88ac2954 --- /dev/null +++ b/sample-custom-extension/src/main/res/drawable/ic_memory_black_48dp.xml @@ -0,0 +1,4 @@ + + + diff --git a/sample-custom-extension/src/main/res/drawable/ic_sentiment_satisfied_red_64dp.xml b/sample-custom-extension/src/main/res/drawable/ic_sentiment_satisfied_red_64dp.xml new file mode 100644 index 00000000..f9c60705 --- /dev/null +++ b/sample-custom-extension/src/main/res/drawable/ic_sentiment_satisfied_red_64dp.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/sample-custom-extension/src/main/res/layout/activity_main.xml b/sample-custom-extension/src/main/res/layout/activity_main.xml new file mode 100644 index 00000000..439dac71 --- /dev/null +++ b/sample-custom-extension/src/main/res/layout/activity_main.xml @@ -0,0 +1,16 @@ + + + + + + \ No newline at end of file diff --git a/sample-custom-extension/src/main/res/values/colors.xml b/sample-custom-extension/src/main/res/values/colors.xml deleted file mode 100644 index 3ab3e9cb..00000000 --- a/sample-custom-extension/src/main/res/values/colors.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - #3F51B5 - #303F9F - #FF4081 - diff --git a/sample-custom-extension/src/main/res/values/strings.xml b/sample-custom-extension/src/main/res/values/strings.xml index 229056d3..7dc177e7 100644 --- a/sample-custom-extension/src/main/res/values/strings.xml +++ b/sample-custom-extension/src/main/res/values/strings.xml @@ -1,3 +1,13 @@ + Markwon-SampleCustomExtension + + + + diff --git a/sample-custom-extension/src/main/res/values/styles.xml b/sample-custom-extension/src/main/res/values/styles.xml index 9785e0c9..49c8cb25 100644 --- a/sample-custom-extension/src/main/res/values/styles.xml +++ b/sample-custom-extension/src/main/res/values/styles.xml @@ -1,8 +1,5 @@ - - +