Remove RxMarkdown dependency from main module

This commit is contained in:
Stefan Niedermann 2021-01-04 10:19:16 +01:00
parent b7ca7d38df
commit 12fa0b4d9a
9 changed files with 110 additions and 438 deletions

View file

@ -68,8 +68,6 @@ dependencies {
// Markdown
implementation project(path: ':markdown')
implementation 'com.yydcdut:markdown-processor:0.1.3'
implementation 'com.yydcdut:rxmarkdown-wrapper:0.1.3'
// Android X
implementation "androidx.appcompat:appcompat:1.2.0"

View file

@ -216,72 +216,71 @@ public abstract class BaseNoteFragment extends BrandedFragment implements Catego
*/
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_cancel:
if (originalNote == null) {
db.deleteNoteAndSync(ssoAccount, note.getId());
} else {
db.updateNoteAndSync(ssoAccount, localAccount, originalNote, null, null);
}
listener.close();
return true;
case R.id.menu_delete:
int itemId = item.getItemId();
if (itemId == R.id.menu_cancel) {
if (originalNote == null) {
db.deleteNoteAndSync(ssoAccount, note.getId());
listener.close();
return true;
case R.id.menu_favorite:
db.toggleFavorite(ssoAccount, note, null);
listener.onNoteUpdated(note);
prepareFavoriteOption(item);
return true;
case R.id.menu_category:
showCategorySelector();
return true;
case R.id.menu_title:
showEditTitleDialog();
return true;
case R.id.menu_move:
AccountPickerDialogFragment.newInstance(note.getAccountId()).show(requireActivity().getSupportFragmentManager(), BaseNoteFragment.class.getSimpleName());
return true;
case R.id.menu_share:
ShareUtil.openShareDialog(requireContext(), note.getTitle(), note.getContent());
return false;
case MENU_ID_PIN:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
ShortcutManager shortcutManager = requireActivity().getSystemService(ShortcutManager.class);
} else {
db.updateNoteAndSync(ssoAccount, localAccount, originalNote, null, null);
}
listener.close();
return true;
} else if (itemId == R.id.menu_delete) {
db.deleteNoteAndSync(ssoAccount, note.getId());
listener.close();
return true;
} else if (itemId == R.id.menu_favorite) {
db.toggleFavorite(ssoAccount, note, null);
listener.onNoteUpdated(note);
prepareFavoriteOption(item);
return true;
} else if (itemId == R.id.menu_category) {
showCategorySelector();
return true;
} else if (itemId == R.id.menu_title) {
showEditTitleDialog();
return true;
} else if (itemId == R.id.menu_move) {
AccountPickerDialogFragment.newInstance(note.getAccountId()).show(requireActivity().getSupportFragmentManager(), BaseNoteFragment.class.getSimpleName());
return true;
} else if (itemId == R.id.menu_share) {
ShareUtil.openShareDialog(requireContext(), note.getTitle(), note.getContent());
return false;
} else if (itemId == MENU_ID_PIN) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
ShortcutManager shortcutManager = requireActivity().getSystemService(ShortcutManager.class);
if (shortcutManager != null) {
if (shortcutManager.isRequestPinShortcutSupported()) {
Intent intent = new Intent(getActivity(), EditNoteActivity.class);
intent.putExtra(EditNoteActivity.PARAM_NOTE_ID, note.getId());
intent.setAction(ACTION_SHORTCUT);
if (shortcutManager != null) {
if (shortcutManager.isRequestPinShortcutSupported()) {
Intent intent = new Intent(getActivity(), EditNoteActivity.class);
intent.putExtra(EditNoteActivity.PARAM_NOTE_ID, note.getId());
intent.setAction(ACTION_SHORTCUT);
ShortcutInfo pinShortcutInfo = new ShortcutInfo.Builder(getActivity(), note.getId() + "")
.setShortLabel(note.getTitle())
.setIcon(Icon.createWithResource(requireActivity().getApplicationContext(), note.isFavorite() ? R.drawable.ic_star_yellow_24dp : R.drawable.ic_star_grey_ccc_24dp))
.setIntent(intent)
.build();
ShortcutInfo pinShortcutInfo = new ShortcutInfo.Builder(getActivity(), note.getId() + "")
.setShortLabel(note.getTitle())
.setIcon(Icon.createWithResource(requireActivity().getApplicationContext(), note.isFavorite() ? R.drawable.ic_star_yellow_24dp : R.drawable.ic_star_grey_ccc_24dp))
.setIntent(intent)
.build();
Intent pinnedShortcutCallbackIntent =
shortcutManager.createShortcutResultIntent(pinShortcutInfo);
Intent pinnedShortcutCallbackIntent =
shortcutManager.createShortcutResultIntent(pinShortcutInfo);
PendingIntent successCallback = PendingIntent.getBroadcast(getActivity(), /* request code */ 0,
pinnedShortcutCallbackIntent, /* flags */ 0);
PendingIntent successCallback = PendingIntent.getBroadcast(getActivity(), /* request code */ 0,
pinnedShortcutCallbackIntent, /* flags */ 0);
shortcutManager.requestPinShortcut(pinShortcutInfo,
successCallback.getIntentSender());
} else {
Log.i(TAG, "RequestPinShortcut is not supported");
}
shortcutManager.requestPinShortcut(pinShortcutInfo,
successCallback.getIntentSender());
} else {
Log.e(TAG, "ShortcutManager is null");
Log.i(TAG, "RequestPinShortcut is not supported");
}
} else {
Log.e(TAG, "ShortcutManager is null");
}
}
return true;
default:
return super.onOptionsItemSelected(item);
return true;
}
return super.onOptionsItemSelected(item);
}
public void onCloseNote() {

View file

@ -61,9 +61,7 @@ public class EditNoteActivity extends LockedActivity implements BaseNoteFragment
}
setSupportActionBar(binding.toolbar);
if (!(fragment instanceof NoteReadonlyFragment)) {
binding.toolbar.setOnClickListener((v) -> fragment.showEditTitleDialog());
}
binding.toolbar.setOnClickListener((v) -> fragment.showEditTitleDialog());
}
@Override

View file

@ -60,23 +60,6 @@ public class NoteEditFragment extends SearchableBaseNoteFragment {
};
private TextWatcher textWatcher;
public static NoteEditFragment newInstance(long accountId, long noteId) {
NoteEditFragment f = new NoteEditFragment();
Bundle b = new Bundle();
b.putLong(PARAM_NOTE_ID, noteId);
b.putLong(PARAM_ACCOUNT_ID, accountId);
f.setArguments(b);
return f;
}
public static NoteEditFragment newInstanceWithNewNote(CloudNote newNote) {
NoteEditFragment f = new NoteEditFragment();
Bundle b = new Bundle();
b.putSerializable(PARAM_NEWNOTE, newNote);
f.setArguments(b);
return f;
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@ -246,4 +229,21 @@ public class NoteEditFragment extends SearchableBaseNoteFragment {
super.applyBrand(mainColor, textColor);
binding.editContent.setSearchColor(mainColor);
}
public static BaseNoteFragment newInstance(long accountId, long noteId) {
final BaseNoteFragment fragment = new NoteEditFragment();
final Bundle args = new Bundle();
args.putLong(PARAM_NOTE_ID, noteId);
args.putLong(PARAM_ACCOUNT_ID, accountId);
fragment.setArguments(args);
return fragment;
}
public static BaseNoteFragment newInstanceWithNewNote(CloudNote newNote) {
final BaseNoteFragment fragment = new NoteEditFragment();
final Bundle args = new Bundle();
args.putSerializable(PARAM_NEWNOTE, newNote);
fragment.setArguments(args);
return fragment;
}
}

View file

@ -39,16 +39,7 @@ public class NotePreviewFragment extends SearchableBaseNoteFragment implements O
private String changedText;
private FragmentNotePreviewBinding binding;
public static NotePreviewFragment newInstance(long accountId, long noteId) {
NotePreviewFragment f = new NotePreviewFragment();
Bundle b = new Bundle();
b.putLong(PARAM_NOTE_ID, noteId);
b.putLong(PARAM_ACCOUNT_ID, accountId);
f.setArguments(b);
return f;
}
protected FragmentNotePreviewBinding binding;
@Override
public void onPrepareOptionsMenu(@NonNull Menu menu) {
@ -89,10 +80,22 @@ public class NotePreviewFragment extends SearchableBaseNoteFragment implements O
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
// .setOnLinkClickCallback((view, link) -> {
// if (NoteLinksUtils.isNoteLink(link)) {
// long noteRemoteId = NoteLinksUtils.extractNoteRemoteId(link);
// long noteLocalId = db.getLocalIdByRemoteId(this.note.getAccountId(), noteRemoteId);
// Intent intent = new Intent(requireActivity().getApplicationContext(), EditNoteActivity.class);
// intent.putExtra(EditNoteActivity.PARAM_NOTE_ID, noteLocalId);
// startActivity(intent);
// } else {
// Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(link));
// startActivity(browserIntent);
// }
// })
final TextProcessorChain chain = defaultTextProcessorChain(note);
binding.singleNoteContent.setMarkdownString(chain.apply(note.getContent()));
changedText = note.getContent();
binding.singleNoteContent.setMovementMethod(LinkMovementMethod.getInstance());
changedText = note.getContent();
db = NotesDatabase.getInstance(requireContext());
binding.swiperefreshlayout.setOnRefreshListener(this);
@ -156,4 +159,13 @@ public class NotePreviewFragment extends SearchableBaseNoteFragment implements O
chain.add(new NoteLinksProcessor(db.getRemoteIds(note.getAccountId())));
return chain;
}
public static BaseNoteFragment newInstance(long accountId, long noteId) {
final BaseNoteFragment fragment = new NotePreviewFragment();
final Bundle args = new Bundle();
args.putLong(PARAM_NOTE_ID, noteId);
args.putLong(PARAM_ACCOUNT_ID, accountId);
fragment.setArguments(args);
return fragment;
}
}

View file

@ -1,55 +1,18 @@
package it.niedermann.owncloud.notes.edit;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Typeface;
import android.net.Uri;
import android.os.Bundle;
import android.text.Layout;
import android.text.SpannableString;
import android.text.method.LinkMovementMethod;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ScrollView;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.preference.PreferenceManager;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.yydcdut.markdown.MarkdownProcessor;
import com.yydcdut.markdown.syntax.text.TextFactory;
import it.niedermann.owncloud.notes.R;
import it.niedermann.owncloud.notes.databinding.FragmentNotePreviewBinding;
import it.niedermann.owncloud.notes.shared.model.ISyncCallback;
import it.niedermann.owncloud.notes.persistence.NotesDatabase;
import it.niedermann.owncloud.notes.shared.util.MarkDownUtil;
import it.niedermann.owncloud.notes.shared.util.NoteLinksUtils;
import static androidx.core.view.ViewCompat.isAttachedToWindow;
import static it.niedermann.owncloud.notes.shared.util.DisplayUtils.searchAndColor;
import static it.niedermann.owncloud.notes.shared.util.MarkDownUtil.parseCompat;
import static it.niedermann.owncloud.notes.shared.util.NoteUtil.getFontSizeFromPreferences;
public class NoteReadonlyFragment extends SearchableBaseNoteFragment {
private MarkdownProcessor markdownProcessor;
private FragmentNotePreviewBinding binding;
public static NoteReadonlyFragment newInstance(String content) {
NoteReadonlyFragment f = new NoteReadonlyFragment();
Bundle b = new Bundle();
b.putString(PARAM_CONTENT, content);
f.setArguments(b);
return f;
}
public class NoteReadonlyFragment extends NotePreviewFragment {
@Override
public void onPrepareOptionsMenu(@NonNull Menu menu) {
@ -62,78 +25,23 @@ public class NoteReadonlyFragment extends SearchableBaseNoteFragment {
menu.findItem(R.id.menu_share).setVisible(false);
menu.findItem(R.id.menu_move).setVisible(false);
menu.findItem(R.id.menu_category).setVisible(false);
menu.findItem(R.id.menu_title).setVisible(false);
if (menu.findItem(MENU_ID_PIN) != null)
menu.findItem(MENU_ID_PIN).setVisible(false);
}
@Override
public ScrollView getScrollView() {
return binding.scrollView;
}
@Override
protected FloatingActionButton getSearchNextButton() {
return binding.searchNext;
}
@Override
protected FloatingActionButton getSearchPrevButton() {
return binding.searchPrev;
}
@Override
protected Layout getLayout() {
binding.singleNoteContent.onPreDraw();
return binding.singleNoteContent.getLayout();
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup
container, @Nullable Bundle savedInstanceState) {
binding = FragmentNotePreviewBinding.inflate(inflater, container, false);
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
binding.singleNoteContent.setEnabled(false);
binding.swiperefreshlayout.setEnabled(false);
return binding.getRoot();
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
markdownProcessor = new MarkdownProcessor(requireActivity());
markdownProcessor.factory(TextFactory.create());
markdownProcessor.config(
MarkDownUtil.getMarkDownConfiguration(binding.singleNoteContent.getContext())
.setOnLinkClickCallback((view, link) -> {
if (NoteLinksUtils.isNoteLink(link)) {
long noteRemoteId = NoteLinksUtils.extractNoteRemoteId(link);
long noteLocalId = db.getLocalIdByRemoteId(this.note.getAccountId(), noteRemoteId);
Intent intent = new Intent(requireActivity().getApplicationContext(), EditNoteActivity.class);
intent.putExtra(EditNoteActivity.PARAM_NOTE_ID, noteLocalId);
startActivity(intent);
} else {
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(link));
startActivity(browserIntent);
}
})
.build());
try {
binding.singleNoteContent.setText(parseCompat(markdownProcessor, note.getContent()));
onResume();
} catch (StringIndexOutOfBoundsException e) {
// Workaround for RxMarkdown: https://github.com/stefan-niedermann/nextcloud-notes/issues/668
binding.singleNoteContent.setText(note.getContent());
Toast.makeText(binding.singleNoteContent.getContext(), R.string.could_not_load_preview_two_digit_numbered_list, Toast.LENGTH_LONG).show();
e.printStackTrace();
}
binding.singleNoteContent.setMovementMethod(LinkMovementMethod.getInstance());
db = NotesDatabase.getInstance(getActivity());
binding.swiperefreshlayout.setEnabled(false);
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(requireActivity().getApplicationContext());
binding.singleNoteContent.setTextSize(TypedValue.COMPLEX_UNIT_PX, getFontSizeFromPreferences(requireContext(), sp));
if (sp.getBoolean(getString(R.string.pref_key_font), false)) {
binding.singleNoteContent.setTypeface(Typeface.MONOSPACE);
}
public void showEditTitleDialog() {
// Do nothing
}
@Override
@ -146,21 +54,11 @@ public class NoteReadonlyFragment extends SearchableBaseNoteFragment {
// Do nothing
}
@Override
protected void colorWithText(@NonNull String newText, @Nullable Integer current, int mainColor, int textColor) {
if ((binding != null) && isAttachedToWindow(binding.singleNoteContent)) {
binding.singleNoteContent.setText(searchAndColor(new SpannableString(parseCompat(markdownProcessor, getContent())), newText, requireContext(), current, mainColor, textColor), TextView.BufferType.SPANNABLE);
}
}
@Override
protected String getContent() {
return note.getContent();
}
@Override
public void applyBrand(int mainColor, int textColor) {
super.applyBrand(mainColor, textColor);
binding.singleNoteContent.setHighlightColor(getTextHighlightBackgroundColor(requireContext(), mainColor, colorPrimary, colorAccent));
public static BaseNoteFragment newInstance(String content) {
final BaseNoteFragment fragment = new NoteReadonlyFragment();
final Bundle args = new Bundle();
args.putString(PARAM_CONTENT, content);
fragment.setArguments(args);
return fragment;
}
}

View file

@ -1,124 +0,0 @@
package it.niedermann.owncloud.notes.shared.util;
import android.content.Context;
import android.graphics.Color;
import android.text.Spanned;
import android.text.TextUtils;
import androidx.annotation.NonNull;
import androidx.core.content.res.ResourcesCompat;
import com.yydcdut.markdown.MarkdownConfiguration;
import com.yydcdut.markdown.MarkdownConfiguration.Builder;
import com.yydcdut.markdown.MarkdownProcessor;
import com.yydcdut.markdown.span.MDImageSpan;
import com.yydcdut.markdown.theme.ThemeDefault;
import com.yydcdut.markdown.theme.ThemeSonsOfObsidian;
import it.niedermann.owncloud.notes.NotesApplication;
import it.niedermann.owncloud.notes.R;
/**
* Created by stefan on 07.12.16.
*/
@SuppressWarnings("WeakerAccess")
public class MarkDownUtil {
private static final String TAG = MarkDownUtil.class.getSimpleName();
public static final String CHECKBOX_UNCHECKED_MINUS = "- [ ]";
public static final String CHECKBOX_UNCHECKED_MINUS_TRAILING_SPACE = CHECKBOX_UNCHECKED_MINUS + " ";
public static final String CHECKBOX_UNCHECKED_STAR = "* [ ]";
public static final String CHECKBOX_UNCHECKED_STAR_TRAILING_SPACE = CHECKBOX_UNCHECKED_STAR + " ";
public static final String CHECKBOX_CHECKED_MINUS = "- [x]";
public static final String CHECKBOX_CHECKED_STAR = "* [x]";
private static final String MD_IMAGE_WITH_EMPTY_DESCRIPTION = "![](";
private static final String MD_IMAGE_WITH_SPACE_DESCRIPTION = "![ ](";
private static final String[] MD_IMAGE_WITH_EMPTY_DESCRIPTION_ARRAY = new String[]{MD_IMAGE_WITH_EMPTY_DESCRIPTION};
private static final String[] MD_IMAGE_WITH_SPACE_DESCRIPTION_ARRAY = new String[]{MD_IMAGE_WITH_SPACE_DESCRIPTION};
/**
* Ensures every instance of RxMD uses the same configuration
*
* @param context Context
* @return RxMDConfiguration
*/
public static Builder getMarkDownConfiguration(Context context) {
return getMarkDownConfiguration(context, NotesApplication.isDarkThemeActive(context));
}
public static Builder getMarkDownConfiguration(Context context, Boolean darkTheme) {
return new MarkdownConfiguration.Builder(context)
.setUnOrderListColor(ResourcesCompat.getColor(context.getResources(),
darkTheme ? R.color.widget_fg_dark_theme : R.color.widget_fg_default, null))
.setHeader2RelativeSize(1.35f)
.setHeader3RelativeSize(1.25f)
.setHeader4RelativeSize(1.15f)
.setHeader5RelativeSize(1.1f)
.setHeader6RelativeSize(1.05f)
.setHorizontalRulesHeight(2)
.setCodeBgColor(darkTheme ? ResourcesCompat.getColor(context.getResources(), R.color.fg_default_high, null) : Color.LTGRAY)
.setTheme(darkTheme ? new ThemeSonsOfObsidian() : new ThemeDefault())
.setTodoColor(ResourcesCompat.getColor(context.getResources(),
darkTheme ? R.color.widget_fg_dark_theme : R.color.widget_fg_default, null))
.setTodoDoneColor(ResourcesCompat.getColor(context.getResources(),
darkTheme ? R.color.widget_fg_dark_theme : R.color.widget_fg_default, null))
.setLinkFontColor(ResourcesCompat.getColor(context.getResources(), R.color.defaultBrand, null))
.setDefaultImageSize(400, 300);
}
/**
* This is a compatibility-method that provides workarounds for several bugs in RxMarkdown
* <p>
* https://github.com/stefan-niedermann/nextcloud-notes/issues/772
*
* @param markdownProcessor RxMarkdown MarkdownProcessor instance
* @param text CharSequence that should be parsed
* @return the processed text but with several workarounds for Bugs in RxMarkdown
*/
@NonNull
public static CharSequence parseCompat(@NonNull final MarkdownProcessor markdownProcessor, CharSequence text) {
if (TextUtils.isEmpty(text)) {
return "";
}
while (TextUtils.indexOf(text, MD_IMAGE_WITH_EMPTY_DESCRIPTION) >= 0) {
text = TextUtils.replace(text, MD_IMAGE_WITH_EMPTY_DESCRIPTION_ARRAY, MD_IMAGE_WITH_SPACE_DESCRIPTION_ARRAY);
}
return markdownProcessor.parse(text);
}
public static boolean containsImageSpan(@NonNull CharSequence text) {
return ((Spanned) text).getSpans(0, text.length(), MDImageSpan.class).length > 0;
}
public static boolean lineStartsWithCheckbox(@NonNull String line) {
return lineStartsWithCheckbox(line, true) || lineStartsWithCheckbox(line, false);
}
public static boolean lineStartsWithCheckbox(@NonNull String line, boolean starAsLeadingCharacter) {
return starAsLeadingCharacter
? line.startsWith(CHECKBOX_UNCHECKED_STAR) || line.startsWith(CHECKBOX_CHECKED_STAR)
: line.startsWith(CHECKBOX_UNCHECKED_MINUS) || line.startsWith(CHECKBOX_CHECKED_MINUS);
}
public static int getStartOfLine(@NonNull CharSequence s, int cursorPosition) {
int startOfLine = cursorPosition;
while (startOfLine > 0 && s.charAt(startOfLine - 1) != '\n') {
startOfLine--;
}
return startOfLine;
}
public static int getEndOfLine(@NonNull CharSequence s, int cursorPosition) {
int nextLinebreak = s.toString().indexOf('\n', cursorPosition);
if (nextLinebreak > -1) {
return nextLinebreak;
}
return cursorPosition;
}
}

View file

@ -33,6 +33,7 @@
android:textColor="@color/fg_default"
android:textIsSelectable="true"
android:theme="@style/textViewStyle"
android:enabled="false"
tools:text="@tools:sample/lorem/random" />
</ScrollView>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>

View file

@ -1,110 +0,0 @@
package it.niedermann.owncloud.notes.shared.util;
import junit.framework.TestCase;
import java.util.HashMap;
import java.util.Map;
/**
* Tests the NoteUtil
* Created by stefan on 06.10.15.
*/
public class MarkDownUtilTest extends TestCase {
public void testGetStartOfLine() {
//language=md
StringBuilder test = new StringBuilder(
"# Test-Note\n" + // line start 0
"\n" + // line start 12
"- [ ] this is a test note\n" + // line start 13
"- [x] test\n" + // line start 39
"[test](https://example.com)\n" + // line start 50
"\n" + // line start 77
"\n" // line start 78
);
for (int i = 0; i < test.length(); i++) {
int startOfLine = MarkDownUtil.getStartOfLine(test, i);
if (i <= 11) {
assertEquals(0, startOfLine);
} else if (i <= 12) {
assertEquals(12, startOfLine);
} else if (i <= 38) {
assertEquals(13, startOfLine);
} else if (i <= 49) {
assertEquals(39, startOfLine);
} else if (i <= 77) {
assertEquals(50, startOfLine);
} else if (i <= 78) {
assertEquals(78, startOfLine);
} else if (i <= 79) {
assertEquals(79, startOfLine);
}
}
}
public void testGetEndOfLine() {
//language=md
StringBuilder test = new StringBuilder(
"# Test-Note\n" + // line 0 - 11
"\n" + // line 12 - 12
"- [ ] this is a test note\n" + // line 13 - 38
"- [x] test\n" + // line start 39 - 49
"[test](https://example.com)\n" + // line 50 - 77
"\n" + // line 77 - 78
"\n" // line 78 - 79
);
for (int i = 0; i < test.length(); i++) {
int endOfLine = MarkDownUtil.getEndOfLine(test, i);
if (i <= 11) {
assertEquals(11, endOfLine);
} else if (i <= 12) {
assertEquals(12, endOfLine);
} else if (i <= 38) {
assertEquals(38, endOfLine);
} else if (i <= 49) {
assertEquals(49, endOfLine);
} else if (i <= 77) {
assertEquals(77, endOfLine);
} else if (i <= 78) {
assertEquals(78, endOfLine);
} else if (i <= 79) {
assertEquals(79, endOfLine);
}
}
}
public void testLineStartsWithCheckbox() {
Map<String, Boolean> lines = new HashMap<>();
lines.put("- [ ] ", true);
lines.put("- [x] ", true);
lines.put("* [ ] ", true);
lines.put("* [x] ", true);
lines.put("- [ ]", true);
lines.put("- [x]", true);
lines.put("* [ ]", true);
lines.put("* [x]", true);
lines.put("-[ ] ", false);
lines.put("-[x] ", false);
lines.put("*[ ] ", false);
lines.put("*[x] ", false);
lines.put("-[ ]", false);
lines.put("-[x]", false);
lines.put("*[ ]", false);
lines.put("*[x]", false);
lines.put("- [] ", false);
lines.put("* [] ", false);
lines.put("- []", false);
lines.put("* []", false);
lines.put("-[] ", false);
lines.put("*[] ", false);
lines.put("-[]", false);
lines.put("*[]", false);
lines.forEach((key,value) -> assertEquals(value, (Boolean) MarkDownUtil.lineStartsWithCheckbox(key)));
}
}