diff --git a/app/build.gradle b/app/build.gradle index 1779752f..cb019542 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -153,6 +153,7 @@ dependencies { implementation "io.noties.markwon:linkify:$markwonVersion" 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 a9275779..5e1db8be 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/CommentActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/CommentActivity.java @@ -50,6 +50,8 @@ import io.noties.markwon.Markwon; 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.AutolinkInlineProcessor; import io.noties.markwon.inlineparser.BangInlineProcessor; import io.noties.markwon.inlineparser.HtmlInlineProcessor; @@ -71,7 +73,7 @@ import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; import ml.docilealligator.infinityforreddit.customviews.LinearLayoutManagerBugFixed; import ml.docilealligator.infinityforreddit.events.SwitchAccountEvent; import ml.docilealligator.infinityforreddit.markdown.SpoilerParserPlugin; -import ml.docilealligator.infinityforreddit.markdown.SuperscriptPlugin; +import ml.docilealligator.infinityforreddit.markdown.SuperscriptInlineProcessor; import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; import ml.docilealligator.infinityforreddit.utils.Utils; import retrofit2.Retrofit; @@ -171,13 +173,16 @@ public class CommentActivity extends BaseActivity implements UploadImageEnabledA plugin.excludeInlineProcessor(AutolinkInlineProcessor.class); plugin.excludeInlineProcessor(HtmlInlineProcessor.class); plugin.excludeInlineProcessor(BangInlineProcessor.class); + plugin.addInlineProcessor(new SuperscriptInlineProcessor()); + })) + .usePlugin(HtmlPlugin.create(plugin -> { + plugin.excludeDefaults(true).addHandler(new SuperScriptHandler()); })) - .usePlugin(SuperscriptPlugin.create()) .usePlugin(new AbstractMarkwonPlugin() { @NonNull @Override public String processMarkdown(@NonNull String markdown) { - return super.processMarkdown(markdown); + return Utils.fixSuperScript(markdown); } @Override @@ -224,13 +229,16 @@ public class CommentActivity extends BaseActivity implements UploadImageEnabledA plugin.excludeInlineProcessor(AutolinkInlineProcessor.class); plugin.excludeInlineProcessor(HtmlInlineProcessor.class); plugin.excludeInlineProcessor(BangInlineProcessor.class); + plugin.addInlineProcessor(new SuperscriptInlineProcessor()); + })) + .usePlugin(HtmlPlugin.create(plugin -> { + plugin.excludeDefaults(true).addHandler(new SuperScriptHandler()); })) - .usePlugin(SuperscriptPlugin.create()) .usePlugin(new AbstractMarkwonPlugin() { @NonNull @Override public String processMarkdown(@NonNull String markdown) { - return super.processMarkdown(markdown); + return Utils.fixSuperScript(markdown); } @Override 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 52c053c7..ed6aaeeb 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/FullMarkdownActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/FullMarkdownActivity.java @@ -3,10 +3,14 @@ package ml.docilealligator.infinityforreddit.activities; import android.app.Activity; import android.content.Intent; import android.content.SharedPreferences; +import android.graphics.Color; import android.net.Uri; import android.os.Build; import android.os.Bundle; +import android.text.SpannableStringBuilder; import android.text.Spanned; +import android.text.TextPaint; +import android.text.style.ClickableSpan; import android.text.util.Linkify; import android.view.Menu; import android.view.MenuItem; @@ -29,6 +33,9 @@ import org.commonmark.ext.gfm.tables.TableBlock; import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.Subscribe; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + import javax.inject.Inject; import javax.inject.Named; @@ -39,6 +46,8 @@ import io.noties.markwon.Markwon; 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.AutolinkInlineProcessor; import io.noties.markwon.inlineparser.BangInlineProcessor; import io.noties.markwon.inlineparser.HtmlInlineProcessor; @@ -54,8 +63,10 @@ import ml.docilealligator.infinityforreddit.customviews.LinearLayoutManagerBugFi import ml.docilealligator.infinityforreddit.customviews.MarkwonLinearLayoutManager; import ml.docilealligator.infinityforreddit.events.SwitchAccountEvent; import ml.docilealligator.infinityforreddit.markdown.SpoilerParserPlugin; -import ml.docilealligator.infinityforreddit.markdown.SuperscriptPlugin; +import ml.docilealligator.infinityforreddit.markdown.SpoilerSpan; import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; +import ml.docilealligator.infinityforreddit.markdown.SuperscriptInlineProcessor; +import ml.docilealligator.infinityforreddit.utils.Utils; public class FullMarkdownActivity extends BaseActivity { @@ -132,13 +143,16 @@ public class FullMarkdownActivity extends BaseActivity { plugin.excludeInlineProcessor(AutolinkInlineProcessor.class); plugin.excludeInlineProcessor(HtmlInlineProcessor.class); plugin.excludeInlineProcessor(BangInlineProcessor.class); + plugin.addInlineProcessor(new SuperscriptInlineProcessor()); + })) + .usePlugin(HtmlPlugin.create(plugin -> { + plugin.excludeDefaults(true).addHandler(new SuperScriptHandler()); })) - .usePlugin(SuperscriptPlugin.create()) .usePlugin(new AbstractMarkwonPlugin() { @NonNull @Override public String processMarkdown(@NonNull String markdown) { - return super.processMarkdown(markdown); + return Utils.fixSuperScript(markdown); } @Override 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 04619b48..19c5f5a2 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/WikiActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/WikiActivity.java @@ -44,6 +44,8 @@ import io.noties.markwon.Markwon; 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.AutolinkInlineProcessor; import io.noties.markwon.inlineparser.BangInlineProcessor; import io.noties.markwon.inlineparser.HtmlInlineProcessor; @@ -63,7 +65,7 @@ import ml.docilealligator.infinityforreddit.customviews.LinearLayoutManagerBugFi import ml.docilealligator.infinityforreddit.customviews.MarkwonLinearLayoutManager; import ml.docilealligator.infinityforreddit.events.SwitchAccountEvent; import ml.docilealligator.infinityforreddit.markdown.SpoilerParserPlugin; -import ml.docilealligator.infinityforreddit.markdown.SuperscriptPlugin; +import ml.docilealligator.infinityforreddit.markdown.SuperscriptInlineProcessor; import ml.docilealligator.infinityforreddit.utils.JSONUtils; import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; import ml.docilealligator.infinityforreddit.utils.Utils; @@ -165,13 +167,16 @@ public class WikiActivity extends BaseActivity { plugin.excludeInlineProcessor(AutolinkInlineProcessor.class); plugin.excludeInlineProcessor(HtmlInlineProcessor.class); plugin.excludeInlineProcessor(BangInlineProcessor.class); + plugin.addInlineProcessor(new SuperscriptInlineProcessor()); + })) + .usePlugin(HtmlPlugin.create(plugin -> { + plugin.excludeDefaults(true).addHandler(new SuperScriptHandler()); })) - .usePlugin(SuperscriptPlugin.create()) .usePlugin(new AbstractMarkwonPlugin() { @NonNull @Override public String processMarkdown(@NonNull String markdown) { - return super.processMarkdown(markdown); + return Utils.fixSuperScript(markdown); } @Override 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 199cd48a..9665fb85 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/CommentsListingRecyclerViewAdapter.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/CommentsListingRecyclerViewAdapter.java @@ -3,9 +3,14 @@ package ml.docilealligator.infinityforreddit.adapters; 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; +import android.text.Spanned; +import android.text.TextPaint; +import android.text.style.ClickableSpan; import android.text.util.Linkify; import android.view.LayoutInflater; import android.view.View; @@ -27,6 +32,8 @@ import androidx.recyclerview.widget.ItemTouchHelper; import androidx.recyclerview.widget.RecyclerView; import java.util.Locale; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import butterknife.BindView; import butterknife.ButterKnife; @@ -35,6 +42,8 @@ import io.noties.markwon.Markwon; 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.AutolinkInlineProcessor; import io.noties.markwon.inlineparser.BangInlineProcessor; import io.noties.markwon.inlineparser.HtmlInlineProcessor; @@ -56,9 +65,10 @@ import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; import ml.docilealligator.infinityforreddit.customviews.CommentIndentationView; import ml.docilealligator.infinityforreddit.customviews.SpoilerOnClickTextView; import ml.docilealligator.infinityforreddit.markdown.SpoilerParserPlugin; -import ml.docilealligator.infinityforreddit.markdown.SuperscriptPlugin; +import ml.docilealligator.infinityforreddit.markdown.SpoilerSpan; import ml.docilealligator.infinityforreddit.utils.APIUtils; import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; +import ml.docilealligator.infinityforreddit.markdown.SuperscriptInlineProcessor; import ml.docilealligator.infinityforreddit.utils.Utils; import retrofit2.Retrofit; @@ -118,13 +128,16 @@ public class CommentsListingRecyclerViewAdapter extends PagedListAdapter { + plugin.excludeDefaults(true).addHandler(new SuperScriptHandler()); })) - .usePlugin(SuperscriptPlugin.create()) .usePlugin(new AbstractMarkwonPlugin() { @NonNull @Override public String processMarkdown(@NonNull String markdown) { - return super.processMarkdown(markdown); + return Utils.fixSuperScript(markdown); } @Override 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 ac7e46ef..64139e8c 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/CommentsRecyclerViewAdapter.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/CommentsRecyclerViewAdapter.java @@ -42,7 +42,10 @@ import io.noties.markwon.Markwon; 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.AutolinkInlineProcessor; +import io.noties.markwon.inlineparser.BackslashInlineProcessor; import io.noties.markwon.inlineparser.BangInlineProcessor; import io.noties.markwon.inlineparser.HtmlInlineProcessor; import io.noties.markwon.inlineparser.MarkwonInlineParserPlugin; @@ -65,7 +68,7 @@ import ml.docilealligator.infinityforreddit.customviews.CommentIndentationView; import ml.docilealligator.infinityforreddit.customviews.SpoilerOnClickTextView; import ml.docilealligator.infinityforreddit.fragments.ViewPostDetailFragment; import ml.docilealligator.infinityforreddit.markdown.SpoilerParserPlugin; -import ml.docilealligator.infinityforreddit.markdown.SuperscriptPlugin; +import ml.docilealligator.infinityforreddit.markdown.SuperscriptInlineProcessor; import ml.docilealligator.infinityforreddit.post.Post; import ml.docilealligator.infinityforreddit.utils.APIUtils; import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; @@ -164,13 +167,16 @@ public class CommentsRecyclerViewAdapter extends RecyclerView.Adapter { + plugin.excludeDefaults(true).addHandler(new SuperScriptHandler()); })) - .usePlugin(SuperscriptPlugin.create()) .usePlugin(new AbstractMarkwonPlugin() { @NonNull @Override public String processMarkdown(@NonNull String markdown) { - return super.processMarkdown(markdown); + return Utils.fixSuperScript(markdown); } @Override 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 0eba99f3..38886715 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/MessageRecyclerViewAdapter.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/MessageRecyclerViewAdapter.java @@ -3,8 +3,13 @@ package ml.docilealligator.infinityforreddit.adapters; import android.content.Context; import android.content.Intent; import android.content.res.ColorStateList; +import android.graphics.Color; import android.net.Uri; +import android.text.SpannableStringBuilder; +import android.text.Spanned; +import android.text.TextPaint; import android.text.method.LinkMovementMethod; +import android.text.style.ClickableSpan; import android.text.util.Linkify; import android.view.LayoutInflater; import android.view.View; @@ -19,6 +24,8 @@ import androidx.recyclerview.widget.DiffUtil; import androidx.recyclerview.widget.RecyclerView; import java.util.ArrayList; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import butterknife.BindView; import butterknife.ButterKnife; @@ -27,6 +34,8 @@ import io.noties.markwon.Markwon; 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.AutolinkInlineProcessor; import io.noties.markwon.inlineparser.BangInlineProcessor; import io.noties.markwon.inlineparser.HtmlInlineProcessor; @@ -39,10 +48,12 @@ import ml.docilealligator.infinityforreddit.activities.ViewPrivateMessagesActivi import ml.docilealligator.infinityforreddit.activities.ViewUserDetailActivity; import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; import ml.docilealligator.infinityforreddit.markdown.SpoilerParserPlugin; -import ml.docilealligator.infinityforreddit.markdown.SuperscriptPlugin; +import ml.docilealligator.infinityforreddit.markdown.SpoilerSpan; import ml.docilealligator.infinityforreddit.message.FetchMessage; import ml.docilealligator.infinityforreddit.message.Message; import ml.docilealligator.infinityforreddit.message.ReadMessage; +import ml.docilealligator.infinityforreddit.markdown.SuperscriptInlineProcessor; +import ml.docilealligator.infinityforreddit.utils.Utils; import retrofit2.Retrofit; public class MessageRecyclerViewAdapter extends PagedListAdapter { @@ -101,13 +112,16 @@ public class MessageRecyclerViewAdapter extends PagedListAdapter { + plugin.excludeDefaults(true).addHandler(new SuperScriptHandler()); })) - .usePlugin(SuperscriptPlugin.create()) .usePlugin(new AbstractMarkwonPlugin() { @NonNull @Override public String processMarkdown(@NonNull String markdown) { - return super.processMarkdown(markdown); + return Utils.fixSuperScript(markdown); } @Override 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 4157db56..7eeff046 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/PostDetailRecyclerViewAdapter.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/PostDetailRecyclerViewAdapter.java @@ -67,6 +67,8 @@ import io.noties.markwon.Markwon; 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.AutolinkInlineProcessor; import io.noties.markwon.inlineparser.BangInlineProcessor; import io.noties.markwon.inlineparser.HtmlInlineProcessor; @@ -105,7 +107,7 @@ import ml.docilealligator.infinityforreddit.customviews.LinearLayoutManagerBugFi import ml.docilealligator.infinityforreddit.customviews.MarkwonLinearLayoutManager; import ml.docilealligator.infinityforreddit.fragments.ViewPostDetailFragment; import ml.docilealligator.infinityforreddit.markdown.SpoilerParserPlugin; -import ml.docilealligator.infinityforreddit.markdown.SuperscriptPlugin; +import ml.docilealligator.infinityforreddit.markdown.SuperscriptInlineProcessor; import ml.docilealligator.infinityforreddit.post.Post; import ml.docilealligator.infinityforreddit.post.PostPagingSource; import ml.docilealligator.infinityforreddit.utils.APIUtils; @@ -229,13 +231,16 @@ public class PostDetailRecyclerViewAdapter extends RecyclerView.Adapter { + plugin.excludeDefaults(true).addHandler(new SuperScriptHandler()); })) - .usePlugin(SuperscriptPlugin.create()) .usePlugin(new AbstractMarkwonPlugin() { @NonNull @Override public String processMarkdown(@NonNull String markdown) { - return super.processMarkdown(markdown); + return Utils.fixSuperScript(markdown); } @Override 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 8d785c4c..065bab4f 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/PrivateMessagesDetailRecyclerViewAdapter.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/PrivateMessagesDetailRecyclerViewAdapter.java @@ -27,6 +27,8 @@ import io.noties.markwon.Markwon; 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.AutolinkInlineProcessor; import io.noties.markwon.inlineparser.BangInlineProcessor; import io.noties.markwon.inlineparser.HtmlInlineProcessor; @@ -38,9 +40,9 @@ import ml.docilealligator.infinityforreddit.activities.LinkResolverActivity; import ml.docilealligator.infinityforreddit.activities.ViewPrivateMessagesActivity; import ml.docilealligator.infinityforreddit.activities.ViewUserDetailActivity; import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; -import ml.docilealligator.infinityforreddit.markdown.SuperscriptPlugin; import ml.docilealligator.infinityforreddit.message.Message; import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; +import ml.docilealligator.infinityforreddit.markdown.SuperscriptInlineProcessor; import ml.docilealligator.infinityforreddit.utils.Utils; public class PrivateMessagesDetailRecyclerViewAdapter extends RecyclerView.Adapter { @@ -74,13 +76,16 @@ public class PrivateMessagesDetailRecyclerViewAdapter extends RecyclerView.Adapt plugin.excludeInlineProcessor(AutolinkInlineProcessor.class); plugin.excludeInlineProcessor(HtmlInlineProcessor.class); plugin.excludeInlineProcessor(BangInlineProcessor.class); + plugin.addInlineProcessor(new SuperscriptInlineProcessor()); + })) + .usePlugin(HtmlPlugin.create(plugin -> { + plugin.excludeDefaults(true).addHandler(new SuperScriptHandler()); })) - .usePlugin(SuperscriptPlugin.create()) .usePlugin(new AbstractMarkwonPlugin() { @NonNull @Override public String processMarkdown(@NonNull String markdown) { - return super.processMarkdown(markdown); + return Utils.fixSuperScript(markdown); } @Override 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 a5da4780..49826453 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/RulesRecyclerViewAdapter.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/RulesRecyclerViewAdapter.java @@ -22,6 +22,8 @@ import io.noties.markwon.Markwon; 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.AutolinkInlineProcessor; import io.noties.markwon.inlineparser.BangInlineProcessor; import io.noties.markwon.inlineparser.HtmlInlineProcessor; @@ -34,7 +36,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.markdown.SuperscriptPlugin; +import ml.docilealligator.infinityforreddit.markdown.SuperscriptInlineProcessor; +import ml.docilealligator.infinityforreddit.utils.Utils; public class RulesRecyclerViewAdapter extends RecyclerView.Adapter { private Markwon markwon; @@ -48,13 +51,16 @@ public class RulesRecyclerViewAdapter extends RecyclerView.Adapter { + plugin.excludeDefaults(true).addHandler(new SuperScriptHandler()); })) - .usePlugin(SuperscriptPlugin.create()) .usePlugin(new AbstractMarkwonPlugin() { @NonNull @Override public String processMarkdown(@NonNull String markdown) { - return super.processMarkdown(markdown); + return Utils.fixSuperScript(markdown); } @Override 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 474eaed4..05ba567d 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/SidebarFragment.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/SidebarFragment.java @@ -34,6 +34,8 @@ import io.noties.markwon.Markwon; 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.AutolinkInlineProcessor; import io.noties.markwon.inlineparser.BangInlineProcessor; import io.noties.markwon.inlineparser.HtmlInlineProcessor; @@ -54,10 +56,11 @@ import ml.docilealligator.infinityforreddit.bottomsheetfragments.CopyTextBottomS import ml.docilealligator.infinityforreddit.bottomsheetfragments.UrlMenuBottomSheetFragment; import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; import ml.docilealligator.infinityforreddit.customviews.LinearLayoutManagerBugFixed; -import ml.docilealligator.infinityforreddit.markdown.SuperscriptPlugin; import ml.docilealligator.infinityforreddit.subreddit.FetchSubredditData; import ml.docilealligator.infinityforreddit.subreddit.SubredditData; import ml.docilealligator.infinityforreddit.subreddit.SubredditViewModel; +import ml.docilealligator.infinityforreddit.markdown.SuperscriptInlineProcessor; +import ml.docilealligator.infinityforreddit.utils.Utils; import retrofit2.Retrofit; public class SidebarFragment extends Fragment { @@ -112,13 +115,16 @@ public class SidebarFragment extends Fragment { plugin.excludeInlineProcessor(AutolinkInlineProcessor.class); plugin.excludeInlineProcessor(HtmlInlineProcessor.class); plugin.excludeInlineProcessor(BangInlineProcessor.class); + plugin.addInlineProcessor(new SuperscriptInlineProcessor()); + })) + .usePlugin(HtmlPlugin.create(plugin -> { + plugin.excludeDefaults(true).addHandler(new SuperScriptHandler()); })) - .usePlugin(SuperscriptPlugin.create()) .usePlugin(new AbstractMarkwonPlugin() { @NonNull @Override public String processMarkdown(@NonNull String markdown) { - return super.processMarkdown(markdown); + return Utils.fixSuperScript(markdown); } @Override diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/ViewRedditGalleryImageOrGifFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/ViewRedditGalleryImageOrGifFragment.java index 6265cf79..cc3110ea 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/ViewRedditGalleryImageOrGifFragment.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/ViewRedditGalleryImageOrGifFragment.java @@ -5,6 +5,7 @@ import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.graphics.Bitmap; +import android.graphics.Color; import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.Build; @@ -309,6 +310,7 @@ public class ViewRedditGalleryImageOrGifFragment extends Fragment { return true; }); captionUrlTextView.setVisibility(View.VISIBLE); + captionUrlTextView.setHighlightColor(Color.TRANSPARENT); } } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/markdown/SpoilerParserPlugin.java b/app/src/main/java/ml/docilealligator/infinityforreddit/markdown/SpoilerParserPlugin.java index 85dc2be5..5200c535 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/markdown/SpoilerParserPlugin.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/markdown/SpoilerParserPlugin.java @@ -70,19 +70,19 @@ public class SpoilerParserPlugin extends AbstractMarkwonPlugin { @Override public void afterSetText(@NonNull TextView textView) { + textView.setHighlightColor(Color.TRANSPARENT); + if (!textHasSpoiler || textView.getText().length() < 5) { firstSpoilerStart = 0; return; } - textView.setHighlightColor(Color.TRANSPARENT); - SpannableStringBuilder markdownStringBuilder = new SpannableStringBuilder(textView.getText()); ArrayList> spoilers = parse(markdownStringBuilder, firstSpoilerStart); firstSpoilerStart = 0; + textHasSpoiler = false; // Since PostDetail can contain multiple TextViews, we do this here if (spoilers.size() == 0) { - textHasSpoiler = false; return; } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/markdown/SuperScriptSpan.java b/app/src/main/java/ml/docilealligator/infinityforreddit/markdown/SuperScriptSpan.java deleted file mode 100644 index 015cf8df..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/markdown/SuperScriptSpan.java +++ /dev/null @@ -1,25 +0,0 @@ -package ml.docilealligator.infinityforreddit.markdown; - -import android.text.TextPaint; -import android.text.style.MetricAffectingSpan; - -import androidx.annotation.NonNull; - -public class SuperScriptSpan extends MetricAffectingSpan { - private static final float SCRIPT_DEF_TEXT_SIZE_RATIO = .75F; - - @Override - public void updateDrawState(TextPaint tp) { - apply(tp); - } - - @Override - public void updateMeasureState(@NonNull TextPaint tp) { - apply(tp); - } - - private void apply(TextPaint paint) { - paint.setTextSize(paint.getTextSize() * SCRIPT_DEF_TEXT_SIZE_RATIO); - paint.baselineShift += (int) (paint.ascent() / 2); - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/markdown/Superscript.java b/app/src/main/java/ml/docilealligator/infinityforreddit/markdown/Superscript.java deleted file mode 100644 index c45a3f3c..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/markdown/Superscript.java +++ /dev/null @@ -1,31 +0,0 @@ -package ml.docilealligator.infinityforreddit.markdown; - -import org.commonmark.node.CustomNode; -import org.commonmark.node.Visitor; - -public class Superscript extends CustomNode { - private String literal; - private int level; - - @Override - public void accept(Visitor visitor) { - visitor.visit(this); - } - - public String getLiteral() { - return literal; - } - - public void setLiteral(String literal) { - this.literal = literal; - } - - public int getLevel() { - return level; - } - - public void setLevel(int level) { - this.level = level; - } - -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/markdown/SuperscriptInlineProcessor.java b/app/src/main/java/ml/docilealligator/infinityforreddit/markdown/SuperscriptInlineProcessor.java new file mode 100644 index 00000000..93c9ab10 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/markdown/SuperscriptInlineProcessor.java @@ -0,0 +1,32 @@ +package ml.docilealligator.infinityforreddit.markdown; + +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("^", 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/markdown/SuperscriptParser.java b/app/src/main/java/ml/docilealligator/infinityforreddit/markdown/SuperscriptParser.java deleted file mode 100644 index 10c6dcfd..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/markdown/SuperscriptParser.java +++ /dev/null @@ -1,116 +0,0 @@ -package ml.docilealligator.infinityforreddit.markdown; - -import androidx.annotation.Nullable; - -import org.commonmark.node.Node; - -import io.noties.markwon.inlineparser.InlineProcessor; - -public class SuperscriptParser extends InlineProcessor { - - private int level = 0; - - @Override - public char specialCharacter() { - return '^'; - } - - @Nullable - @Override - protected Node parse() { - Node node = parseSuperscript(level); - if (node != null) { - return nestSuperscriptNodes(node); - } - level = 0; - return null; - } - - private Node nestSuperscriptNodes(Node node) { - if (block.getLastChild() instanceof Superscript - && peek() != '^') { - var current = block.getLastChild(); - current.appendChild(node); - Node tmp = null; - while (true) { - tmp = current; - current = current.getPrevious(); - if (current instanceof Superscript) { - current.appendChild(tmp); - } else { - break; - } - } - level = 0; - return tmp; - } else { - level++; - return node; - } - } - - // Hopefully we've handled edge cases - private Superscript parseSuperscript(int level) { - int start = index; - int length = input.length(); - int caret_pos = -1; - int nCarets = 0; - int new_lines = 0; - boolean hasBracket = false; - for (int i = start; i < length; i++) { - char currentChar = input.charAt(i); - if (currentChar == '\n') { - new_lines++; - if (new_lines > 0 && nCarets > 0 || hasBracket) { - break; - } - } else if ((i + 1) < length - && nCarets == 0 - && !hasBracket - && !(i > 0 && input.charAt(i - 1) == '\\') - && currentChar == '^' - && !Character.isWhitespace(input.charAt(i + 1))) { - if (input.charAt(i + 1) == '(') { - hasBracket = true; - } - caret_pos = i; - nCarets++; - } else if (nCarets > 0) { - if (hasBracket - && (i > 0) - && currentChar == ')' - && input.charAt(i - 1) != '\\') { - index = i + 1; - Superscript node = new Superscript(); - node.setLiteral(input.substring(caret_pos + 2, i)); - node.setLevel(level); - return node; - } else if (!hasBracket && Character.isWhitespace(currentChar)) { - index = i; - Superscript node = new Superscript(); - node.setLiteral(input.substring(caret_pos + 1, i)); - node.setLevel(level); - return node; - } else if (!hasBracket && (i == length - 1)) { - index = i + 1; - Superscript node = new Superscript(); - node.setLiteral(input.substring(caret_pos + 1, i + 1)); - node.setLevel(level); - return node; - } else if ((i + 1) < length - && (i > 0) - && currentChar == '^' - && input.charAt(i - 1) != '\\' - && !Character.isWhitespace(input.charAt(i + 1))) { - index = i; - Superscript node = new Superscript(); - node.setLiteral(input.substring(caret_pos + 1, i)); - node.setLevel(level); - return node; - } - } - } - return null; - } -} - diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/markdown/SuperscriptPlugin.java b/app/src/main/java/ml/docilealligator/infinityforreddit/markdown/SuperscriptPlugin.java deleted file mode 100644 index 7e220bb3..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/markdown/SuperscriptPlugin.java +++ /dev/null @@ -1,38 +0,0 @@ -package ml.docilealligator.infinityforreddit.markdown; - -import androidx.annotation.NonNull; - -import io.noties.markwon.AbstractMarkwonPlugin; -import io.noties.markwon.MarkwonVisitor; -import io.noties.markwon.inlineparser.MarkwonInlineParserPlugin; - -public class SuperscriptPlugin extends AbstractMarkwonPlugin { - - SuperscriptPlugin() { - - } - - public static SuperscriptPlugin create() { - return new SuperscriptPlugin(); - } - - @Override - public void configure(@NonNull Registry registry) { - registry.require(MarkwonInlineParserPlugin.class, plugin -> - plugin.factoryBuilder().addInlineProcessor(new SuperscriptParser())); - } - - @Override - public void configureVisitor(@NonNull MarkwonVisitor.Builder builder) { - builder.on(Superscript.class, (visitor, superscript) -> { - if (superscript.getLevel() < 29) { // Arbitrary nesting limit - final int start = visitor.length(); - visitor.builder().append(superscript.getLiteral()); - visitor.visitChildren(superscript); - visitor.setSpans(start, new SuperScriptSpan()); - } else { - visitor.clear(); - } - }); - } -} 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 3f08b372..68af76f7 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/utils/Utils.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/utils/Utils.java @@ -59,8 +59,7 @@ public final class Utils { private static final long DAY_MILLIS = 24 * HOUR_MILLIS; private static final long MONTH_MILLIS = 30 * DAY_MILLIS; private static final long YEAR_MILLIS = 12 * MONTH_MILLIS; - - public static final Pattern[] REGEX_PATTERN = { + private static final Pattern[] REGEX_PATTERNS = { Pattern.compile("((?<=[\\s])|^)/[rRuU]/[\\w-]+/{0,1}"), Pattern.compile("((?<=[\\s])|^)[rRuU]/[\\w-]+/{0,1}"), Pattern.compile("\\^{2,}"), @@ -77,42 +76,102 @@ public final class Utils { }; public static String modifyMarkdown(String markdown) { - String regexed = REGEX_PATTERN[0].matcher(markdown).replaceAll("[$0](https://www.reddit.com$0)"); - regexed = REGEX_PATTERN[1].matcher(regexed).replaceAll("[$0](https://www.reddit.com/$0)"); - regexed = REGEX_PATTERN[2].matcher(regexed).replaceAll("^"); - regexed = REGEX_PATTERN[3].matcher(regexed).replaceAll("$0 "); - regexed = REGEX_PATTERN[4].matcher(regexed).replaceAll("$0 "); - regexed = REGEX_PATTERN[5].matcher(regexed).replaceAll("$0 "); - regexed = REGEX_PATTERN[6].matcher(regexed).replaceAll("$0 "); - regexed = REGEX_PATTERN[7].matcher(regexed).replaceAll("$0 "); - regexed = REGEX_PATTERN[8].matcher(regexed).replaceAll("$0 "); + String regexed = REGEX_PATTERNS[0].matcher(markdown).replaceAll("[$0](https://www.reddit.com$0)"); + regexed = REGEX_PATTERNS[1].matcher(regexed).replaceAll("[$0](https://www.reddit.com/$0)"); + regexed = REGEX_PATTERNS[2].matcher(regexed).replaceAll("^"); + regexed = REGEX_PATTERNS[3].matcher(regexed).replaceAll("$0 "); + regexed = REGEX_PATTERNS[4].matcher(regexed).replaceAll("$0 "); + regexed = REGEX_PATTERNS[5].matcher(regexed).replaceAll("$0 "); + regexed = REGEX_PATTERNS[6].matcher(regexed).replaceAll("$0 "); + regexed = REGEX_PATTERNS[7].matcher(regexed).replaceAll("$0 "); + regexed = REGEX_PATTERNS[8].matcher(regexed).replaceAll("$0 "); + //return fixSuperScript(regexed); + // We don't want to fix super scripts here because we need the original markdown later for editing posts return regexed; } + public static String fixSuperScript(String regexedMarkdown) { + StringBuilder regexed = new StringBuilder(regexedMarkdown); + boolean hasBracket = false; + int nCarets = 0; + int new_lines = 0; + for (int i = 0; i < regexed.length(); i++) { + char currentChar = regexed.charAt(i); + if (hasBracket && currentChar == '\n') { + new_lines++; + if (new_lines > 1) { + hasBracket = false; + nCarets = 0; + new_lines = 0; + } + } else if (currentChar == '^') { + if (!(i > 0 && regexed.charAt(i - 1) == '\\')) { + if (nCarets == 0 && i < regexed.length() - 1 && regexed.charAt(i + 1) == '(') { + regexed.replace(i, i + 2, ""); + hasBracket = true; + } else { + regexed.replace(i, i + 1, ""); + } + nCarets++; + } + } else if (hasBracket && currentChar == ')') { + if (i > 0 && regexed.charAt(i - 1) == '\\') { + hasBracket = false; + nCarets--; + continue; + } + hasBracket = false; + regexed.replace(i, i + 1, ""); + nCarets--; + } else if (!hasBracket && currentChar == '\n') { + for (int j = 0; j < nCarets; j++) { + regexed.insert(i, ""); + i += 6; + } + nCarets = 0; + } else if (!hasBracket && Character.isWhitespace(currentChar)) { + for (int j = 0; j < nCarets; j++) { + regexed.insert(i, ""); + i += 6; + } + nCarets = 0; + } else { + new_lines = 0; + } + } + if (!hasBracket) { + for (int j = 0; j < nCarets; j++) { + regexed.append(""); + } + } + + return regexed.toString(); + } + public static String parseInlineGifInComments(String markdown) { StringBuilder markdownStringBuilder = new StringBuilder(markdown); - Pattern inlineGifPattern = REGEX_PATTERN[9]; + Pattern inlineGifPattern = REGEX_PATTERNS[9]; Matcher matcher = inlineGifPattern.matcher(markdownStringBuilder); while (matcher.find()) { markdownStringBuilder.replace(matcher.start(), matcher.end(), "[gif](https://i.giphy.com/media/" + markdownStringBuilder.substring(matcher.start() + "![gif](giphy|".length(), matcher.end() - 1) + "/giphy.mp4)"); matcher = inlineGifPattern.matcher(markdownStringBuilder); } - Pattern inlineGifPattern2 = REGEX_PATTERN[10]; + Pattern inlineGifPattern2 = REGEX_PATTERNS[10]; Matcher matcher2 = inlineGifPattern2.matcher(markdownStringBuilder); while (matcher2.find()) { markdownStringBuilder.replace(matcher2.start(), matcher2.end(), "[gif](https://i.giphy.com/media/" + markdownStringBuilder.substring(matcher2.start() + "![gif](giphy|".length(), matcher2.end() - "|downsized\\)".length() + 1) + "/giphy.mp4)"); matcher2 = inlineGifPattern2.matcher(markdownStringBuilder); } - Pattern inlineGifPattern3 = REGEX_PATTERN[11]; + Pattern inlineGifPattern3 = REGEX_PATTERNS[11]; Matcher matcher3 = inlineGifPattern3.matcher(markdownStringBuilder); while (matcher3.find()) { markdownStringBuilder.replace(matcher3.start(), matcher3.end(), "[gif](https://reddit-meta-production.s3.amazonaws.com/public/fortnitebr/emotes/snoomoji_emotes/" + markdownStringBuilder.substring( - matcher3.start() + "![gif](emote|".length(), matcher3.end() - 1).replace('|', '/') + ".gif)"); + matcher3.start() + "![gif](emote|".length(), matcher3.end() - 1).replace('|', '/') + ".gif)"); matcher3 = inlineGifPattern3.matcher(markdownStringBuilder); } @@ -132,7 +191,7 @@ public final class Utils { i--; } while (i >= 0 && Character.isWhitespace(source.charAt(i))); - return source.subSequence(0, i+1); + return source.subSequence(0, i + 1); } public static String getFormattedTime(Locale locale, long time, String pattern) { @@ -141,7 +200,7 @@ public final class Utils { return new SimpleDateFormat(pattern, locale).format(postTimeCalendar.getTime()); } - public static String getElapsedTime(Context context, long time) { + public static String getElapsedTime(Context context, long time) { long now = System.currentTimeMillis(); long diff = now - time; @@ -205,7 +264,8 @@ public final class Utils { return NETWORK_TYPE_CELLULAR; } } - } catch (SecurityException ignore) {} + } catch (SecurityException ignore) { + } return NETWORK_TYPE_OTHER; } else { boolean isWifi = false; @@ -320,7 +380,7 @@ public final class Utils { public static void uploadImageToReddit(Context context, Executor executor, Retrofit oauthRetrofit, Retrofit uploadMediaRetrofit, String accessToken, EditText editText, CoordinatorLayout coordinatorLayout, Uri imageUri, - ArrayListuploadedImages) { + ArrayList uploadedImages) { Toast.makeText(context, R.string.uploading_image, Toast.LENGTH_SHORT).show(); Handler handler = new Handler(); executor.execute(() -> { diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index a0b0243f..3eac8f66 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -74,6 +74,8 @@ ?attr/font_default @style/MaterialAlertDialogTitleTextStyle + @style/MaterialAlertDialogPositiveButtonStyle + @style/MaterialAlertDialogNegativeButtonStyle