diff options
author | Docile-Alligator <chineseperson5@gmail.com> | 2021-11-15 00:47:32 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-11-15 00:47:32 +0000 |
commit | 2e0725e25e3f8eea0871c9e3a48fec673618298a (patch) | |
tree | e66d5f483283d5ed0a8f648ef9504082f822014a | |
parent | d0f0647bc8deeff87f297b4d60f6ed58a17a0d31 (diff) | |
parent | 550706d2d72fd12e0043a8e1eb90ae9437d92a6c (diff) | |
download | infinity-for-reddit-2e0725e25e3f8eea0871c9e3a48fec673618298a.tar infinity-for-reddit-2e0725e25e3f8eea0871c9e3a48fec673618298a.tar.gz infinity-for-reddit-2e0725e25e3f8eea0871c9e3a48fec673618298a.tar.bz2 infinity-for-reddit-2e0725e25e3f8eea0871c9e3a48fec673618298a.tar.lz infinity-for-reddit-2e0725e25e3f8eea0871c9e3a48fec673618298a.tar.xz infinity-for-reddit-2e0725e25e3f8eea0871c9e3a48fec673618298a.tar.zst infinity-for-reddit-2e0725e25e3f8eea0871c9e3a48fec673618298a.zip |
Merge pull request #526 from scria1000/markdown-disable-html
More fixes related to markdown rendering
18 files changed, 327 insertions, 171 deletions
diff --git a/app/build.gradle b/app/build.gradle index 24b666a8..25a6f061 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -154,6 +154,7 @@ dependencies { implementation "io.noties.markwon:recycler-table:$markwonVersion" implementation "io.noties.markwon:simple-ext:$markwonVersion" implementation "io.noties.markwon:html:$markwonVersion" + implementation "io.noties.markwon:inline-parser:$markwonVersion" implementation 'com.atlassian.commonmark:commonmark-ext-gfm-tables:0.14.0' implementation 'me.saket:better-link-movement-method:2.2.0' diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/CommentActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/CommentActivity.java index 1f85f362..ffb9173b 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/CommentActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/CommentActivity.java @@ -51,6 +51,10 @@ import io.noties.markwon.MarkwonConfiguration; import io.noties.markwon.core.MarkwonTheme; import io.noties.markwon.ext.strikethrough.StrikethroughPlugin; import io.noties.markwon.html.HtmlPlugin; +import io.noties.markwon.html.tag.SuperScriptHandler; +import io.noties.markwon.inlineparser.BangInlineProcessor; +import io.noties.markwon.inlineparser.HtmlInlineProcessor; +import io.noties.markwon.inlineparser.MarkwonInlineParserPlugin; import io.noties.markwon.linkify.LinkifyPlugin; import io.noties.markwon.recycler.MarkwonAdapter; import io.noties.markwon.recycler.table.TableEntry; @@ -68,6 +72,7 @@ import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; import ml.docilealligator.infinityforreddit.customviews.LinearLayoutManagerBugFixed; import ml.docilealligator.infinityforreddit.events.SwitchAccountEvent; import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; +import ml.docilealligator.infinityforreddit.utils.SuperscriptInlineProcessor; import ml.docilealligator.infinityforreddit.utils.Utils; import retrofit2.Retrofit; @@ -160,8 +165,21 @@ public class CommentActivity extends BaseActivity implements UploadImageEnabledA int linkColor = mCustomThemeWrapper.getLinkColor(); Markwon markwon = Markwon.builder(this) - .usePlugin(HtmlPlugin.create()) + .usePlugin(MarkwonInlineParserPlugin.create(plugin -> { + plugin.excludeInlineProcessor(HtmlInlineProcessor.class); + plugin.excludeInlineProcessor(BangInlineProcessor.class); + plugin.addInlineProcessor(new SuperscriptInlineProcessor()); + })) + .usePlugin(HtmlPlugin.create(plugin -> { + plugin.excludeDefaults(true).addHandler(new SuperScriptHandler()); + })) .usePlugin(new AbstractMarkwonPlugin() { + @NonNull + @Override + public String processMarkdown(@NonNull String markdown) { + return super.processMarkdown(Utils.fixSuperScript(markdown)); + } + @Override public void configureConfiguration(@NonNull MarkwonConfiguration.Builder builder) { builder.linkResolver((view, link) -> { @@ -201,8 +219,21 @@ public class CommentActivity extends BaseActivity implements UploadImageEnabledA contentMarkdownRecyclerView.setVisibility(View.VISIBLE); contentMarkdownRecyclerView.setNestedScrollingEnabled(false); Markwon postBodyMarkwon = Markwon.builder(this) - .usePlugin(HtmlPlugin.create()) + .usePlugin(MarkwonInlineParserPlugin.create(plugin -> { + plugin.excludeInlineProcessor(HtmlInlineProcessor.class); + plugin.excludeInlineProcessor(BangInlineProcessor.class); + plugin.addInlineProcessor(new SuperscriptInlineProcessor()); + })) + .usePlugin(HtmlPlugin.create(plugin -> { + plugin.excludeDefaults(true).addHandler(new SuperScriptHandler()); + })) .usePlugin(new AbstractMarkwonPlugin() { + @NonNull + @Override + public String processMarkdown(@NonNull String markdown) { + return super.processMarkdown(Utils.fixSuperScript(markdown)); + } + @Override public void beforeSetText(@NonNull TextView textView, @NonNull Spanned markdown) { textView.setTextColor(markdownColor); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/EditCommentActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/EditCommentActivity.java index 4f4b81ec..cb03370b 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/EditCommentActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/EditCommentActivity.java @@ -132,7 +132,7 @@ public class EditCommentActivity extends BaseActivity implements UploadImageEnab mFullName = getIntent().getStringExtra(EXTRA_FULLNAME); mAccessToken = mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCESS_TOKEN, null); - mCommentContent = getIntent().getStringExtra(EXTRA_CONTENT); + mCommentContent = getIntent().getStringExtra(EXTRA_CONTENT).replaceAll(">",">"); contentEditText.setText(mCommentContent); if (savedInstanceState != null) { diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/EditPostActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/EditPostActivity.java index 0d22d9b3..16e91ebc 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/EditPostActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/EditPostActivity.java @@ -141,7 +141,7 @@ public class EditPostActivity extends BaseActivity implements UploadImageEnabled mFullName = getIntent().getStringExtra(EXTRA_FULLNAME); mAccessToken = mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCESS_TOKEN, null); titleTextView.setText(getIntent().getStringExtra(EXTRA_TITLE)); - mPostContent = getIntent().getStringExtra(EXTRA_CONTENT); + mPostContent = getIntent().getStringExtra(EXTRA_CONTENT).replaceAll(">",">");; contentEditText.setText(mPostContent); if (savedInstanceState != null) { diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/FullMarkdownActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/FullMarkdownActivity.java index 60406d70..32a5f452 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/FullMarkdownActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/FullMarkdownActivity.java @@ -33,7 +33,6 @@ import org.commonmark.ext.gfm.tables.TableBlock; import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.Subscribe; -import java.util.ArrayList; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -48,6 +47,10 @@ import io.noties.markwon.MarkwonConfiguration; import io.noties.markwon.core.MarkwonTheme; import io.noties.markwon.ext.strikethrough.StrikethroughPlugin; import io.noties.markwon.html.HtmlPlugin; +import io.noties.markwon.html.tag.SuperScriptHandler; +import io.noties.markwon.inlineparser.BangInlineProcessor; +import io.noties.markwon.inlineparser.HtmlInlineProcessor; +import io.noties.markwon.inlineparser.MarkwonInlineParserPlugin; import io.noties.markwon.linkify.LinkifyPlugin; import io.noties.markwon.recycler.MarkwonAdapter; import io.noties.markwon.recycler.table.TableEntry; @@ -59,6 +62,8 @@ import ml.docilealligator.infinityforreddit.customviews.LinearLayoutManagerBugFi import ml.docilealligator.infinityforreddit.customviews.MarkwonLinearLayoutManager; import ml.docilealligator.infinityforreddit.events.SwitchAccountEvent; import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; +import ml.docilealligator.infinityforreddit.utils.SuperscriptInlineProcessor; +import ml.docilealligator.infinityforreddit.utils.Utils; public class FullMarkdownActivity extends BaseActivity { @@ -131,28 +136,25 @@ public class FullMarkdownActivity extends BaseActivity { int spoilerBackgroundColor = markdownColor | 0xFF000000; int linkColor = mCustomThemeWrapper.getLinkColor(); Markwon markwon = Markwon.builder(this) - .usePlugin(HtmlPlugin.create()) + .usePlugin(MarkwonInlineParserPlugin.create(plugin -> { + plugin.excludeInlineProcessor(HtmlInlineProcessor.class); + plugin.excludeInlineProcessor(BangInlineProcessor.class); + plugin.addInlineProcessor(new SuperscriptInlineProcessor()); + })) + .usePlugin(HtmlPlugin.create(plugin -> { + plugin.excludeDefaults(true).addHandler(new SuperScriptHandler()); + })) .usePlugin(new AbstractMarkwonPlugin() { @NonNull @Override public String processMarkdown(@NonNull String markdown) { - StringBuilder markdownStringBuilder = new StringBuilder(markdown); - Pattern spoilerPattern = Pattern.compile(">![\\S\\s]+?!<"); - Matcher matcher = spoilerPattern.matcher(markdownStringBuilder); - ArrayList<Integer> matched = new ArrayList<>(); - while (matcher.find()) { - matched.add(matcher.start()); - } - for (int i = matched.size() - 1; i >= 0; i--) { - markdownStringBuilder.replace(matched.get(i), matched.get(i) + 1, ">"); - } - return super.processMarkdown(markdownStringBuilder.toString()); + return super.processMarkdown(Utils.fixSuperScript(markdown)); } - + @Override public void afterSetText(@NonNull TextView textView) { textView.setHighlightColor(Color.TRANSPARENT); - SpannableStringBuilder markdownStringBuilder = new SpannableStringBuilder(textView.getText().toString()); + SpannableStringBuilder markdownStringBuilder = new SpannableStringBuilder(textView.getText()); Pattern spoilerPattern = Pattern.compile(">![\\S\\s]+?!<"); Matcher matcher = spoilerPattern.matcher(markdownStringBuilder); int start = 0; diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewSubredditDetailActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewSubredditDetailActivity.java index 8cf3dfc6..b81c06fe 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewSubredditDetailActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewSubredditDetailActivity.java @@ -4,6 +4,7 @@ import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.content.res.ColorStateList; +import android.graphics.PorterDuff; import android.net.Uri; import android.os.Build; import android.os.Bundle; @@ -71,6 +72,9 @@ import io.noties.markwon.AbstractMarkwonPlugin; import io.noties.markwon.Markwon; import io.noties.markwon.MarkwonConfiguration; import io.noties.markwon.core.MarkwonTheme; +import io.noties.markwon.inlineparser.BangInlineProcessor; +import io.noties.markwon.inlineparser.HtmlInlineProcessor; +import io.noties.markwon.inlineparser.MarkwonInlineParserPlugin; import io.noties.markwon.linkify.LinkifyPlugin; import io.noties.markwon.movement.MovementMethodPlugin; import jp.wasabeef.glide.transformations.RoundedCornersTransformation; @@ -380,6 +384,10 @@ public class ViewSubredditDetailActivity extends BaseActivity implements SortTyp Locale locale = getResources().getConfiguration().locale; Markwon markwon = Markwon.builder(this) + .usePlugin(MarkwonInlineParserPlugin.create(plugin -> { + plugin.excludeInlineProcessor(HtmlInlineProcessor.class); + plugin.excludeInlineProcessor(BangInlineProcessor.class); + })) .usePlugin(new AbstractMarkwonPlugin() { @Override public void configureConfiguration(@NonNull MarkwonConfiguration.Builder builder) { @@ -541,10 +549,10 @@ public class ViewSubredditDetailActivity extends BaseActivity implements SortTyp descriptionTextView.setTextColor(primaryTextColor); bottomNavigationView.setBackgroundTint(ColorStateList.valueOf(mCustomThemeWrapper.getBottomAppBarBackgroundColor())); int bottomAppBarIconColor = mCustomThemeWrapper.getBottomAppBarIconColor(); - option2BottomAppBar.setColorFilter(bottomAppBarIconColor, android.graphics.PorterDuff.Mode.SRC_IN); - option1BottomAppBar.setColorFilter(bottomAppBarIconColor, android.graphics.PorterDuff.Mode.SRC_IN); - option3BottomAppBar.setColorFilter(bottomAppBarIconColor, android.graphics.PorterDuff.Mode.SRC_IN); - option4BottomAppBar.setColorFilter(bottomAppBarIconColor, android.graphics.PorterDuff.Mode.SRC_IN); + option2BottomAppBar.setColorFilter(bottomAppBarIconColor, PorterDuff.Mode.SRC_IN); + option1BottomAppBar.setColorFilter(bottomAppBarIconColor, PorterDuff.Mode.SRC_IN); + option3BottomAppBar.setColorFilter(bottomAppBarIconColor, PorterDuff.Mode.SRC_IN); + option4BottomAppBar.setColorFilter(bottomAppBarIconColor, PorterDuff.Mode.SRC_IN); applyTabLayoutTheme(tabLayout); applyFABTheme(fab); unsubscribedColor = mCustomThemeWrapper.getUnsubscribed(); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewUserDetailActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewUserDetailActivity.java index d12290ee..16ec23b9 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewUserDetailActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewUserDetailActivity.java @@ -5,6 +5,7 @@ import android.content.Intent; import android.content.SharedPreferences; import android.content.res.ColorStateList; import android.content.res.Resources; +import android.graphics.PorterDuff; import android.net.Uri; import android.os.AsyncTask; import android.os.Build; @@ -73,6 +74,9 @@ import io.noties.markwon.AbstractMarkwonPlugin; import io.noties.markwon.Markwon; import io.noties.markwon.MarkwonConfiguration; import io.noties.markwon.core.MarkwonTheme; +import io.noties.markwon.inlineparser.BangInlineProcessor; +import io.noties.markwon.inlineparser.HtmlInlineProcessor; +import io.noties.markwon.inlineparser.MarkwonInlineParserPlugin; import io.noties.markwon.linkify.LinkifyPlugin; import io.noties.markwon.movement.MovementMethodPlugin; import jp.wasabeef.glide.transformations.RoundedCornersTransformation; @@ -376,6 +380,10 @@ public class ViewUserDetailActivity extends BaseActivity implements SortTypeSele Locale locale = getResources().getConfiguration().locale; Markwon markwon = Markwon.builder(this) + .usePlugin(MarkwonInlineParserPlugin.create(plugin -> { + plugin.excludeInlineProcessor(HtmlInlineProcessor.class); + plugin.excludeInlineProcessor(BangInlineProcessor.class); + })) .usePlugin(new AbstractMarkwonPlugin() { @Override public void configureConfiguration(@NonNull MarkwonConfiguration.Builder builder) { @@ -635,10 +643,10 @@ public class ViewUserDetailActivity extends BaseActivity implements SortTypeSele cakedayTextView.setTextColor(mCustomThemeWrapper.getPrimaryTextColor()); bottomNavigationView.setBackgroundTint(ColorStateList.valueOf(mCustomThemeWrapper.getBottomAppBarBackgroundColor())); int bottomAppBarIconColor = mCustomThemeWrapper.getBottomAppBarIconColor(); - option2BottomAppBar.setColorFilter(bottomAppBarIconColor, android.graphics.PorterDuff.Mode.SRC_IN); - option1BottomAppBar.setColorFilter(bottomAppBarIconColor, android.graphics.PorterDuff.Mode.SRC_IN); - option3BottomAppBar.setColorFilter(bottomAppBarIconColor, android.graphics.PorterDuff.Mode.SRC_IN); - option4BottomAppBar.setColorFilter(bottomAppBarIconColor, android.graphics.PorterDuff.Mode.SRC_IN); + option2BottomAppBar.setColorFilter(bottomAppBarIconColor, PorterDuff.Mode.SRC_IN); + option1BottomAppBar.setColorFilter(bottomAppBarIconColor, PorterDuff.Mode.SRC_IN); + option3BottomAppBar.setColorFilter(bottomAppBarIconColor, PorterDuff.Mode.SRC_IN); + option4BottomAppBar.setColorFilter(bottomAppBarIconColor, PorterDuff.Mode.SRC_IN); applyFABTheme(fab); descriptionTextView.setTextColor(mCustomThemeWrapper.getPrimaryTextColor()); subscribeUserChip.setTextColor(mCustomThemeWrapper.getChipTextColor()); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/WikiActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/WikiActivity.java index 63b147fb..1a353a7f 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/WikiActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/WikiActivity.java @@ -37,7 +37,6 @@ import org.greenrobot.eventbus.Subscribe; import org.json.JSONException; import org.json.JSONObject; -import java.util.ArrayList; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -52,6 +51,10 @@ import io.noties.markwon.MarkwonConfiguration; import io.noties.markwon.core.MarkwonTheme; import io.noties.markwon.ext.strikethrough.StrikethroughPlugin; import io.noties.markwon.html.HtmlPlugin; +import io.noties.markwon.html.tag.SuperScriptHandler; +import io.noties.markwon.inlineparser.BangInlineProcessor; +import io.noties.markwon.inlineparser.HtmlInlineProcessor; +import io.noties.markwon.inlineparser.MarkwonInlineParserPlugin; import io.noties.markwon.linkify.LinkifyPlugin; import io.noties.markwon.recycler.MarkwonAdapter; import io.noties.markwon.recycler.table.TableEntry; @@ -65,6 +68,8 @@ import ml.docilealligator.infinityforreddit.customviews.MarkwonLinearLayoutManag import ml.docilealligator.infinityforreddit.events.SwitchAccountEvent; import ml.docilealligator.infinityforreddit.utils.JSONUtils; import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; +import ml.docilealligator.infinityforreddit.utils.SuperscriptInlineProcessor; +import ml.docilealligator.infinityforreddit.utils.Utils; import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; @@ -156,28 +161,25 @@ public class WikiActivity extends BaseActivity { int spoilerBackgroundColor = markdownColor | 0xFF000000; int linkColor = mCustomThemeWrapper.getLinkColor(); markwon = Markwon.builder(this) - .usePlugin(HtmlPlugin.create()) + .usePlugin(MarkwonInlineParserPlugin.create(plugin -> { + plugin.excludeInlineProcessor(HtmlInlineProcessor.class); + plugin.excludeInlineProcessor(BangInlineProcessor.class); + plugin.addInlineProcessor(new SuperscriptInlineProcessor()); + })) + .usePlugin(HtmlPlugin.create(plugin -> { + plugin.excludeDefaults(true).addHandler(new SuperScriptHandler()); + })) .usePlugin(new AbstractMarkwonPlugin() { @NonNull @Override public String processMarkdown(@NonNull String markdown) { - StringBuilder markdownStringBuilder = new StringBuilder(markdown); - Pattern spoilerPattern = Pattern.compile(">![\\S\\s]+?!<"); - Matcher matcher = spoilerPattern.matcher(markdownStringBuilder); - ArrayList<Integer> matched = new ArrayList<>(); - while (matcher.find()) { - matched.add(matcher.start()); - } - for (int i = matched.size() - 1; i >= 0; i--) { - markdownStringBuilder.replace(matched.get(i), matched.get(i) + 1, ">"); - } - return super.processMarkdown(markdownStringBuilder.toString()); + return super.processMarkdown(Utils.fixSuperScript(markdown)); } @Override public void afterSetText(@NonNull TextView textView) { textView.setHighlightColor(Color.TRANSPARENT); - SpannableStringBuilder markdownStringBuilder = new SpannableStringBuilder(textView.getText().toString()); + SpannableStringBuilder markdownStringBuilder = new SpannableStringBuilder(textView.getText()); Pattern spoilerPattern = Pattern.compile(">![\\S\\s]+?!<"); Matcher matcher = spoilerPattern.matcher(markdownStringBuilder); int start = 0; diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/CommentsListingRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/CommentsListingRecyclerViewAdapter.java index e298734c..616b9c1b 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/CommentsListingRecyclerViewAdapter.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/CommentsListingRecyclerViewAdapter.java @@ -4,6 +4,7 @@ import android.content.Intent; import android.content.SharedPreferences; import android.content.res.ColorStateList; import android.graphics.Color; +import android.graphics.PorterDuff; import android.net.Uri; import android.os.Bundle; import android.text.SpannableStringBuilder; @@ -30,7 +31,6 @@ import androidx.recyclerview.widget.DiffUtil; import androidx.recyclerview.widget.ItemTouchHelper; import androidx.recyclerview.widget.RecyclerView; -import java.util.ArrayList; import java.util.Locale; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -43,6 +43,10 @@ import io.noties.markwon.MarkwonConfiguration; import io.noties.markwon.core.MarkwonTheme; import io.noties.markwon.ext.strikethrough.StrikethroughPlugin; import io.noties.markwon.html.HtmlPlugin; +import io.noties.markwon.html.tag.SuperScriptHandler; +import io.noties.markwon.inlineparser.BangInlineProcessor; +import io.noties.markwon.inlineparser.HtmlInlineProcessor; +import io.noties.markwon.inlineparser.MarkwonInlineParserPlugin; import io.noties.markwon.linkify.LinkifyPlugin; import me.saket.bettermovementmethod.BetterLinkMovementMethod; import ml.docilealligator.infinityforreddit.NetworkState; @@ -61,6 +65,7 @@ import ml.docilealligator.infinityforreddit.customviews.CommentIndentationView; import ml.docilealligator.infinityforreddit.customviews.SpoilerOnClickTextView; import ml.docilealligator.infinityforreddit.utils.APIUtils; import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; +import ml.docilealligator.infinityforreddit.utils.SuperscriptInlineProcessor; import ml.docilealligator.infinityforreddit.utils.Utils; import retrofit2.Retrofit; @@ -116,22 +121,19 @@ public class CommentsListingRecyclerViewAdapter extends PagedListAdapter<Comment mCommentColor = customThemeWrapper.getCommentColor(); int commentSpoilerBackgroundColor = mCommentColor | 0xFF000000; mMarkwon = Markwon.builder(mActivity) - .usePlugin(HtmlPlugin.create()) + .usePlugin(MarkwonInlineParserPlugin.create(plugin -> { + plugin.excludeInlineProcessor(HtmlInlineProcessor.class); + plugin.excludeInlineProcessor(BangInlineProcessor.class); + plugin.addInlineProcessor(new SuperscriptInlineProcessor()); + })) + .usePlugin(HtmlPlugin.create(plugin -> { + plugin.excludeDefaults(true).addHandler(new SuperScriptHandler()); + })) .usePlugin(new AbstractMarkwonPlugin() { @NonNull @Override public String processMarkdown(@NonNull String markdown) { - StringBuilder markdownStringBuilder = new StringBuilder(markdown); - Pattern spoilerPattern = Pattern.compile(">![\\S\\s]+?!<"); - Matcher matcher = spoilerPattern.matcher(markdownStringBuilder); - ArrayList<Integer> matched = new ArrayList<>(); - while (matcher.find()) { - matched.add(matcher.start()); - } - for (int i = matched.size() - 1; i >= 0; i--) { - markdownStringBuilder.replace(matched.get(i), matched.get(i) + 1, ">"); - } - return super.processMarkdown(markdownStringBuilder.toString()); + return super.processMarkdown(Utils.fixSuperScript(markdown)); } @Override @@ -282,12 +284,12 @@ public class CommentsListingRecyclerViewAdapter extends PagedListAdapter<Comment switch (comment.getVoteType()) { case Comment.VOTE_TYPE_UPVOTE: ((CommentViewHolder) holder).upvoteButton - .setColorFilter(mUpvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); + .setColorFilter(mUpvotedColor, PorterDuff.Mode.SRC_IN); ((CommentViewHolder) holder).scoreTextView.setTextColor(mUpvotedColor); break; case Comment.VOTE_TYPE_DOWNVOTE: ((CommentViewHolder) holder).downvoteButton - .setColorFilter(mDownvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); + .setColorFilter(mDownvotedColor, PorterDuff.Mode.SRC_IN); ((CommentViewHolder) holder).scoreTextView.setTextColor(mDownvotedColor); break; } @@ -322,8 +324,8 @@ public class CommentsListingRecyclerViewAdapter extends PagedListAdapter<Comment ((CommentViewHolder) holder).authorFlairTextView.setVisibility(View.GONE); ((CommentViewHolder) holder).awardsTextView.setText(""); ((CommentViewHolder) holder).awardsTextView.setVisibility(View.GONE); - ((CommentViewHolder) holder).upvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - ((CommentViewHolder) holder).downvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + ((CommentViewHolder) holder).upvoteButton.setColorFilter(mCommentIconAndInfoColor, PorterDuff.Mode.SRC_IN); + ((CommentViewHolder) holder).downvoteButton.setColorFilter(mCommentIconAndInfoColor, PorterDuff.Mode.SRC_IN); ((CommentViewHolder) holder).scoreTextView.setTextColor(mCommentIconAndInfoColor); } } @@ -470,13 +472,13 @@ public class CommentsListingRecyclerViewAdapter extends PagedListAdapter<Comment commentTimeTextView.setTextColor(mSecondaryTextColor); awardsTextView.setTextColor(mSecondaryTextColor); commentMarkdownView.setTextColor(mCommentColor); - upvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + upvoteButton.setColorFilter(mCommentIconAndInfoColor, PorterDuff.Mode.SRC_IN); scoreTextView.setTextColor(mCommentIconAndInfoColor); - downvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - moreButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - expandButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - saveButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - replyButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + downvoteButton.setColorFilter(mCommentIconAndInfoColor, PorterDuff.Mode.SRC_IN); + moreButton.setColorFilter(mCommentIconAndInfoColor, PorterDuff.Mode.SRC_IN); + expandButton.setColorFilter(mCommentIconAndInfoColor, PorterDuff.Mode.SRC_IN); + saveButton.setColorFilter(mCommentIconAndInfoColor, PorterDuff.Mode.SRC_IN); + replyButton.setColorFilter(mCommentIconAndInfoColor, PorterDuff.Mode.SRC_IN); commentDivider.setBackgroundColor(mDividerColor); authorTextView.setOnClickListener(view -> { @@ -566,20 +568,20 @@ public class CommentsListingRecyclerViewAdapter extends PagedListAdapter<Comment int previousVoteType = comment.getVoteType(); String newVoteType; - downvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + downvoteButton.setColorFilter(mCommentIconAndInfoColor, PorterDuff.Mode.SRC_IN); if (previousVoteType != Comment.VOTE_TYPE_UPVOTE) { //Not upvoted before comment.setVoteType(Comment.VOTE_TYPE_UPVOTE); newVoteType = APIUtils.DIR_UPVOTE; upvoteButton - .setColorFilter(mUpvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); + .setColorFilter(mUpvotedColor, PorterDuff.Mode.SRC_IN); scoreTextView.setTextColor(mUpvotedColor); } else { //Upvoted before comment.setVoteType(Comment.VOTE_TYPE_NO_VOTE); newVoteType = APIUtils.DIR_UNVOTE; - upvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + upvoteButton.setColorFilter(mCommentIconAndInfoColor, PorterDuff.Mode.SRC_IN); scoreTextView.setTextColor(mCommentIconAndInfoColor); } @@ -593,19 +595,19 @@ public class CommentsListingRecyclerViewAdapter extends PagedListAdapter<Comment if (newVoteType.equals(APIUtils.DIR_UPVOTE)) { comment.setVoteType(Comment.VOTE_TYPE_UPVOTE); if (currentPosition == position) { - upvoteButton.setColorFilter(mUpvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); + upvoteButton.setColorFilter(mUpvotedColor, PorterDuff.Mode.SRC_IN); scoreTextView.setTextColor(mUpvotedColor); } } else { comment.setVoteType(Comment.VOTE_TYPE_NO_VOTE); if (currentPosition == position) { - upvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + upvoteButton.setColorFilter(mCommentIconAndInfoColor, PorterDuff.Mode.SRC_IN); scoreTextView.setTextColor(mCommentIconAndInfoColor); } } if (currentPosition == position) { - downvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + downvoteButton.setColorFilter(mCommentIconAndInfoColor, PorterDuff.Mode.SRC_IN); scoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, comment.getScore() + comment.getVoteType())); } @@ -633,19 +635,19 @@ public class CommentsListingRecyclerViewAdapter extends PagedListAdapter<Comment int previousVoteType = comment.getVoteType(); String newVoteType; - upvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + upvoteButton.setColorFilter(mCommentIconAndInfoColor, PorterDuff.Mode.SRC_IN); if (previousVoteType != Comment.VOTE_TYPE_DOWNVOTE) { //Not downvoted before comment.setVoteType(Comment.VOTE_TYPE_DOWNVOTE); newVoteType = APIUtils.DIR_DOWNVOTE; - downvoteButton.setColorFilter(mDownvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); + downvoteButton.setColorFilter(mDownvotedColor, PorterDuff.Mode.SRC_IN); scoreTextView.setTextColor(mDownvotedColor); } else { //Downvoted before comment.setVoteType(Comment.VOTE_TYPE_NO_VOTE); newVoteType = APIUtils.DIR_UNVOTE; - downvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + downvoteButton.setColorFilter(mCommentIconAndInfoColor, PorterDuff.Mode.SRC_IN); scoreTextView.setTextColor(mCommentIconAndInfoColor); } @@ -659,19 +661,19 @@ public class CommentsListingRecyclerViewAdapter extends PagedListAdapter<Comment if (newVoteType.equals(APIUtils.DIR_DOWNVOTE)) { comment.setVoteType(Comment.VOTE_TYPE_DOWNVOTE); if (currentPosition == position) { - downvoteButton.setColorFilter(mDownvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); + downvoteButton.setColorFilter(mDownvotedColor, PorterDuff.Mode.SRC_IN); scoreTextView.setTextColor(mDownvotedColor); } } else { comment.setVoteType(Comment.VOTE_TYPE_NO_VOTE); if (currentPosition == position) { - downvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + downvoteButton.setColorFilter(mCommentIconAndInfoColor, PorterDuff.Mode.SRC_IN); scoreTextView.setTextColor(mCommentIconAndInfoColor); } } if (currentPosition == position) { - upvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + upvoteButton.setColorFilter(mCommentIconAndInfoColor, PorterDuff.Mode.SRC_IN); scoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, comment.getScore() + comment.getVoteType())); } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/CommentsRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/CommentsRecyclerViewAdapter.java index b9d6bfd0..5bd116ee 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/CommentsRecyclerViewAdapter.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/CommentsRecyclerViewAdapter.java @@ -4,6 +4,7 @@ import android.content.Intent; import android.content.SharedPreferences; import android.content.res.ColorStateList; import android.graphics.Color; +import android.graphics.PorterDuff; import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.Bundle; @@ -48,6 +49,10 @@ import io.noties.markwon.MarkwonConfiguration; import io.noties.markwon.core.MarkwonTheme; import io.noties.markwon.ext.strikethrough.StrikethroughPlugin; import io.noties.markwon.html.HtmlPlugin; +import io.noties.markwon.html.tag.SuperScriptHandler; +import io.noties.markwon.inlineparser.BangInlineProcessor; +import io.noties.markwon.inlineparser.HtmlInlineProcessor; +import io.noties.markwon.inlineparser.MarkwonInlineParserPlugin; import io.noties.markwon.linkify.LinkifyPlugin; import io.noties.markwon.movement.MovementMethodPlugin; import me.saket.bettermovementmethod.BetterLinkMovementMethod; @@ -69,6 +74,7 @@ import ml.docilealligator.infinityforreddit.fragments.ViewPostDetailFragment; import ml.docilealligator.infinityforreddit.post.Post; import ml.docilealligator.infinityforreddit.utils.APIUtils; import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; +import ml.docilealligator.infinityforreddit.utils.SuperscriptInlineProcessor; import ml.docilealligator.infinityforreddit.utils.Utils; import retrofit2.Retrofit; @@ -160,22 +166,19 @@ public class CommentsRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerVi int commentSpoilerBackgroundColor = mCommentTextColor | 0xFF000000; int linkColor = customThemeWrapper.getLinkColor(); mCommentMarkwon = Markwon.builder(mActivity) - .usePlugin(HtmlPlugin.create()) + .usePlugin(MarkwonInlineParserPlugin.create(plugin -> { + plugin.excludeInlineProcessor(HtmlInlineProcessor.class); + plugin.excludeInlineProcessor(BangInlineProcessor.class); + plugin.addInlineProcessor(new SuperscriptInlineProcessor()); + })) + .usePlugin(HtmlPlugin.create(plugin -> { + plugin.excludeDefaults(true).addHandler(new SuperScriptHandler()); + })) .usePlugin(new AbstractMarkwonPlugin() { @NonNull @Override public String processMarkdown(@NonNull String markdown) { - StringBuilder markdownStringBuilder = new StringBuilder(markdown); - Pattern spoilerPattern = Pattern.compile(">![\\S\\s]+?!<"); - Matcher matcher = spoilerPattern.matcher(markdownStringBuilder); - ArrayList<Integer> matched = new ArrayList<>(); - while (matcher.find()) { - matched.add(matcher.start()); - } - for (int i = matched.size() - 1; i >= 0; i--) { - markdownStringBuilder.replace(matched.get(i), matched.get(i) + 1, ">"); - } - return super.processMarkdown(markdownStringBuilder.toString()); + return super.processMarkdown(Utils.fixSuperScript(markdown)); } @Override @@ -486,13 +489,13 @@ public class CommentsRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerVi switch (comment.getVoteType()) { case Comment.VOTE_TYPE_UPVOTE: ((CommentViewHolder) holder).upvoteButton - .setColorFilter(mUpvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); + .setColorFilter(mUpvotedColor, PorterDuff.Mode.SRC_IN); ((CommentViewHolder) holder).scoreTextView.setTextColor(mUpvotedColor); ((CommentViewHolder) holder).topScoreTextView.setTextColor(mUpvotedColor); break; case Comment.VOTE_TYPE_DOWNVOTE: ((CommentViewHolder) holder).downvoteButton - .setColorFilter(mDownvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); + .setColorFilter(mDownvotedColor, PorterDuff.Mode.SRC_IN); ((CommentViewHolder) holder).scoreTextView.setTextColor(mDownvotedColor); ((CommentViewHolder) holder).topScoreTextView.setTextColor(mDownvotedColor); break; @@ -501,19 +504,19 @@ public class CommentsRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerVi if (mPost.isArchived()) { ((CommentViewHolder) holder).replyButton .setColorFilter(mVoteAndReplyUnavailableVoteButtonColor, - android.graphics.PorterDuff.Mode.SRC_IN); + PorterDuff.Mode.SRC_IN); ((CommentViewHolder) holder).upvoteButton .setColorFilter(mVoteAndReplyUnavailableVoteButtonColor, - android.graphics.PorterDuff.Mode.SRC_IN); + PorterDuff.Mode.SRC_IN); ((CommentViewHolder) holder).downvoteButton .setColorFilter(mVoteAndReplyUnavailableVoteButtonColor, - android.graphics.PorterDuff.Mode.SRC_IN); + PorterDuff.Mode.SRC_IN); } if (mPost.isLocked()) { ((CommentViewHolder) holder).replyButton .setColorFilter(mVoteAndReplyUnavailableVoteButtonColor, - android.graphics.PorterDuff.Mode.SRC_IN); + PorterDuff.Mode.SRC_IN); } if (comment.isSaved()) { @@ -1059,10 +1062,10 @@ public class CommentsRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerVi ((CommentViewHolder) holder).awardsTextView.setText(""); ((CommentViewHolder) holder).awardsTextView.setVisibility(View.GONE); ((CommentViewHolder) holder).expandButton.setVisibility(View.GONE); - ((CommentViewHolder) holder).upvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + ((CommentViewHolder) holder).upvoteButton.setColorFilter(mCommentIconAndInfoColor, PorterDuff.Mode.SRC_IN); ((CommentViewHolder) holder).scoreTextView.setTextColor(mCommentIconAndInfoColor); - ((CommentViewHolder) holder).downvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - ((CommentViewHolder) holder).replyButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + ((CommentViewHolder) holder).downvoteButton.setColorFilter(mCommentIconAndInfoColor, PorterDuff.Mode.SRC_IN); + ((CommentViewHolder) holder).replyButton.setColorFilter(mCommentIconAndInfoColor, PorterDuff.Mode.SRC_IN); } } @@ -1171,13 +1174,13 @@ public class CommentsRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerVi topScoreTextView.setTextColor(mSecondaryTextColor); awardsTextView.setTextColor(mSecondaryTextColor); commentDivider.setBackgroundColor(mDividerColor); - upvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + upvoteButton.setColorFilter(mCommentIconAndInfoColor, PorterDuff.Mode.SRC_IN); scoreTextView.setTextColor(mCommentIconAndInfoColor); - downvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - moreButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - expandButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - saveButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - replyButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + downvoteButton.setColorFilter(mCommentIconAndInfoColor, PorterDuff.Mode.SRC_IN); + moreButton.setColorFilter(mCommentIconAndInfoColor, PorterDuff.Mode.SRC_IN); + expandButton.setColorFilter(mCommentIconAndInfoColor, PorterDuff.Mode.SRC_IN); + saveButton.setColorFilter(mCommentIconAndInfoColor, PorterDuff.Mode.SRC_IN); + replyButton.setColorFilter(mCommentIconAndInfoColor, PorterDuff.Mode.SRC_IN); authorFlairTextView.setOnClickListener(view -> authorTextView.performClick()); @@ -1254,20 +1257,20 @@ public class CommentsRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerVi int previousVoteType = comment.getVoteType(); String newVoteType; - downvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + downvoteButton.setColorFilter(mCommentIconAndInfoColor, PorterDuff.Mode.SRC_IN); if (previousVoteType != Comment.VOTE_TYPE_UPVOTE) { //Not upvoted before comment.setVoteType(Comment.VOTE_TYPE_UPVOTE); newVoteType = APIUtils.DIR_UPVOTE; - upvoteButton.setColorFilter(mUpvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); + upvoteButton.setColorFilter(mUpvotedColor, PorterDuff.Mode.SRC_IN); scoreTextView.setTextColor(mUpvotedColor); topScoreTextView.setTextColor(mUpvotedColor); } else { //Upvoted before comment.setVoteType(Comment.VOTE_TYPE_NO_VOTE); newVoteType = APIUtils.DIR_UNVOTE; - upvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + upvoteButton.setColorFilter(mCommentIconAndInfoColor, PorterDuff.Mode.SRC_IN); scoreTextView.setTextColor(mCommentIconAndInfoColor); topScoreTextView.setTextColor(mSecondaryTextColor); } @@ -1286,21 +1289,21 @@ public class CommentsRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerVi if (newVoteType.equals(APIUtils.DIR_UPVOTE)) { comment.setVoteType(Comment.VOTE_TYPE_UPVOTE); if (currentPosition == position) { - upvoteButton.setColorFilter(mUpvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); + upvoteButton.setColorFilter(mUpvotedColor, PorterDuff.Mode.SRC_IN); scoreTextView.setTextColor(mUpvotedColor); topScoreTextView.setTextColor(mUpvotedColor); } } else { comment.setVoteType(Comment.VOTE_TYPE_NO_VOTE); if (currentPosition == position) { - upvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + upvoteButton.setColorFilter(mCommentIconAndInfoColor, PorterDuff.Mode.SRC_IN); scoreTextView.setTextColor(mCommentIconAndInfoColor); topScoreTextView.setTextColor(mSecondaryTextColor); } } if (currentPosition == position) { - downvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + downvoteButton.setColorFilter(mCommentIconAndInfoColor, PorterDuff.Mode.SRC_IN); scoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, comment.getScore() + comment.getVoteType())); topScoreTextView.setText(mActivity.getString(R.string.top_score, @@ -1332,20 +1335,20 @@ public class CommentsRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerVi int previousVoteType = comment.getVoteType(); String newVoteType; - upvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + upvoteButton.setColorFilter(mCommentIconAndInfoColor, PorterDuff.Mode.SRC_IN); if (previousVoteType != Comment.VOTE_TYPE_DOWNVOTE) { //Not downvoted before comment.setVoteType(Comment.VOTE_TYPE_DOWNVOTE); newVoteType = APIUtils.DIR_DOWNVOTE; - downvoteButton.setColorFilter(mDownvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); + downvoteButton.setColorFilter(mDownvotedColor, PorterDuff.Mode.SRC_IN); scoreTextView.setTextColor(mDownvotedColor); topScoreTextView.setTextColor(mDownvotedColor); } else { //Downvoted before comment.setVoteType(Comment.VOTE_TYPE_NO_VOTE); newVoteType = APIUtils.DIR_UNVOTE; - downvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + downvoteButton.setColorFilter(mCommentIconAndInfoColor, PorterDuff.Mode.SRC_IN); scoreTextView.setTextColor(mCommentIconAndInfoColor); topScoreTextView.setTextColor(mSecondaryTextColor); } @@ -1364,21 +1367,21 @@ public class CommentsRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerVi if (newVoteType.equals(APIUtils.DIR_DOWNVOTE)) { comment.setVoteType(Comment.VOTE_TYPE_DOWNVOTE); if (currentPosition == position) { - downvoteButton.setColorFilter(mDownvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); + downvoteButton.setColorFilter(mDownvotedColor, PorterDuff.Mode.SRC_IN); scoreTextView.setTextColor(mDownvotedColor); topScoreTextView.setTextColor(mDownvotedColor); } } else { comment.setVoteType(Comment.VOTE_TYPE_NO_VOTE); if (currentPosition == position) { - downvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + downvoteButton.setColorFilter(mCommentIconAndInfoColor, PorterDuff.Mode.SRC_IN); scoreTextView.setTextColor(mCommentIconAndInfoColor); topScoreTextView.setTextColor(mSecondaryTextColor); } } if (currentPosition == position) { - upvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + upvoteButton.setColorFilter(mCommentIconAndInfoColor, PorterDuff.Mode.SRC_IN); scoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, comment.getScore() + comment.getVoteType())); topScoreTextView.setText(mActivity.getString(R.string.top_score, diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/MessageRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/MessageRecyclerViewAdapter.java index 440544dc..095a36f7 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/MessageRecyclerViewAdapter.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/MessageRecyclerViewAdapter.java @@ -35,6 +35,10 @@ import io.noties.markwon.MarkwonConfiguration; import io.noties.markwon.core.MarkwonTheme; import io.noties.markwon.ext.strikethrough.StrikethroughPlugin; import io.noties.markwon.html.HtmlPlugin; +import io.noties.markwon.html.tag.SuperScriptHandler; +import io.noties.markwon.inlineparser.BangInlineProcessor; +import io.noties.markwon.inlineparser.HtmlInlineProcessor; +import io.noties.markwon.inlineparser.MarkwonInlineParserPlugin; import io.noties.markwon.linkify.LinkifyPlugin; import ml.docilealligator.infinityforreddit.NetworkState; import ml.docilealligator.infinityforreddit.R; @@ -45,6 +49,8 @@ import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; import ml.docilealligator.infinityforreddit.message.FetchMessage; import ml.docilealligator.infinityforreddit.message.Message; import ml.docilealligator.infinityforreddit.message.ReadMessage; +import ml.docilealligator.infinityforreddit.utils.SuperscriptInlineProcessor; +import ml.docilealligator.infinityforreddit.utils.Utils; import retrofit2.Retrofit; public class MessageRecyclerViewAdapter extends PagedListAdapter<Message, RecyclerView.ViewHolder> { @@ -99,28 +105,25 @@ public class MessageRecyclerViewAdapter extends PagedListAdapter<Message, Recycl mButtonTextColor = customThemeWrapper.getButtonTextColor(); mMarkwon = Markwon.builder(mContext) - .usePlugin(HtmlPlugin.create()) + .usePlugin(MarkwonInlineParserPlugin.create(plugin -> { + plugin.excludeInlineProcessor(HtmlInlineProcessor.class); + plugin.excludeInlineProcessor(BangInlineProcessor.class); + plugin.addInlineProcessor(new SuperscriptInlineProcessor()); + })) + .usePlugin(HtmlPlugin.create(plugin -> { + plugin.excludeDefaults(true).addHandler(new SuperScriptHandler()); + })) .usePlugin(new AbstractMarkwonPlugin() { @NonNull @Override public String processMarkdown(@NonNull String markdown) { - StringBuilder markdownStringBuilder = new StringBuilder(markdown); - Pattern spoilerPattern = Pattern.compile(">![\\S\\s]+?!<"); - Matcher matcher = spoilerPattern.matcher(markdownStringBuilder); - ArrayList<Integer> matched = new ArrayList<>(); - while (matcher.find()) { - matched.add(matcher.start()); - } - for (int i = matched.size() - 1; i >= 0; i--) { - markdownStringBuilder.replace(matched.get(i), matched.get(i) + 1, ">"); - } - return super.processMarkdown(markdownStringBuilder.toString()); + return super.processMarkdown(Utils.fixSuperScript(markdown)); } @Override public void afterSetText(@NonNull TextView textView) { textView.setHighlightColor(Color.TRANSPARENT); - SpannableStringBuilder markdownStringBuilder = new SpannableStringBuilder(textView.getText().toString()); + SpannableStringBuilder markdownStringBuilder = new SpannableStringBuilder(textView.getText()); Pattern spoilerPattern = Pattern.compile(">![\\S\\s]+?!<"); Matcher matcher = spoilerPattern.matcher(markdownStringBuilder); int start = 0; diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/PostDetailRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/PostDetailRecyclerViewAdapter.java index e5075417..0b2c7f94 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/PostDetailRecyclerViewAdapter.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/PostDetailRecyclerViewAdapter.java @@ -74,6 +74,10 @@ import io.noties.markwon.MarkwonConfiguration; import io.noties.markwon.core.MarkwonTheme; import io.noties.markwon.ext.strikethrough.StrikethroughPlugin; import io.noties.markwon.html.HtmlPlugin; +import io.noties.markwon.html.tag.SuperScriptHandler; +import io.noties.markwon.inlineparser.BangInlineProcessor; +import io.noties.markwon.inlineparser.HtmlInlineProcessor; +import io.noties.markwon.inlineparser.MarkwonInlineParserPlugin; import io.noties.markwon.linkify.LinkifyPlugin; import io.noties.markwon.movement.MovementMethodPlugin; import io.noties.markwon.recycler.MarkwonAdapter; @@ -110,6 +114,7 @@ import ml.docilealligator.infinityforreddit.post.Post; import ml.docilealligator.infinityforreddit.post.PostPagingSource; import ml.docilealligator.infinityforreddit.utils.APIUtils; import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; +import ml.docilealligator.infinityforreddit.utils.SuperscriptInlineProcessor; import ml.docilealligator.infinityforreddit.utils.Utils; import pl.droidsonroids.gif.GifImageView; import retrofit2.Retrofit; @@ -226,28 +231,25 @@ public class PostDetailRecyclerViewAdapter extends RecyclerView.Adapter<Recycler int postSpoilerBackgroundColor = markdownColor | 0xFF000000; int linkColor = customThemeWrapper.getLinkColor(); mPostDetailMarkwon = Markwon.builder(mActivity) - .usePlugin(HtmlPlugin.create()) + .usePlugin(MarkwonInlineParserPlugin.create(plugin -> { + plugin.excludeInlineProcessor(HtmlInlineProcessor.class); + plugin.excludeInlineProcessor(BangInlineProcessor.class); + plugin.addInlineProcessor(new SuperscriptInlineProcessor()); + })) + .usePlugin(HtmlPlugin.create(plugin -> { + plugin.excludeDefaults(true).addHandler(new SuperScriptHandler()); + })) .usePlugin(new AbstractMarkwonPlugin() { @NonNull @Override public String processMarkdown(@NonNull String markdown) { - StringBuilder markdownStringBuilder = new StringBuilder(markdown); - Pattern spoilerPattern = Pattern.compile(">![\\S\\s]+?!<"); - Matcher matcher = spoilerPattern.matcher(markdownStringBuilder); - ArrayList<Integer> matched = new ArrayList<>(); - while (matcher.find()) { - matched.add(matcher.start()); - } - for (int i = matched.size() - 1; i >= 0; i--) { - markdownStringBuilder.replace(matched.get(i), matched.get(i) + 1, ">"); - } - return super.processMarkdown(markdownStringBuilder.toString()); + return super.processMarkdown(Utils.fixSuperScript(markdown)); } @Override public void afterSetText(@NonNull TextView textView) { textView.setHighlightColor(Color.TRANSPARENT); - SpannableStringBuilder markdownStringBuilder = new SpannableStringBuilder(textView.getText().toString()); + SpannableStringBuilder markdownStringBuilder = new SpannableStringBuilder(textView.getText()); Pattern spoilerPattern = Pattern.compile(">![\\S\\s]+?!<"); Matcher matcher = spoilerPattern.matcher(markdownStringBuilder); int start = 0; @@ -594,16 +596,16 @@ public class PostDetailRecyclerViewAdapter extends RecyclerView.Adapter<Recycler ((PostDetailBaseViewHolder) holder).mScoreTextView.setTextColor(mDownvotedColor); break; case 0: - ((PostDetailBaseViewHolder) holder).mUpvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - ((PostDetailBaseViewHolder) holder).mDownvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + ((PostDetailBaseViewHolder) holder).mUpvoteButton.setColorFilter(mPostIconAndInfoColor, PorterDuff.Mode.SRC_IN); + ((PostDetailBaseViewHolder) holder).mDownvoteButton.setColorFilter(mPostIconAndInfoColor, PorterDuff.Mode.SRC_IN); ((PostDetailBaseViewHolder) holder).mScoreTextView.setTextColor(mPostIconAndInfoColor); } if (mPost.isArchived()) { ((PostDetailBaseViewHolder) holder).mUpvoteButton - .setColorFilter(mVoteAndReplyUnavailableVoteButtonColor, android.graphics.PorterDuff.Mode.SRC_IN); + .setColorFilter(mVoteAndReplyUnavailableVoteButtonColor, PorterDuff.Mode.SRC_IN); ((PostDetailBaseViewHolder) holder).mDownvoteButton - .setColorFilter(mVoteAndReplyUnavailableVoteButtonColor, android.graphics.PorterDuff.Mode.SRC_IN); + .setColorFilter(mVoteAndReplyUnavailableVoteButtonColor, PorterDuff.Mode.SRC_IN); } if (mPost.isCrosspost()) { @@ -1066,9 +1068,9 @@ public class PostDetailRecyclerViewAdapter extends RecyclerView.Adapter<Recycler @Override public void onViewRecycled(@NonNull RecyclerView.ViewHolder holder) { if (holder instanceof PostDetailBaseViewHolder) { - ((PostDetailBaseViewHolder) holder).mUpvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + ((PostDetailBaseViewHolder) holder).mUpvoteButton.setColorFilter(mPostIconAndInfoColor, PorterDuff.Mode.SRC_IN); ((PostDetailBaseViewHolder) holder).mScoreTextView.setTextColor(mPostIconAndInfoColor); - ((PostDetailBaseViewHolder) holder).mDownvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + ((PostDetailBaseViewHolder) holder).mDownvoteButton.setColorFilter(mPostIconAndInfoColor, PorterDuff.Mode.SRC_IN); ((PostDetailBaseViewHolder) holder).mFlairTextView.setVisibility(View.GONE); ((PostDetailBaseViewHolder) holder).mSpoilerTextView.setVisibility(View.GONE); ((PostDetailBaseViewHolder) holder).mNSFWTextView.setVisibility(View.GONE); @@ -1265,19 +1267,19 @@ public class PostDetailRecyclerViewAdapter extends RecyclerView.Adapter<Recycler int previousVoteType = mPost.getVoteType(); String newVoteType; - mDownvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + mDownvoteButton.setColorFilter(mPostIconAndInfoColor, PorterDuff.Mode.SRC_IN); if (previousVoteType != 1) { //Not upvoted before mPost.setVoteType(1); newVoteType = APIUtils.DIR_UPVOTE; - mUpvoteButton.setColorFilter(mUpvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); + mUpvoteButton.setColorFilter(mUpvotedColor, PorterDuff.Mode.SRC_IN); mScoreTextView.setTextColor(mUpvotedColor); } else { //Upvoted before mPost.setVoteType(0); newVoteType = APIUtils.DIR_UNVOTE; - mUpvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + mUpvoteButton.setColorFilter(mPostIconAndInfoColor, PorterDuff.Mode.SRC_IN); mScoreTextView.setTextColor(mPostIconAndInfoColor); } @@ -1293,15 +1295,15 @@ public class PostDetailRecyclerViewAdapter extends RecyclerView.Adapter<Recycler public void onVoteThingSuccess() { if (newVoteType.equals(APIUtils.DIR_UPVOTE)) { mPost.setVoteType(1); - mUpvoteButton.setColorFilter(mUpvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); + mUpvoteButton.setColorFilter(mUpvotedColor, PorterDuff.Mode.SRC_IN); mScoreTextView.setTextColor(mUpvotedColor); } else { mPost.setVoteType(0); - mUpvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + mUpvoteButton.setColorFilter(mPostIconAndInfoColor, PorterDuff.Mode.SRC_IN); mScoreTextView.setTextColor(mPostIconAndInfoColor); } - mDownvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + mDownvoteButton.setColorFilter(mPostIconAndInfoColor, PorterDuff.Mode.SRC_IN); if (!mHideTheNumberOfVotes) { mScoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, mPost.getScore() + mPost.getVoteType())); @@ -1345,19 +1347,19 @@ public class PostDetailRecyclerViewAdapter extends RecyclerView.Adapter<Recycler int previousVoteType = mPost.getVoteType(); String newVoteType; - mUpvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + mUpvoteButton.setColorFilter(mPostIconAndInfoColor, PorterDuff.Mode.SRC_IN); if (previousVoteType != -1) { //Not upvoted before mPost.setVoteType(-1); newVoteType = APIUtils.DIR_DOWNVOTE; - mDownvoteButton.setColorFilter(mDownvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); + mDownvoteButton.setColorFilter(mDownvotedColor, PorterDuff.Mode.SRC_IN); mScoreTextView.setTextColor(mDownvotedColor); } else { //Upvoted before mPost.setVoteType(0); newVoteType = APIUtils.DIR_UNVOTE; - mDownvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + mDownvoteButton.setColorFilter(mPostIconAndInfoColor, PorterDuff.Mode.SRC_IN); mScoreTextView.setTextColor(mPostIconAndInfoColor); } @@ -1373,15 +1375,15 @@ public class PostDetailRecyclerViewAdapter extends RecyclerView.Adapter<Recycler public void onVoteThingSuccess() { if (newVoteType.equals(APIUtils.DIR_DOWNVOTE)) { mPost.setVoteType(-1); - mDownvoteButton.setColorFilter(mDownvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); + mDownvoteButton.setColorFilter(mDownvotedColor, PorterDuff.Mode.SRC_IN); mScoreTextView.setTextColor(mDownvotedColor); } else { mPost.setVoteType(0); - mDownvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + mDownvoteButton.setColorFilter(mPostIconAndInfoColor, PorterDuff.Mode.SRC_IN); mScoreTextView.setTextColor(mPostIconAndInfoColor); } - mUpvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + mUpvoteButton.setColorFilter(mPostIconAndInfoColor, PorterDuff.Mode.SRC_IN); if (!mHideTheNumberOfVotes) { mScoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, mPost.getScore() + mPost.getVoteType())); @@ -1553,13 +1555,13 @@ public class PostDetailRecyclerViewAdapter extends RecyclerView.Adapter<Recycler mUpvoteRatioTextView.setCompoundDrawablesWithIntrinsicBounds( upvoteRatioDrawable, null, null, null); mUpvoteRatioTextView.setTextColor(mSecondaryTextColor); - mUpvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + mUpvoteButton.setColorFilter(mPostIconAndInfoColor, PorterDuff.Mode.SRC_IN); mScoreTextView.setTextColor(mPostIconAndInfoColor); - mDownvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + mDownvoteButton.setColorFilter(mPostIconAndInfoColor, PorterDuff.Mode.SRC_IN); commentsCountTextView.setTextColor(mPostIconAndInfoColor); commentsCountTextView.setCompoundDrawablesWithIntrinsicBounds(mCommentIcon, null, null, null); - mSaveButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - mShareButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + mSaveButton.setColorFilter(mPostIconAndInfoColor, PorterDuff.Mode.SRC_IN); + mShareButton.setColorFilter(mPostIconAndInfoColor, PorterDuff.Mode.SRC_IN); } } @@ -2203,7 +2205,7 @@ public class PostDetailRecyclerViewAdapter extends RecyclerView.Adapter<Recycler mLinkTextView.setTextColor(mSecondaryTextColor); mNoPreviewPostTypeImageView.setBackgroundColor(mNoPreviewPostTypeBackgroundColor); - mNoPreviewPostTypeImageView.setColorFilter(mNoPreviewPostTypeIconTint, android.graphics.PorterDuff.Mode.SRC_IN); + mNoPreviewPostTypeImageView.setColorFilter(mNoPreviewPostTypeIconTint, PorterDuff.Mode.SRC_IN); mNoPreviewPostTypeImageView.setOnClickListener(view -> { if (mPost != null) { @@ -2348,7 +2350,7 @@ public class PostDetailRecyclerViewAdapter extends RecyclerView.Adapter<Recycler mLoadImageProgressBar.setIndeterminateTintList(ColorStateList.valueOf(mColorAccent)); mLoadImageErrorTextView.setTextColor(mPrimaryTextColor); mNoPreviewPostTypeImageView.setBackgroundColor(mNoPreviewPostTypeBackgroundColor); - mNoPreviewPostTypeImageView.setColorFilter(mNoPreviewPostTypeIconTint, android.graphics.PorterDuff.Mode.SRC_IN); + mNoPreviewPostTypeImageView.setColorFilter(mNoPreviewPostTypeIconTint, PorterDuff.Mode.SRC_IN); mImageView.setOnClickListener(view -> { Intent intent = new Intent(mActivity, ViewRedditGalleryActivity.class); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/PrivateMessagesDetailRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/PrivateMessagesDetailRecyclerViewAdapter.java index 8fe78d79..e357771b 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/PrivateMessagesDetailRecyclerViewAdapter.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/PrivateMessagesDetailRecyclerViewAdapter.java @@ -28,6 +28,10 @@ import io.noties.markwon.MarkwonConfiguration; import io.noties.markwon.core.MarkwonTheme; import io.noties.markwon.ext.strikethrough.StrikethroughPlugin; import io.noties.markwon.html.HtmlPlugin; +import io.noties.markwon.html.tag.SuperScriptHandler; +import io.noties.markwon.inlineparser.BangInlineProcessor; +import io.noties.markwon.inlineparser.HtmlInlineProcessor; +import io.noties.markwon.inlineparser.MarkwonInlineParserPlugin; import io.noties.markwon.linkify.LinkifyPlugin; import jp.wasabeef.glide.transformations.RoundedCornersTransformation; import ml.docilealligator.infinityforreddit.R; @@ -37,6 +41,7 @@ import ml.docilealligator.infinityforreddit.activities.ViewUserDetailActivity; import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; import ml.docilealligator.infinityforreddit.message.Message; import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; +import ml.docilealligator.infinityforreddit.utils.SuperscriptInlineProcessor; import ml.docilealligator.infinityforreddit.utils.Utils; public class PrivateMessagesDetailRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { @@ -66,8 +71,21 @@ public class PrivateMessagesDetailRecyclerViewAdapter extends RecyclerView.Adapt mLocale = locale; mAccountName = accountName; mMarkwon = Markwon.builder(viewPrivateMessagesActivity) - .usePlugin(HtmlPlugin.create()) + .usePlugin(MarkwonInlineParserPlugin.create(plugin -> { + plugin.excludeInlineProcessor(HtmlInlineProcessor.class); + plugin.excludeInlineProcessor(BangInlineProcessor.class); + plugin.addInlineProcessor(new SuperscriptInlineProcessor()); + })) + .usePlugin(HtmlPlugin.create(plugin -> { + plugin.excludeDefaults(true).addHandler(new SuperScriptHandler()); + })) .usePlugin(new AbstractMarkwonPlugin() { + @NonNull + @Override + public String processMarkdown(@NonNull String markdown) { + return super.processMarkdown(Utils.fixSuperScript(markdown)); + } + @Override public void configureConfiguration(@NonNull MarkwonConfiguration.Builder builder) { builder.linkResolver((view, link) -> { diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/RulesRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/RulesRecyclerViewAdapter.java index 454ecdd4..294733a1 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/RulesRecyclerViewAdapter.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/RulesRecyclerViewAdapter.java @@ -23,6 +23,10 @@ import io.noties.markwon.MarkwonConfiguration; import io.noties.markwon.core.MarkwonTheme; import io.noties.markwon.ext.strikethrough.StrikethroughPlugin; import io.noties.markwon.html.HtmlPlugin; +import io.noties.markwon.html.tag.SuperScriptHandler; +import io.noties.markwon.inlineparser.BangInlineProcessor; +import io.noties.markwon.inlineparser.HtmlInlineProcessor; +import io.noties.markwon.inlineparser.MarkwonInlineParserPlugin; import io.noties.markwon.linkify.LinkifyPlugin; import io.noties.markwon.movement.MovementMethodPlugin; import me.saket.bettermovementmethod.BetterLinkMovementMethod; @@ -31,6 +35,8 @@ import ml.docilealligator.infinityforreddit.Rule; import ml.docilealligator.infinityforreddit.activities.LinkResolverActivity; import ml.docilealligator.infinityforreddit.bottomsheetfragments.UrlMenuBottomSheetFragment; import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.utils.SuperscriptInlineProcessor; +import ml.docilealligator.infinityforreddit.utils.Utils; public class RulesRecyclerViewAdapter extends RecyclerView.Adapter<RulesRecyclerViewAdapter.RuleViewHolder> { private Markwon markwon; @@ -40,8 +46,21 @@ public class RulesRecyclerViewAdapter extends RecyclerView.Adapter<RulesRecycler public RulesRecyclerViewAdapter(AppCompatActivity activity, CustomThemeWrapper customThemeWrapper) { markwon = Markwon.builder(activity) - .usePlugin(HtmlPlugin.create()) + .usePlugin(MarkwonInlineParserPlugin.create(plugin -> { + plugin.excludeInlineProcessor(HtmlInlineProcessor.class); + plugin.excludeInlineProcessor(BangInlineProcessor.class); + plugin.addInlineProcessor(new SuperscriptInlineProcessor()); + })) + .usePlugin(HtmlPlugin.create(plugin -> { + plugin.excludeDefaults(true).addHandler(new SuperScriptHandler()); + })) .usePlugin(new AbstractMarkwonPlugin() { + @NonNull + @Override + public String processMarkdown(@NonNull String markdown) { + return super.processMarkdown(Utils.fixSuperScript(markdown)); + } + @Override public void configureConfiguration(@NonNull MarkwonConfiguration.Builder builder) { builder.linkResolver((view, link) -> { diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/CopyTextBottomSheetFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/CopyTextBottomSheetFragment.java index d8cf1fe9..4264f36a 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/CopyTextBottomSheetFragment.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/CopyTextBottomSheetFragment.java @@ -6,6 +6,7 @@ import android.content.ClipData; import android.content.ClipboardManager; import android.content.Context; import android.os.Bundle; +import android.text.Html; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -72,7 +73,8 @@ public class CopyTextBottomSheetFragment extends LandscapeExpandedRoundedBottomS } if (markdownText != null) { - markdownText = markdownText.replaceAll("<sup>", "^").replaceAll("</sup>", ""); + //markdownText = markdownText.replaceAll("<sup>", "^").replaceAll("</sup>", ""); + markdownText = markdownText.replaceAll(">", ">"); copyMarkdownTextView.setOnClickListener(view -> { showCopyDialog(markdownText); dismiss(); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/SidebarFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/SidebarFragment.java index ef3d6925..3f22a64e 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/SidebarFragment.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/SidebarFragment.java @@ -35,6 +35,10 @@ import io.noties.markwon.MarkwonConfiguration; import io.noties.markwon.core.MarkwonTheme; import io.noties.markwon.ext.strikethrough.StrikethroughPlugin; import io.noties.markwon.html.HtmlPlugin; +import io.noties.markwon.html.tag.SuperScriptHandler; +import io.noties.markwon.inlineparser.BangInlineProcessor; +import io.noties.markwon.inlineparser.HtmlInlineProcessor; +import io.noties.markwon.inlineparser.MarkwonInlineParserPlugin; import io.noties.markwon.linkify.LinkifyPlugin; import io.noties.markwon.movement.MovementMethodPlugin; import io.noties.markwon.recycler.MarkwonAdapter; @@ -54,6 +58,8 @@ import ml.docilealligator.infinityforreddit.customviews.LinearLayoutManagerBugFi import ml.docilealligator.infinityforreddit.subreddit.FetchSubredditData; import ml.docilealligator.infinityforreddit.subreddit.SubredditData; import ml.docilealligator.infinityforreddit.subreddit.SubredditViewModel; +import ml.docilealligator.infinityforreddit.utils.SuperscriptInlineProcessor; +import ml.docilealligator.infinityforreddit.utils.Utils; import retrofit2.Retrofit; public class SidebarFragment extends Fragment { @@ -104,8 +110,21 @@ public class SidebarFragment extends Fragment { markdownColor = mCustomThemeWrapper.getPrimaryTextColor(); Markwon markwon = Markwon.builder(activity) - .usePlugin(HtmlPlugin.create()) + .usePlugin(MarkwonInlineParserPlugin.create(plugin -> { + plugin.excludeInlineProcessor(HtmlInlineProcessor.class); + plugin.excludeInlineProcessor(BangInlineProcessor.class); + plugin.addInlineProcessor(new SuperscriptInlineProcessor()); + })) + .usePlugin(HtmlPlugin.create(plugin -> { + plugin.excludeDefaults(true).addHandler(new SuperScriptHandler()); + })) .usePlugin(new AbstractMarkwonPlugin() { + @NonNull + @Override + public String processMarkdown(@NonNull String markdown) { + return super.processMarkdown(Utils.fixSuperScript(markdown)); + } + @Override public void beforeSetText(@NonNull TextView textView, @NonNull Spanned markdown) { textView.setTextColor(markdownColor); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/utils/SuperscriptInlineProcessor.java b/app/src/main/java/ml/docilealligator/infinityforreddit/utils/SuperscriptInlineProcessor.java new file mode 100644 index 00000000..136a69d4 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/utils/SuperscriptInlineProcessor.java @@ -0,0 +1,32 @@ +package ml.docilealligator.infinityforreddit.utils; + +import androidx.annotation.Nullable; + +import org.commonmark.node.HtmlInline; +import org.commonmark.node.Node; + +import java.util.regex.Pattern; + +import io.noties.markwon.inlineparser.InlineProcessor; + +public class SuperscriptInlineProcessor extends InlineProcessor { + private static final Pattern HTML_TAG = Pattern.compile("</?sup>", Pattern.CASE_INSENSITIVE); + + @Override + public char specialCharacter() { + return '<'; + } + + @Nullable + @Override + protected Node parse() { + String m = match(HTML_TAG); + if (m != null) { + HtmlInline node = new HtmlInline(); + node.setLiteral(m); + return node; + } else { + return null; + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/utils/Utils.java b/app/src/main/java/ml/docilealligator/infinityforreddit/utils/Utils.java index ad2b7405..8e5e73c1 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/utils/Utils.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/utils/Utils.java @@ -65,6 +65,7 @@ public class Utils { .replaceAll("((?<=[\\s])|^)/[rRuU]/[\\w-]+/{0,1}", "[$0](https://www.reddit.com$0)") .replaceAll("((?<=[\\s])|^)[rRuU]/[\\w-]+/{0,1}", "[$0](https://www.reddit.com/$0)") .replaceAll("\\^{2,}", "^") + .replaceAll("(?:>!)(\\n?[\\S\\h]+?\\n?[\\S\\h]+\\n?!<)", ">!$1") // html entity remains escaped inside an inline block .replaceAll("(^|^ *|\\n *)#(?!($|\\s|#))", "$0 ") .replaceAll("(^|^ *|\\n *)##(?!($|\\s|#))", "$0 ") .replaceAll("(^|^ *|\\n *)###(?!($|\\s|#))", "$0 ") @@ -72,10 +73,13 @@ public class Utils { .replaceAll("(^|^ *|\\n *)#####(?!($|\\s|#))", "$0 ") .replaceAll("(^|^ *|\\n *)######(?!($|\\s|#))", "$0 ")); - return fixSuperScript(regexed); + //return fixSuperScript(regexed); + // We don't want to fix super scripts here because we need the original markdown later for editing posts + return regexed.toString(); } - private static String fixSuperScript(StringBuilder regexed) { + public static String fixSuperScript(String regexedMarkdown) { + StringBuilder regexed = new StringBuilder(regexedMarkdown); boolean hasBracket = false; int nCarets = 0; for (int i = 0; i < regexed.length(); i++) { |