Detects markdown + disable them by default

This commit is contained in:
Thomas 2023-09-15 11:04:42 +02:00
parent ec50416a8b
commit cf37e16ce5
3 changed files with 115 additions and 60 deletions

View file

@ -138,6 +138,7 @@ public class Status implements Serializable, Cloneable {
public boolean spoilerChecked = false;
public Filter filteredByApp;
public transient Spannable contentSpan;
public transient Spannable contentMarkdownSpan;
public transient Spannable contentSpoilerSpan;
public transient Spannable contentTranslateSpan;
public transient MathJaxView mathJaxView;

View file

@ -152,72 +152,28 @@ public class SpannableHelper {
} else {
initialContent = new SpannableString(text);
}
boolean markdownSupport = sharedpreferences.getBoolean(context.getString(R.string.SET_MARKDOWN_SUPPORT), true);
boolean markdownSupport = sharedpreferences.getBoolean(context.getString(R.string.SET_MARKDOWN_SUPPORT), false);
//Get all links
SpannableStringBuilder content;
SpannableStringBuilder markdownContent;
if (markdownSupport && convertMarkdown) {
MarkdownConverter markdownConverter = new MarkdownConverter();
markdownConverter.markdownItems = new ArrayList<>();
int next;
int position = 0;
for (int i = 0; i < initialContent.length(); i = next) {
// find the next span transition
next = initialContent.nextSpanTransition(i, initialContent.length(), URLSpan.class);
MarkdownConverter.MarkdownItem markdownItem = new MarkdownConverter.MarkdownItem();
markdownItem.code = initialContent.subSequence(i, next).toString();
markdownItem.position = position;
// get all spans in this range
URLSpan[] spans = initialContent.getSpans(i, next, URLSpan.class);
if (spans != null && spans.length > 0) {
markdownItem.urlSpan = spans[0];
}
if (markdownItem.code.trim().length() > 0) {
markdownConverter.markdownItems.add(markdownItem);
position++;
}
}
final Markwon markwon = Markwon.builder(context)
.usePlugin(TablePlugin.create(context))
.usePlugin(SoftBreakAddsNewLinePlugin.create())
.usePlugin(SyntaxHighlightPlugin.create(new Prism4j(new MySuperGrammerLocator()), Prism4jThemeDefault.create()))
.usePlugin(StrikethroughPlugin.create())
.usePlugin(MarkwonInlineParserPlugin.create())
.usePlugin(new AbstractMarkwonPlugin() {
@Override
public void configure(@NonNull Registry registry) {
registry.require(MarkwonInlineParserPlugin.class, plugin -> plugin.factoryBuilder()
.excludeInlineProcessor(HtmlInlineProcessor.class));
}
})
.build();
final Spanned markdown = markwon.toMarkdown(initialContent.toString());
content = new SpannableStringBuilder(markdown);
position = 0;
for (MarkdownConverter.MarkdownItem markdownItem : markdownConverter.markdownItems) {
String sb = Pattern.compile("\\A[\\p{L}0-9_]").matcher(markdownItem.code).find() ? "\\b" : "";
String eb = Pattern.compile("[\\p{L}0-9_]\\z").matcher(markdownItem.code).find() ? "\\b" : "\\B";
Pattern p = Pattern.compile(sb + "(" + Pattern.quote(markdownItem.code) + ")" + eb, Pattern.UNICODE_CASE);
Matcher m = p.matcher(content);
int fetchPosition = 1;
while (m.find()) {
int regexPosition = markdownItem.regexPosition(markdownConverter.markdownItems);
if (regexPosition == fetchPosition) {
content.setSpan(markdownItem.urlSpan, m.start(), m.end(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
}
fetchPosition++;
}
position++;
}
content = transformMarkDown(context, initialContent);
} else {
content = new SpannableStringBuilder(initialContent);
boolean isMarkdown = isMarkDown(content.toString());
if (isMarkdown && status != null) {
markdownContent = transformMarkDown(context, initialContent);
status.contentMarkdownSpan = convert(context, markdownContent, text, status, account, announcement, viewWeakReference, mentions, callback);
}
}
return convert(context, content, text, status, account, announcement, viewWeakReference, mentions, callback);
}
private static Spannable convert(Context context, SpannableStringBuilder content, String text,
Status status, Account account, Announcement announcement,
WeakReference<View> viewWeakReference, List<Mention> mentions, Status.Callback callback) {
SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(context);
URLSpan[] urls = content.getSpans(0, (content.length() - 1), URLSpan.class);
//Loop through links
for (URLSpan span : urls) {
@ -938,4 +894,102 @@ public class SpannableHelper {
return trimSpannable(new SpannableStringBuilder(content));
}
private static boolean isMarkDown(String content) {
Pattern pattern1 = Pattern.compile("(#\\s)(.*)");
Pattern pattern2 = Pattern.compile("(#{2}\\s)(.*)");
Pattern pattern3 = Pattern.compile("(#{3}\\s)(.*)");
Pattern pattern4 = Pattern.compile("(#{4}\\s)(.*)");
Pattern pattern5 = Pattern.compile("(#{5}\\s)(.*)");
Pattern pattern6 = Pattern.compile("(#{6}\\s)(.*)");
Pattern pattern7 = Pattern.compile("([*_])+(\\S+)([*_])+");
Pattern pattern8 = Pattern.compile("(\\[.*])(\\((http)s?(://).*\\))");
Pattern pattern9 = Pattern.compile("(^(\\W)(\\s)(.*)$?)+");
Pattern pattern10 = Pattern.compile("(^(\\d+\\.)(\\s)(.*)$?)+");
Pattern pattern11 = Pattern.compile("(^(>{1})(\\s)(.*)$?)+");
Pattern pattern12 = Pattern.compile("(`)(.*)(`)");
Pattern pattern13 = Pattern.compile("(```)(.*)(```)");
Matcher matcher1 = pattern1.matcher(content);
Matcher matcher2 = pattern2.matcher(content);
Matcher matcher3 = pattern3.matcher(content);
Matcher matcher4 = pattern4.matcher(content);
Matcher matcher5 = pattern5.matcher(content);
Matcher matcher6 = pattern6.matcher(content);
Matcher matcher7 = pattern7.matcher(content);
Matcher matcher8 = pattern8.matcher(content);
Matcher matcher9 = pattern9.matcher(content);
Matcher matcher10 = pattern10.matcher(content);
Matcher matcher11 = pattern11.matcher(content);
Matcher matcher12 = pattern12.matcher(content);
Matcher matcher13 = pattern13.matcher(content);
return matcher1.find() || matcher2.find() || matcher3.find() || matcher4.find() || matcher5.find()
|| matcher6.find() || matcher7.find() || matcher8.find() || matcher9.find() || matcher10.find()
|| matcher11.find() || matcher12.find() || matcher13.find();
}
private static SpannableStringBuilder transformMarkDown(Context context, SpannableString initialContent) {
MarkdownConverter markdownConverter = new MarkdownConverter();
markdownConverter.markdownItems = new ArrayList<>();
int next;
int position = 0;
for (int i = 0; i < initialContent.length(); i = next) {
// find the next span transition
next = initialContent.nextSpanTransition(i, initialContent.length(), URLSpan.class);
MarkdownConverter.MarkdownItem markdownItem = new MarkdownConverter.MarkdownItem();
markdownItem.code = initialContent.subSequence(i, next).toString();
markdownItem.position = position;
// get all spans in this range
URLSpan[] spans = initialContent.getSpans(i, next, URLSpan.class);
if (spans != null && spans.length > 0) {
markdownItem.urlSpan = spans[0];
}
if (markdownItem.code.trim().length() > 0) {
markdownConverter.markdownItems.add(markdownItem);
position++;
}
}
final Markwon markwon = Markwon.builder(context)
.usePlugin(TablePlugin.create(context))
.usePlugin(SoftBreakAddsNewLinePlugin.create())
.usePlugin(SyntaxHighlightPlugin.create(new Prism4j(new MySuperGrammerLocator()), Prism4jThemeDefault.create()))
.usePlugin(StrikethroughPlugin.create())
.usePlugin(MarkwonInlineParserPlugin.create())
.usePlugin(new AbstractMarkwonPlugin() {
@Override
public void configure(@NonNull Registry registry) {
registry.require(MarkwonInlineParserPlugin.class, plugin -> plugin.factoryBuilder()
.excludeInlineProcessor(HtmlInlineProcessor.class));
}
})
.build();
final Spanned markdown = markwon.toMarkdown(initialContent.toString());
SpannableStringBuilder content = new SpannableStringBuilder(markdown);
position = 0;
for (MarkdownConverter.MarkdownItem markdownItem : markdownConverter.markdownItems) {
String sb = Pattern.compile("\\A[\\p{L}0-9_]").matcher(markdownItem.code).find() ? "\\b" : "";
String eb = Pattern.compile("[\\p{L}0-9_]\\z").matcher(markdownItem.code).find() ? "\\b" : "\\B";
Pattern p = Pattern.compile(sb + "(" + Pattern.quote(markdownItem.code) + ")" + eb, Pattern.UNICODE_CASE);
Matcher m = p.matcher(content);
int fetchPosition = 1;
while (m.find()) {
int regexPosition = markdownItem.regexPosition(markdownConverter.markdownItems);
if (regexPosition == fetchPosition) {
content.setSpan(markdownItem.urlSpan, m.start(), m.end(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
}
fetchPosition++;
}
position++;
}
return content;
}
}

View file

@ -51,7 +51,7 @@
app:title="@string/boost_original_date" />
<SwitchPreferenceCompat
android:defaultValue="true"
android:defaultValue="false"
app:iconSpaceReserved="false"
app:key="@string/SET_MARKDOWN_SUPPORT"
app:singleLineTitle="false"