Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/stefan-niedermann/nextcloud-notes.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md2
-rw-r--r--app/build.gradle12
-rw-r--r--app/src/main/java/it/niedermann/owncloud/notes/AppendToNoteActivity.java8
-rw-r--r--app/src/main/java/it/niedermann/owncloud/notes/LockedActivity.java2
-rw-r--r--app/src/main/java/it/niedermann/owncloud/notes/NotesApplication.java2
-rw-r--r--app/src/main/java/it/niedermann/owncloud/notes/edit/EditNoteActivity.java19
-rw-r--r--app/src/main/java/it/niedermann/owncloud/notes/importaccount/ImportAccountViewModel.java2
-rw-r--r--app/src/main/java/it/niedermann/owncloud/notes/main/MainActivity.java17
-rw-r--r--app/src/main/java/it/niedermann/owncloud/notes/main/items/NoteViewHolder.java8
-rw-r--r--app/src/main/java/it/niedermann/owncloud/notes/persistence/NotesDatabase.java5
-rw-r--r--app/src/main/java/it/niedermann/owncloud/notes/shared/model/CloudNote.java0
-rw-r--r--app/src/main/java/it/niedermann/owncloud/notes/shared/util/DisplayUtils.java104
-rw-r--r--app/src/main/java/it/niedermann/owncloud/notes/shared/util/NoteUtil.java45
-rw-r--r--app/src/main/java/it/niedermann/owncloud/notes/shared/util/ShareUtil.java28
-rw-r--r--app/src/main/res/layout/activity_formatting_help.xml4
-rw-r--r--app/src/main/res/layout/activity_notes_list_view.xml1
-rw-r--r--app/src/main/res/layout/fragment_note_preview.xml2
-rw-r--r--app/src/main/res/values-ar/strings.xml2
-rw-r--r--app/src/main/res/values-ca/strings.xml12
-rw-r--r--app/src/main/res/values-cs-rCZ/strings.xml12
-rw-r--r--app/src/main/res/values-de/strings.xml12
-rw-r--r--app/src/main/res/values-el/strings.xml25
-rw-r--r--app/src/main/res/values-es/strings.xml12
-rw-r--r--app/src/main/res/values-eu/strings.xml27
-rw-r--r--app/src/main/res/values-fa/strings.xml159
-rw-r--r--app/src/main/res/values-fi-rFI/strings.xml2
-rw-r--r--app/src/main/res/values-fr/strings.xml12
-rw-r--r--app/src/main/res/values-gl/strings.xml12
-rw-r--r--app/src/main/res/values-hr/strings.xml2
-rw-r--r--app/src/main/res/values-it/strings.xml12
-rw-r--r--app/src/main/res/values-ja-rJP/strings.xml2
-rw-r--r--app/src/main/res/values-ko/strings.xml10
-rw-r--r--app/src/main/res/values-lt-rLT/strings.xml2
-rw-r--r--app/src/main/res/values-nb-rNO/strings.xml9
-rw-r--r--app/src/main/res/values-nl/strings.xml12
-rw-r--r--app/src/main/res/values-pl/strings.xml12
-rw-r--r--app/src/main/res/values-pt-rBR/strings.xml14
-rw-r--r--app/src/main/res/values-ru/strings.xml2
-rw-r--r--app/src/main/res/values-sc/strings.xml248
-rw-r--r--app/src/main/res/values-sk-rSK/strings.xml2
-rw-r--r--app/src/main/res/values-sl/strings.xml11
-rw-r--r--app/src/main/res/values-sr/strings.xml2
-rw-r--r--app/src/main/res/values-sv/strings.xml2
-rw-r--r--app/src/main/res/values-tr/strings.xml12
-rw-r--r--app/src/main/res/values-uk/strings.xml2
-rw-r--r--app/src/main/res/values-zh-rCN/strings.xml12
-rw-r--r--app/src/main/res/values-zh-rHK/strings.xml203
-rw-r--r--app/src/main/res/values-zh-rTW/strings.xml3
-rw-r--r--app/src/main/res/values/strings.xml1
-rw-r--r--app/src/test/java/it/niedermann/owncloud/notes/shared/model/NoteTest.java17
-rw-r--r--app/src/test/java/it/niedermann/owncloud/notes/shared/util/NoteUtilTest.java40
-rw-r--r--build.gradle4
-rw-r--r--fastlane/metadata/android/en-US/changelogs/2019001.txt1
-rw-r--r--fastlane/metadata/android/en-US/changelogs/3000000.txt18
-rw-r--r--fastlane/metadata/android/en-US/changelogs/3000001.txt24
-rw-r--r--fastlane/metadata/android/en-US/changelogs/3001000.txt28
-rw-r--r--fastlane/metadata/android/en-US/changelogs/3001001.txt2
-rw-r--r--fastlane/metadata/android/en-US/changelogs/3001002.txt1
-rw-r--r--fastlane/metadata/android/en-US/changelogs/3001003.txt1
-rw-r--r--fastlane/metadata/android/en-US/full_description.txt2
-rw-r--r--markdown/build.gradle4
-rw-r--r--markdown/src/androidTest/java/it/niedermann/android/markdown/MarkdownUtilTest.java (renamed from markdown/src/androidTest/java/it/niedermann/android/markdown/MarkwonMarkdownUtilTest.java)200
-rw-r--r--markdown/src/main/java/it/niedermann/android/markdown/MarkdownUtil.java310
-rw-r--r--markdown/src/main/java/it/niedermann/android/markdown/markwon/MarkwonMarkdownEditor.java41
-rw-r--r--markdown/src/main/java/it/niedermann/android/markdown/markwon/MarkwonMarkdownUtil.java329
-rw-r--r--markdown/src/main/java/it/niedermann/android/markdown/markwon/MarkwonMarkdownViewer.java71
-rw-r--r--markdown/src/main/java/it/niedermann/android/markdown/markwon/format/ContextBasedFormattingCallback.java12
-rw-r--r--markdown/src/main/java/it/niedermann/android/markdown/markwon/format/ContextBasedRangeFormattingCallback.java10
-rw-r--r--markdown/src/main/java/it/niedermann/android/markdown/markwon/plugins/LinkClickInterceptorPlugin.java2
-rw-r--r--markdown/src/main/java/it/niedermann/android/markdown/markwon/plugins/SearchHighlightPlugin.java17
-rw-r--r--markdown/src/main/java/it/niedermann/android/markdown/markwon/textwatcher/AutoContinuationTextWatcher.java31
-rw-r--r--markdown/src/main/java/it/niedermann/android/markdown/markwon/textwatcher/SearchHighlightTextWatcher.java22
-rw-r--r--markdown/src/main/java/it/niedermann/android/markdown/model/EListType.java (renamed from markdown/src/main/java/it/niedermann/android/markdown/markwon/model/EListType.java)2
-rw-r--r--markdown/src/main/java/it/niedermann/android/markdown/model/SearchSpan.java (renamed from markdown/src/main/java/it/niedermann/android/markdown/markwon/span/SearchSpan.java)23
-rw-r--r--markdown/src/main/java/it/niedermann/android/markdown/rxmarkdown/RxMarkdownEditor.java72
-rw-r--r--markdown/src/main/java/it/niedermann/android/markdown/rxmarkdown/RxMarkdownUtil.java44
-rw-r--r--markdown/src/main/java/it/niedermann/android/markdown/rxmarkdown/RxMarkdownViewer.java68
77 files changed, 1562 insertions, 957 deletions
diff --git a/README.md b/README.md
index 1d41cef9..98bf81b0 100644
--- a/README.md
+++ b/README.md
@@ -40,7 +40,7 @@ An android client for [Nextcloud Notes App](https://github.com/nextcloud/notes/)
* Bulk delete
* In-note search
* Single note widget and note list widget
- * Render MarkDown (using [RxMarkdown](https://github.com/yydcdut/RxMarkdown))
+ * Render Markdown (using [Markwon](https://noties.io/Markwon))
* Translated in many languages on [Transifex](https://www.transifex.com/nextcloud/nextcloud/android-notes/)
* Context based formatting ([#363](https://github.com/stefan-niedermann/nextcloud-notes/issues/363))
* Password protection ([#354](https://github.com/stefan-niedermann/nextcloud-notes/issues/354))
diff --git a/app/build.gradle b/app/build.gradle
index 877acb35..5720e7a3 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -12,10 +12,10 @@ android {
defaultConfig {
applicationId "it.niedermann.owncloud.notes"
- minSdkVersion 19
+ minSdkVersion 21
targetSdkVersion 30
- versionCode 2019000
- versionName "2.19.0"
+ versionCode 3001003
+ versionName "3.1.3"
multiDexEnabled true
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
javaCompileOptions {
@@ -77,13 +77,13 @@ dependencies {
// Android X
implementation "androidx.appcompat:appcompat:1.2.0"
- implementation "androidx.fragment:fragment:1.2.5"
+ implementation "androidx.fragment:fragment:1.3.0"
implementation "androidx.preference:preference:1.1.1"
implementation "androidx.recyclerview:recyclerview:1.1.0"
implementation 'androidx.recyclerview:recyclerview-selection:1.0.0'
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
- implementation 'androidx.work:work-runtime:2.4.0'
- implementation "com.google.android.material:material:1.2.1"
+ implementation 'androidx.work:work-runtime:2.5.0'
+ implementation "com.google.android.material:material:1.3.0"
// Database
implementation "androidx.room:room-runtime:2.2.6"
diff --git a/app/src/main/java/it/niedermann/owncloud/notes/AppendToNoteActivity.java b/app/src/main/java/it/niedermann/owncloud/notes/AppendToNoteActivity.java
index 191f0d47..a827ab50 100644
--- a/app/src/main/java/it/niedermann/owncloud/notes/AppendToNoteActivity.java
+++ b/app/src/main/java/it/niedermann/owncloud/notes/AppendToNoteActivity.java
@@ -1,7 +1,7 @@
package it.niedermann.owncloud.notes;
-import android.content.Intent;
import android.os.Bundle;
+import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.Toast;
@@ -12,6 +12,7 @@ import androidx.lifecycle.LiveData;
import it.niedermann.owncloud.notes.main.MainActivity;
import it.niedermann.owncloud.notes.persistence.entity.Note;
+import it.niedermann.owncloud.notes.shared.util.ShareUtil;
public class AppendToNoteActivity extends MainActivity {
@@ -23,8 +24,7 @@ public class AppendToNoteActivity extends MainActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- final Intent receivedIntent = getIntent();
- receivedText = receivedIntent.getStringExtra(Intent.EXTRA_TEXT);
+ receivedText = ShareUtil.extractSharedText(getIntent());
@Nullable final ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
getSupportActionBar().setTitle(R.string.append_to_note);
@@ -36,7 +36,7 @@ public class AppendToNoteActivity extends MainActivity {
@Override
public void onNoteClick(int position, View v) {
- if (receivedText != null && receivedText.length() > 0) {
+ if (!TextUtils.isEmpty(receivedText)) {
final LiveData<Note> fullNote$ = mainViewModel.getFullNote(((Note) adapter.getItem(position)).getId());
fullNote$.observe(this, (fullNote) -> {
fullNote$.removeObservers(this);
diff --git a/app/src/main/java/it/niedermann/owncloud/notes/LockedActivity.java b/app/src/main/java/it/niedermann/owncloud/notes/LockedActivity.java
index 8b024050..7ce7206b 100644
--- a/app/src/main/java/it/niedermann/owncloud/notes/LockedActivity.java
+++ b/app/src/main/java/it/niedermann/owncloud/notes/LockedActivity.java
@@ -93,7 +93,7 @@ public abstract class LockedActivity extends BrandedActivity {
}
private void askToUnlock() {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && NotesApplication.isLocked()) {
+ if (NotesApplication.isLocked()) {
KeyguardManager keyguardManager = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
if (keyguardManager != null) {
Intent i = keyguardManager.createConfirmDeviceCredentialIntent(getString(R.string.unlock_notes), null);
diff --git a/app/src/main/java/it/niedermann/owncloud/notes/NotesApplication.java b/app/src/main/java/it/niedermann/owncloud/notes/NotesApplication.java
index 852180b6..ef31acfc 100644
--- a/app/src/main/java/it/niedermann/owncloud/notes/NotesApplication.java
+++ b/app/src/main/java/it/niedermann/owncloud/notes/NotesApplication.java
@@ -16,7 +16,7 @@ import static androidx.preference.PreferenceManager.getDefaultSharedPreferences;
public class NotesApplication extends MultiDexApplication {
private static final String TAG = NotesApplication.class.getSimpleName();
- private static final long LOCK_TIME = 30 * 1000;
+ private static final long LOCK_TIME = 30_000;
private static boolean lockedPreference = false;
private static boolean isLocked = true;
private static long lastInteraction = 0;
diff --git a/app/src/main/java/it/niedermann/owncloud/notes/edit/EditNoteActivity.java b/app/src/main/java/it/niedermann/owncloud/notes/edit/EditNoteActivity.java
index 9b8fca09..c00db4aa 100644
--- a/app/src/main/java/it/niedermann/owncloud/notes/edit/EditNoteActivity.java
+++ b/app/src/main/java/it/niedermann/owncloud/notes/edit/EditNoteActivity.java
@@ -7,12 +7,17 @@ import android.text.TextUtils;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
+import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;
import androidx.preference.PreferenceManager;
+import com.nextcloud.android.sso.exceptions.NextcloudFilesAppAccountNotFoundException;
+import com.nextcloud.android.sso.exceptions.NoCurrentAccountSelectedException;
+import com.nextcloud.android.sso.helper.SingleAccountHelper;
+
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
@@ -24,12 +29,14 @@ import it.niedermann.owncloud.notes.LockedActivity;
import it.niedermann.owncloud.notes.R;
import it.niedermann.owncloud.notes.accountpicker.AccountPickerListener;
import it.niedermann.owncloud.notes.databinding.ActivityEditBinding;
+import it.niedermann.owncloud.notes.databinding.ActivityEditBinding;
import it.niedermann.owncloud.notes.edit.category.CategoryViewModel;
import it.niedermann.owncloud.notes.persistence.entity.Account;
import it.niedermann.owncloud.notes.persistence.entity.Note;
import it.niedermann.owncloud.notes.shared.model.DBStatus;
import it.niedermann.owncloud.notes.shared.model.NavigationCategory;
import it.niedermann.owncloud.notes.shared.util.NoteUtil;
+import it.niedermann.owncloud.notes.shared.util.ShareUtil;
import static it.niedermann.owncloud.notes.shared.model.ENavigationCategoryType.FAVORITES;
@@ -55,6 +62,16 @@ public class EditNoteActivity extends LockedActivity implements BaseNoteFragment
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+ try {
+ if (SingleAccountHelper.getCurrentSingleSignOnAccount(this) == null) {
+ throw new NoCurrentAccountSelectedException();
+ }
+ } catch (NextcloudFilesAppAccountNotFoundException | NoCurrentAccountSelectedException e) {
+ Toast.makeText(this, R.string.no_account_configured_yet, Toast.LENGTH_LONG).show();
+ finish();
+ return;
+ }
+
categoryViewModel = new ViewModelProvider(this).get(CategoryViewModel.class);
binding = ActivityEditBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
@@ -179,7 +196,7 @@ public class EditNoteActivity extends LockedActivity implements BaseNoteFragment
(Intent.ACTION_SEND.equals(intent.getAction()) ||
INTENT_GOOGLE_ASSISTANT.equals(intent.getAction()))
) {
- content = intent.getStringExtra(Intent.EXTRA_TEXT);
+ content = ShareUtil.extractSharedText(intent);
} else if (intent.hasExtra(PARAM_CONTENT)) {
content = intent.getStringExtra(PARAM_CONTENT);
}
diff --git a/app/src/main/java/it/niedermann/owncloud/notes/importaccount/ImportAccountViewModel.java b/app/src/main/java/it/niedermann/owncloud/notes/importaccount/ImportAccountViewModel.java
index 10f44676..04b30d8d 100644
--- a/app/src/main/java/it/niedermann/owncloud/notes/importaccount/ImportAccountViewModel.java
+++ b/app/src/main/java/it/niedermann/owncloud/notes/importaccount/ImportAccountViewModel.java
@@ -10,8 +10,6 @@ import it.niedermann.owncloud.notes.persistence.NotesDatabase;
import it.niedermann.owncloud.notes.persistence.entity.Account;
import it.niedermann.owncloud.notes.shared.model.Capabilities;
-import static it.niedermann.owncloud.notes.shared.util.DisplayUtils.convertToCategoryNavigationItem;
-
public class ImportAccountViewModel extends AndroidViewModel {
private static final String TAG = ImportAccountViewModel.class.getSimpleName();
diff --git a/app/src/main/java/it/niedermann/owncloud/notes/main/MainActivity.java b/app/src/main/java/it/niedermann/owncloud/notes/main/MainActivity.java
index 315fdc42..f36c0c02 100644
--- a/app/src/main/java/it/niedermann/owncloud/notes/main/MainActivity.java
+++ b/app/src/main/java/it/niedermann/owncloud/notes/main/MainActivity.java
@@ -23,12 +23,10 @@ import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.core.graphics.drawable.DrawableCompat;
import androidx.core.view.GravityCompat;
-import androidx.core.view.ViewCompat;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.selection.SelectionTracker;
-import androidx.recyclerview.selection.SelectionTracker.SelectionObserver;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.StaggeredGridLayoutManager;
@@ -81,7 +79,6 @@ import it.niedermann.owncloud.notes.shared.model.NoteClickListener;
import it.niedermann.owncloud.notes.shared.util.NoteUtil;
import static android.os.Build.VERSION.SDK_INT;
-import static android.os.Build.VERSION_CODES.LOLLIPOP;
import static android.os.Build.VERSION_CODES.O;
import static android.view.View.GONE;
import static android.view.View.VISIBLE;
@@ -420,7 +417,7 @@ public class MainActivity extends LockedActivity implements NoteClickListener, A
tracker = ItemSelectionTracker.build(listView, adapter);
adapter.setTracker(tracker);
- tracker.addObserver(new SelectionObserver<Long>() {
+ tracker.addObserver(new SelectionTracker.SelectionObserver<Long>() {
@Override
public void onSelectionChanged() {
super.onSelectionChanged();
@@ -513,9 +510,7 @@ public class MainActivity extends LockedActivity implements NoteClickListener, A
binding.headerView.setBackgroundColor(mainColor);
binding.appName.setTextColor(textColor);
- if (SDK_INT >= LOLLIPOP) {
- activityBinding.progressCircular.getIndeterminateDrawable().setColorFilter(getSecondaryForegroundColorDependingOnTheme(this, mainColor), PorterDuff.Mode.SRC_IN);
- }
+ activityBinding.progressCircular.getIndeterminateDrawable().setColorFilter(getSecondaryForegroundColorDependingOnTheme(this, mainColor), PorterDuff.Mode.SRC_IN);
// TODO We assume, that the background of the spinner is always white
activityBinding.swiperefreshlayout.setColorSchemeColors(contrastRatioIsSufficient(Color.WHITE, mainColor) ? mainColor : Color.BLACK);
@@ -664,12 +659,8 @@ public class MainActivity extends LockedActivity implements NoteClickListener, A
private void updateToolbars(boolean disableSearch) {
activityBinding.homeToolbar.setVisibility(disableSearch ? VISIBLE : GONE);
activityBinding.toolbar.setVisibility(disableSearch ? GONE : VISIBLE);
- if (SDK_INT >= LOLLIPOP) {
- activityBinding.appBar.setStateListAnimator(AnimatorInflater.loadStateListAnimator(activityBinding.appBar.getContext(),
- disableSearch ? R.animator.appbar_elevation_off : R.animator.appbar_elevation_on));
- } else {
- ViewCompat.setElevation(activityBinding.appBar, disableSearch ? 0 : getResources().getDimension(R.dimen.design_appbar_elevation));
- }
+ activityBinding.appBar.setStateListAnimator(AnimatorInflater.loadStateListAnimator(activityBinding.appBar.getContext(),
+ disableSearch ? R.animator.appbar_elevation_off : R.animator.appbar_elevation_on));
if (disableSearch) {
activityBinding.searchView.setQuery(null, true);
}
diff --git a/app/src/main/java/it/niedermann/owncloud/notes/main/items/NoteViewHolder.java b/app/src/main/java/it/niedermann/owncloud/notes/main/items/NoteViewHolder.java
index 73002879..6a0d5ceb 100644
--- a/app/src/main/java/it/niedermann/owncloud/notes/main/items/NoteViewHolder.java
+++ b/app/src/main/java/it/niedermann/owncloud/notes/main/items/NoteViewHolder.java
@@ -96,13 +96,7 @@ public abstract class NoteViewHolder extends RecyclerView.ViewHolder {
((Chip) noteCategory).setChipStrokeColor(ColorStateList.valueOf(categoryBackground));
((Chip) noteCategory).setChipBackgroundColor(ColorStateList.valueOf(isDarkThemeActive ? categoryBackground : Color.TRANSPARENT));
} else {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
- DrawableCompat.setTint(noteCategory.getBackground(), categoryBackground);
- } else {
- final GradientDrawable drawable = (GradientDrawable) noteCategory.getBackground();
- drawable.setStroke(1, categoryBackground);
- drawable.setColor(isDarkThemeActive ? categoryBackground : Color.TRANSPARENT);
- }
+ DrawableCompat.setTint(noteCategory.getBackground(), categoryBackground);
}
}
diff --git a/app/src/main/java/it/niedermann/owncloud/notes/persistence/NotesDatabase.java b/app/src/main/java/it/niedermann/owncloud/notes/persistence/NotesDatabase.java
index 9034ce48..9432d6fa 100644
--- a/app/src/main/java/it/niedermann/owncloud/notes/persistence/NotesDatabase.java
+++ b/app/src/main/java/it/niedermann/owncloud/notes/persistence/NotesDatabase.java
@@ -97,8 +97,10 @@ public abstract class NotesDatabase extends RoomDatabase {
private static NotesDatabase instance;
private static Context context;
private static NoteServerSyncHelper serverSyncHelper;
+ private static String defaultNonEmptyTitle;
private static NotesDatabase create(final Context context) {
+ defaultNonEmptyTitle = NoteUtil.generateNonEmptyNoteTitle("", context);
return Room.databaseBuilder(
context,
NotesDatabase.class,
@@ -269,7 +271,8 @@ public abstract class NotesDatabase extends RoomDatabase {
if (newTitle != null) {
title = newTitle;
} else {
- if (oldNote.getRemoteId() == null || localAccount.getPreferredApiVersion() == null || localAccount.getPreferredApiVersion().compareTo(new ApiVersion("1.0", 0, 0)) < 0) {
+ if ((oldNote.getRemoteId() == null || localAccount.getPreferredApiVersion() == null || localAccount.getPreferredApiVersion().compareTo(new ApiVersion("1.0", 0, 0)) < 0) &&
+ (defaultNonEmptyTitle.equals(oldNote.getTitle()))) {
title = NoteUtil.generateNonEmptyNoteTitle(newContent, context);
} else {
title = oldNote.getTitle();
diff --git a/app/src/main/java/it/niedermann/owncloud/notes/shared/model/CloudNote.java b/app/src/main/java/it/niedermann/owncloud/notes/shared/model/CloudNote.java
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/app/src/main/java/it/niedermann/owncloud/notes/shared/model/CloudNote.java
diff --git a/app/src/main/java/it/niedermann/owncloud/notes/shared/util/DisplayUtils.java b/app/src/main/java/it/niedermann/owncloud/notes/shared/util/DisplayUtils.java
index db696d85..ad6b6793 100644
--- a/app/src/main/java/it/niedermann/owncloud/notes/shared/util/DisplayUtils.java
+++ b/app/src/main/java/it/niedermann/owncloud/notes/shared/util/DisplayUtils.java
@@ -1,22 +1,3 @@
-/*
- * Nextcloud Notes application
- *
- * @author Mario Danic
- * Copyright (C) 2018 Mario Danic <mario@lovelyhq.com>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
package it.niedermann.owncloud.notes.shared.util;
import android.content.Context;
@@ -52,91 +33,6 @@ public class DisplayUtils {
}
- public static Spannable searchAndColor(Spannable spannable, CharSequence searchText, @NonNull Context context, @Nullable Integer current, @ColorInt int mainColor, @ColorInt int textColor) {
- CharSequence text = spannable.toString();
-
- Object[] spansToRemove = spannable.getSpans(0, text.length(), Object.class);
- for (Object span : spansToRemove) {
- if (span instanceof SearchSpan)
- spannable.removeSpan(span);
- }
-
- if (TextUtils.isEmpty(text) || TextUtils.isEmpty(searchText)) {
- return spannable;
- }
-
- Matcher m = Pattern.compile(searchText.toString(), Pattern.CASE_INSENSITIVE | Pattern.LITERAL)
- .matcher(text);
-
- int i = 1;
- while (m.find()) {
- int start = m.start();
- int end = m.end();
- spannable.setSpan(new SearchSpan(context, mainColor, textColor, (current != null && i == current)), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
- i++;
- }
-
- return spannable;
- }
-
-
- static class SearchSpan extends MetricAffectingSpan {
-
- private final boolean current;
- @NonNull
- Context context;
- @ColorInt
- private final int mainColor;
- @ColorInt
- private final int textColor;
- @ColorInt
- private final int highlightColor;
-
- SearchSpan(@NonNull Context context, @ColorInt int mainColor, @ColorInt int textColor, boolean current) {
- this.context = context;
- this.mainColor = mainColor;
- this.textColor = textColor;
- this.current = current;
- this.highlightColor = ContextCompat.getColor(context, R.color.bg_highlighted);
- }
-
- @Override
- public void updateDrawState(TextPaint tp) {
- if (current) {
- if (NotesApplication.isDarkThemeActive(context)) {
- if (ColorUtil.INSTANCE.isColorDark(mainColor)) {
- tp.bgColor = Color.WHITE;
- tp.setColor(mainColor);
- } else {
- tp.bgColor = mainColor;
- tp.setColor(Color.BLACK);
- }
- } else {
- if (ColorUtil.INSTANCE.isColorDark(mainColor)) {
- tp.bgColor = mainColor;
- tp.setColor(Color.WHITE);
- } else {
- if (NotesColorUtil.contrastRatioIsSufficient(mainColor, highlightColor)) {
- tp.bgColor = highlightColor;
- } else {
- tp.bgColor = Color.BLACK;
- }
- tp.setColor(mainColor);
- }
- }
- } else {
- tp.bgColor = highlightColor;
- tp.setColor(BrandingUtil.getSecondaryForegroundColorDependingOnTheme(context, mainColor));
- }
- tp.setFakeBoldText(true);
- }
-
- @Override
- public void updateMeasureState(@NonNull TextPaint tp) {
- tp.setFakeBoldText(true);
- }
- }
-
public static List<NavigationItem.CategoryNavigationItem> convertToCategoryNavigationItem(@NonNull Context context, @NonNull Collection<CategoryWithNotesCount> counter) {
return counter.stream()
.map(ctr -> convertToCategoryNavigationItem(context, ctr))
diff --git a/app/src/main/java/it/niedermann/owncloud/notes/shared/util/NoteUtil.java b/app/src/main/java/it/niedermann/owncloud/notes/shared/util/NoteUtil.java
index 9254de82..32caeaaf 100644
--- a/app/src/main/java/it/niedermann/owncloud/notes/shared/util/NoteUtil.java
+++ b/app/src/main/java/it/niedermann/owncloud/notes/shared/util/NoteUtil.java
@@ -7,10 +7,10 @@ import android.text.TextUtils;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
-import java.util.regex.Pattern;
-
import it.niedermann.owncloud.notes.R;
+import static it.niedermann.android.markdown.MarkdownUtil.removeMarkdown;
+
/**
* Provides basic functionality for Note operations.
* Created by stefan on 06.10.15.
@@ -18,13 +18,6 @@ import it.niedermann.owncloud.notes.R;
@SuppressWarnings("WeakerAccess")
public class NoteUtil {
- private static final Pattern pLists = Pattern.compile("^\\s*[*+-]\\s+", Pattern.MULTILINE);
- private static final Pattern pHeadings = Pattern.compile("^#+\\s+(.*?)\\s*#*$", Pattern.MULTILINE);
- private static final Pattern pHeadingLine = Pattern.compile("^(?:=*|-*)$", Pattern.MULTILINE);
- private static final Pattern pEmphasis = Pattern.compile("(\\*+|_+)(.*?)\\1", Pattern.MULTILINE);
- private static final Pattern pSpace1 = Pattern.compile("^\\s+", Pattern.MULTILINE);
- private static final Pattern pSpace2 = Pattern.compile("\\s+$", Pattern.MULTILINE);
-
public static final String EXCERPT_LINE_SEPARATOR = " ";
private NoteUtil() {
@@ -32,26 +25,6 @@ public class NoteUtil {
}
/**
- * Strips all MarkDown from the given String
- *
- * @param s String - MarkDown
- * @return Plain Text-String
- */
- @NonNull
- public static String removeMarkDown(@Nullable String s) {
- if (s == null)
- return "";
- String result = s;
- result = pLists.matcher(result).replaceAll("");
- result = pHeadings.matcher(result).replaceAll("$1");
- result = pHeadingLine.matcher(result).replaceAll("");
- result = pEmphasis.matcher(result).replaceAll("$2");
- result = pSpace1.matcher(result).replaceAll("");
- result = pSpace2.matcher(result).replaceAll("");
- return result;
- }
-
- /**
* Checks if a line is empty.
* <pre>
* " " -> empty
@@ -65,7 +38,7 @@ public class NoteUtil {
* @return boolean isEmpty
*/
public static boolean isEmptyLine(@Nullable String line) {
- return removeMarkDown(line).trim().length() == 0;
+ return removeMarkdown(line).trim().length() == 0;
}
/**
@@ -90,12 +63,12 @@ public class NoteUtil {
*/
@NonNull
public static String generateNoteExcerpt(@NonNull String content, @Nullable String title) {
- content = removeMarkDown(content.trim());
+ content = removeMarkdown(content.trim());
if (TextUtils.isEmpty(content)) {
return "";
}
if (!TextUtils.isEmpty(title)) {
- final String trimmedTitle = removeMarkDown(title.trim());
+ final String trimmedTitle = removeMarkdown(title.trim());
if (content.startsWith(trimmedTitle)) {
content = content.substring(trimmedTitle.length());
}
@@ -120,18 +93,18 @@ public class NoteUtil {
*/
@NonNull
public static String generateNoteTitle(@NonNull String content) {
- return getLineWithoutMarkDown(content, 0);
+ return getLineWithoutMarkdown(content, 0);
}
/**
- * Reads the requested line and strips all MarkDown. If line is empty, it will go ahead to find the next not-empty line.
+ * Reads the requested line and strips all Markdown. If line is empty, it will go ahead to find the next not-empty line.
*
* @param content String
* @param lineNumber int
* @return lineContent String
*/
@NonNull
- public static String getLineWithoutMarkDown(@NonNull String content, int lineNumber) {
+ public static String getLineWithoutMarkdown(@NonNull String content, int lineNumber) {
String line = "";
if (content.contains("\n")) {
String[] lines = content.split("\n");
@@ -140,7 +113,7 @@ public class NoteUtil {
currentLine++;
}
if (currentLine < lines.length) {
- line = NoteUtil.removeMarkDown(lines[currentLine]);
+ line = removeMarkdown(lines[currentLine]);
}
} else {
line = content;
diff --git a/app/src/main/java/it/niedermann/owncloud/notes/shared/util/ShareUtil.java b/app/src/main/java/it/niedermann/owncloud/notes/shared/util/ShareUtil.java
index 09ad7124..115d18dd 100644
--- a/app/src/main/java/it/niedermann/owncloud/notes/shared/util/ShareUtil.java
+++ b/app/src/main/java/it/niedermann/owncloud/notes/shared/util/ShareUtil.java
@@ -6,6 +6,11 @@ import android.content.Intent;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import it.niedermann.android.markdown.MarkdownUtil;
+
import static android.content.ClipDescription.MIMETYPE_TEXT_PLAIN;
public class ShareUtil {
@@ -17,4 +22,27 @@ public class ShareUtil {
.putExtra(Intent.EXTRA_TITLE, subject)
.putExtra(Intent.EXTRA_TEXT, text), subject));
}
+
+ public static String extractSharedText(@NonNull Intent intent) {
+ final String text = intent.getStringExtra(Intent.EXTRA_TEXT);
+ if (intent.hasExtra(Intent.EXTRA_SUBJECT)) {
+ final String subject = intent.getStringExtra(Intent.EXTRA_SUBJECT);
+ try {
+ new URL(text);
+ if (text != null && subject != null && !subject.trim().isEmpty()) {
+ return MarkdownUtil.getMarkdownLink(subject, text);
+ } else {
+ return text;
+ }
+ } catch (MalformedURLException e) {
+ if (subject != null && !subject.trim().isEmpty()) {
+ return subject + ": " + text;
+ } else {
+ return text;
+ }
+ }
+ } else {
+ return text;
+ }
+ }
}
diff --git a/app/src/main/res/layout/activity_formatting_help.xml b/app/src/main/res/layout/activity_formatting_help.xml
index bca0346f..d9becb26 100644
--- a/app/src/main/res/layout/activity_formatting_help.xml
+++ b/app/src/main/res/layout/activity_formatting_help.xml
@@ -37,7 +37,7 @@
android:orientation="vertical"
android:padding="@dimen/spacer_2x">
- <it.niedermann.android.markdown.markwon.MarkwonMarkdownViewer
+ <it.niedermann.android.markdown.MarkdownViewerImpl
android:id="@+id/content_context_based_formatting"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@@ -57,7 +57,7 @@
android:contentDescription="@string/context_based_formatting"
android:src="@drawable/context_based_formatting" />
- <it.niedermann.android.markdown.markwon.MarkwonMarkdownViewer
+ <it.niedermann.android.markdown.MarkdownViewerImpl
android:id="@+id/content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
diff --git a/app/src/main/res/layout/activity_notes_list_view.xml b/app/src/main/res/layout/activity_notes_list_view.xml
index 781b02c0..f747be40 100644
--- a/app/src/main/res/layout/activity_notes_list_view.xml
+++ b/app/src/main/res/layout/activity_notes_list_view.xml
@@ -124,7 +124,6 @@
android:layout_height="wrap_content"
android:layout_gravity="center"
android:indeterminateTint="@color/defaultBrand"
- tools:targetApi="lollipop"
tools:visibility="gone" />
<androidx.recyclerview.widget.RecyclerView
diff --git a/app/src/main/res/layout/fragment_note_preview.xml b/app/src/main/res/layout/fragment_note_preview.xml
index 733f381e..475f9ede 100644
--- a/app/src/main/res/layout/fragment_note_preview.xml
+++ b/app/src/main/res/layout/fragment_note_preview.xml
@@ -20,7 +20,7 @@
android:orientation="vertical"
tools:context="it.niedermann.owncloud.notes.edit.EditNoteActivity">
- <it.niedermann.android.markdown.markwon.MarkwonMarkdownViewer
+ <it.niedermann.android.markdown.MarkdownViewerImpl
android:id="@+id/single_note_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml
index bef0aa95..d1e5d01f 100644
--- a/app/src/main/res/values-ar/strings.xml
+++ b/app/src/main/res/values-ar/strings.xml
@@ -229,4 +229,4 @@
<string name="error_action_open_deck_info">افتح معلومات التطبيق</string>
<string name="error_action_open_network">اعدادات الشبكة</string>
<string name="no_other_accounts">لا يوجد لديك أي حسابات مكونة أخرى حتى الآن.</string>
-</resources>
+ </resources>
diff --git a/app/src/main/res/values-ca/strings.xml b/app/src/main/res/values-ca/strings.xml
index 5dbe96f2..b2e0cc60 100644
--- a/app/src/main/res/values-ca/strings.xml
+++ b/app/src/main/res/values-ca/strings.xml
@@ -189,6 +189,7 @@
<string name="formatting_help_codefence_inline" translateable="false">`%1$s`</string>
<string name="formatting_help_codefence_inline_escaped" translateable="false">\\`%1$s\\`</string>
<string name="formatting_help_codefence" translateable="false">```</string>
+ <string name="formatting_help_codefence_outer" translateable="false">````</string>
<string name="formatting_help_codefence_javascript" translateable="false">```javascript</string>
<string name="formatting_help_cbf_title">Format basat en el context</string>
<string name="formatting_help_cbf_body_1">Un objectiu principal del disseny de l\'aplicació Notes és proporcionar una eina lliure de distraccions. Tanmateix, podreu formatar els vostres textos amb Markdown. Per a molts dels exemples esmentats a continuació, podeu utilitzar dreceres per a formatar les vostres notes sense haver d\'escriure els codis següents.</string>
@@ -226,11 +227,22 @@
<string name="formatting_help_code_body_2">Markdown també admet l\'aïllament de codi, que permet inserir diverses línies sense sagnat:</string>
<string name="formatting_help_code_body_3">Si voleu utilitzar el ressaltat de sintaxi, incloeu-hi el llenguatge:</string>
+ <string name="formatting_help_tables_title">Taules</string>
+ <!-- Column header of a sample table -->
+ <string name="formatting_help_tables_column">Columna %1d</string>
+ <!-- Table cell value of a sample table -->
+ <string name="formatting_help_tables_value">Valor %1d</string>
+
+ <string name="formatting_help_images_title">Imatges</string>
+ <string name="formatting_help_images_alt">Imatge bonica</string>
+
<string name="simple_other">Altres</string>
<string name="sort_last_modified">Ordena per la data de modificació</string>
<string name="sort_alphabetically">Ordena alfabèticament</string>
<string name="error_action_open_battery_settings">Paràmetres de la bateria</string>
<string name="error_action_open_deck_info">Obre la informació de l\'aplicació</string>
<string name="error_action_open_network">Paràmetres de la xarxa</string>
+ <string name="no_account_configured_yet">Encara no s\'ha configurat cap compte</string>
<string name="no_other_accounts">Encara no heu configurat cap altre compte.</string>
+ <string name="context_based_formatting">Element emergent de format basat en el context</string>
</resources>
diff --git a/app/src/main/res/values-cs-rCZ/strings.xml b/app/src/main/res/values-cs-rCZ/strings.xml
index a38e4a1f..45d3da75 100644
--- a/app/src/main/res/values-cs-rCZ/strings.xml
+++ b/app/src/main/res/values-cs-rCZ/strings.xml
@@ -197,6 +197,7 @@
<string name="formatting_help_codefence_inline" translateable="false">`%1$s`</string>
<string name="formatting_help_codefence_inline_escaped" translateable="false">\\`%1$s\\`</string>
<string name="formatting_help_codefence" translateable="false">```</string>
+ <string name="formatting_help_codefence_outer" translateable="false">````</string>
<string name="formatting_help_codefence_javascript" translateable="false">```javascript</string>
<string name="formatting_help_cbf_title">Formátování založené na kontextu</string>
<string name="formatting_help_cbf_body_1">Hlavním cílem návrhu aplikace Poznámky je poskytovat nástroj, kterého používání nerozptyluje. Ačkoli můžete texty formátovat pomocí Markdown značek. Pro různé z níže uvedených příkladů můžete použít zkratky, takže své poznámky můžete formátovat bez zadávání níže uvedených kódů.</string>
@@ -234,11 +235,22 @@
<string name="formatting_help_code_body_2">Značkovací jazyk Markdown také podporuje něco co se nazývá „oplocení“ kódu, což umožňuje vícero řádek bez odsazení:</string>
<string name="formatting_help_code_body_3">A pokud chcete použít zvýrazňování syntaxe, včetně jazyka:</string>
+ <string name="formatting_help_tables_title">Tabulky</string>
+ <!-- Column header of a sample table -->
+ <string name="formatting_help_tables_column">Sloupec %1d</string>
+ <!-- Table cell value of a sample table -->
+ <string name="formatting_help_tables_value">Hodnota %1d</string>
+
+ <string name="formatting_help_images_title">Obrázky</string>
+ <string name="formatting_help_images_alt">Ozdobný obrázek</string>
+
<string name="simple_other">Ostatní</string>
<string name="sort_last_modified">Seřadit podle data změny</string>
<string name="sort_alphabetically">Seřadit abecedně</string>
<string name="error_action_open_battery_settings">Nastavení správy napájení</string>
<string name="error_action_open_deck_info">Otevřít informace o aplikaci</string>
<string name="error_action_open_network">Nastavení sítě</string>
+ <string name="no_account_configured_yet">Zatím není nastavený žádný účet</string>
<string name="no_other_accounts">Zatím jste nenastavili žádné další účty.</string>
+ <string name="context_based_formatting">Kontextové vyskakovací okno formátování</string>
</resources>
diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml
index 3b27c170..8ce88e1d 100644
--- a/app/src/main/res/values-de/strings.xml
+++ b/app/src/main/res/values-de/strings.xml
@@ -189,6 +189,7 @@
<string name="formatting_help_codefence_inline" translateable="false">`%1$s`</string>
<string name="formatting_help_codefence_inline_escaped" translateable="false">\\`%1$s\\`</string>
<string name="formatting_help_codefence" translateable="false">```</string>
+ <string name="formatting_help_codefence_outer" translateable="false">````</string>
<string name="formatting_help_codefence_javascript" translateable="false">```javascript</string>
<string name="formatting_help_cbf_title">Kontextbasierte Formatierung</string>
<string name="formatting_help_cbf_body_1">Ein wichtiges Designziel der Notes-App ist die Bereitstellung eines ablenkungsfreien Werkzeugs. Sie können Ihre Texte mit Markdown formatieren. Für verschiedene der unten genannten Beispiele können Sie Verknüpfungen verwenden, um Ihre Notizen zu formatieren, ohne die folgenden Codes eingeben zu müssen.</string>
@@ -226,11 +227,22 @@
<string name="formatting_help_code_body_2">Markdown unterstützt auch das sogenannte Code-Fencing, das mehrere Zeilen ohne Einrückung zulässt:</string>
<string name="formatting_help_code_body_3">Wenn Sie die Syntaxhervorhebung verwenden möchten, geben Sie folgendes ein:</string>
+ <string name="formatting_help_tables_title">Tabellen</string>
+ <!-- Column header of a sample table -->
+ <string name="formatting_help_tables_column">Spalte %1d</string>
+ <!-- Table cell value of a sample table -->
+ <string name="formatting_help_tables_value">Wert %1d</string>
+
+ <string name="formatting_help_images_title">Bilder</string>
+ <string name="formatting_help_images_alt">Ausgefallenes Bild</string>
+
<string name="simple_other">Andere</string>
<string name="sort_last_modified">Nach Änderungsdatum sortieren</string>
<string name="sort_alphabetically">Alphabetisch sortieren</string>
<string name="error_action_open_battery_settings">Batterie-Einstellungen</string>
<string name="error_action_open_deck_info">App-Informationen öffnen</string>
<string name="error_action_open_network">Netzwerkeinstellungen</string>
+ <string name="no_account_configured_yet">Bislang kein Konto eingerichtet</string>
<string name="no_other_accounts">Sie haben bislang keine weiteren Konten eingerichtet.</string>
+ <string name="context_based_formatting">Popup für die kontextbasierte Formatierung</string>
</resources>
diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml
index d8c8726a..cadff94a 100644
--- a/app/src/main/res/values-el/strings.xml
+++ b/app/src/main/res/values-el/strings.xml
@@ -172,10 +172,24 @@
<item quantity="one">%d επιλέχτηκε</item>
<item quantity="other">%d επιλέχτηκαν</item>
</plurals>
+ <plurals name="bulk_notes_deleted">
+ <item quantity="one">Διαγράφηκε μία σημείωση</item>
+ <item quantity="other">Διαγράφηκαν %1$d σημειώσεις</item>
+ </plurals>
+ <plurals name="bulk_notes_restored">
+ <item quantity="one">Επαναφέρθηκε μία σημείωση</item>
+ <item quantity="other">Επαναφέρθηκαν %1$dσημειώσεις</item>
+ </plurals>
+ <plurals name="share_multiple">
+ <item quantity="one">Διαμοιρασμός περιεχομένου %1$d σημείωσης</item>
+ <item quantity="other">Διαμοιρασμός περιεχομένου %1$d σημειώσεων</item>
+ </plurals>
+
<string name="formatting_help_divider" translateable="false">---</string>
<string name="formatting_help_codefence_inline" translateable="false">`%1$s`</string>
<string name="formatting_help_codefence_inline_escaped" translateable="false">\\`%1$s\\`</string>
<string name="formatting_help_codefence" translateable="false">```</string>
+ <string name="formatting_help_codefence_outer" translateable="false">````</string>
<string name="formatting_help_codefence_javascript" translateable="false">```javascript</string>
<string name="formatting_help_cbf_title">Μορφοποίηση βάσει κατάστασης</string>
<string name="formatting_help_cbf_body_1">Ένας κύριος σχεδιαστικός στόχος της εφαρμογής Σημειώσεις, είναι να παρέχει ένα ανεξάρτητο εργαλείο. Θα μπορείτε να μορφοποιήσετε τα κείμενά σας με το Markdown. Για διάφορα από τα παρακάτω παραδείγματα, μπορείτε να χρησιμοποιήσετε συντομεύσεις για να μορφοποιήσετε τις σημειώσεις σας χωρίς να πληκτρολογήσετε τους παρακάτω κωδικούς.</string>
@@ -213,11 +227,22 @@
<string name="formatting_help_code_body_2">Το Markdown υποστηρίζει επίσης κάτι που ονομάζεται code fencing, το οποίο επιτρέπει πολλαπλές γραμμές χωρίς εσοχή:</string>
<string name="formatting_help_code_body_3">Και αν θέλετε να χρησιμοποιήσετε την επισήμανση σύνταξης, συμπεριλάβετε τη γλώσσα:</string>
+ <string name="formatting_help_tables_title">Πίνακες</string>
+ <!-- Column header of a sample table -->
+ <string name="formatting_help_tables_column">Στήλη %1d</string>
+ <!-- Table cell value of a sample table -->
+ <string name="formatting_help_tables_value">Αξία %1d</string>
+
+ <string name="formatting_help_images_title">Εικόνες</string>
+ <string name="formatting_help_images_alt">Φανταστική εικόνα</string>
+
<string name="simple_other">Άλλο</string>
<string name="sort_last_modified">Ταξινόμηση κατά ημερομηνία τροποποίησης</string>
<string name="sort_alphabetically">Ταξινόμηση αλφαβητικά</string>
<string name="error_action_open_battery_settings">Ρυθμίσεις μπαταρίας</string>
<string name="error_action_open_deck_info">Πληροφορίες εφαρμογής</string>
<string name="error_action_open_network">Ρυθμίσεις δικτύου</string>
+ <string name="no_account_configured_yet">Δεν έχει ρυθμιστεί ακόμη κάποιος λογαριασμός</string>
<string name="no_other_accounts">Δεν έχετε ρυθμίσει ακόμη άλλους λογαριασμούς.</string>
+ <string name="context_based_formatting">Μορφοποίηση βάσει περιεχομένου popover</string>
</resources>
diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml
index f9861970..e2b6429a 100644
--- a/app/src/main/res/values-es/strings.xml
+++ b/app/src/main/res/values-es/strings.xml
@@ -189,6 +189,7 @@
<string name="formatting_help_codefence_inline" translateable="false">`%1$s`</string>
<string name="formatting_help_codefence_inline_escaped" translateable="false">\\`%1$s\\`</string>
<string name="formatting_help_codefence" translateable="false">```</string>
+ <string name="formatting_help_codefence_outer" translateable="false">````</string>
<string name="formatting_help_codefence_javascript" translateable="false">```javascript</string>
<string name="formatting_help_cbf_title">Formato basado en el contexto</string>
<string name="formatting_help_cbf_body_1">Un objetivo principal de diseño de la app Notas es ofrecer una herramienta libre de distracciones. Aunque podrás formatear tus textos con Markdown. Para varios de los ejemplos mencionados debajo, puedes usar atajos para formatear las notas sin escribir los códigos.</string>
@@ -226,11 +227,22 @@
<string name="formatting_help_code_body_2">Markdown también soporta el llamado vallado de código, que permite líneas múltiples sin indentación:</string>
<string name="formatting_help_code_body_3">Y si quieres usar subrayado de sintaxis, incluye el lenguaje:</string>
+ <string name="formatting_help_tables_title">Tablas</string>
+ <!-- Column header of a sample table -->
+ <string name="formatting_help_tables_column">Columna %1d</string>
+ <!-- Table cell value of a sample table -->
+ <string name="formatting_help_tables_value">Valor %1d</string>
+
+ <string name="formatting_help_images_title">Imágenes</string>
+ <string name="formatting_help_images_alt">Imagen elegante</string>
+
<string name="simple_other">Otro</string>
<string name="sort_last_modified">Ordenar por fecha de modificación</string>
<string name="sort_alphabetically">Ordenar alfabéticamente</string>
<string name="error_action_open_battery_settings">Ajustes de batería</string>
<string name="error_action_open_deck_info">Abrir info de la app</string>
<string name="error_action_open_network">Configuración de red</string>
+ <string name="no_account_configured_yet">Todavía no hay una cuenta configurada</string>
<string name="no_other_accounts">Aún no ha configurado ninguna otra cuenta.</string>
+ <string name="context_based_formatting">Ventana emergente para formato basado en el contexto</string>
</resources>
diff --git a/app/src/main/res/values-eu/strings.xml b/app/src/main/res/values-eu/strings.xml
index 8455fa2d..3063a548 100644
--- a/app/src/main/res/values-eu/strings.xml
+++ b/app/src/main/res/values-eu/strings.xml
@@ -172,10 +172,24 @@
<item quantity="one">%d hautatuta</item>
<item quantity="other">%d hautatuta</item>
</plurals>
+ <plurals name="bulk_notes_deleted">
+ <item quantity="one">ohar ezabatu dira</item>
+ <item quantity="other">%1$dohar ezabatu dira</item>
+ </plurals>
+ <plurals name="bulk_notes_restored">
+ <item quantity="one">ohar leheneratu dira</item>
+ <item quantity="other">%1$dohar leheneratu dira</item>
+ </plurals>
+ <plurals name="share_multiple">
+ <item quantity="one">Partekatu %1$doharraren edukia</item>
+ <item quantity="other">Partekatu %1$doharraren edukia</item>
+ </plurals>
+
<string name="formatting_help_divider" translateable="false">---</string>
<string name="formatting_help_codefence_inline" translateable="false">`%1$s`</string>
<string name="formatting_help_codefence_inline_escaped" translateable="false">\\`%1$s\\`</string>
<string name="formatting_help_codefence" translateable="false">```</string>
+ <string name="formatting_help_codefence_outer" translateable="false">````</string>
<string name="formatting_help_codefence_javascript" translateable="false">```javascript</string>
<string name="formatting_help_cbf_title">Testuinguruan oinarritutako formatu ematea</string>
<string name="formatting_help_cbf_body_1">Oharrak aplikazioaren diseinuaren erronka handi bat arreta-galtzerik gabeko tresna bat eskaintzea da. Baina aukera dago Markdown erabiliz testuei formatua emateko. Behean adierazitako adibide ugaritarako, lasterbideak erabil daitezke oharrei formatua emateko beheko kodeak idatzi gabe.</string>
@@ -209,13 +223,26 @@
<string name="formatting_help_structured_documents_body_6">- Albert Einstein</string>
<string name="formatting_help_code_title">Kodea</string>
+ <string name="formatting_help_code_body_1">Markdown-ekin kode estiloa zuzentzeko hainbat modu daude. Txertatutako kode-blokeak izanez gero, egokitu atzeramarkekin:</string>
+ <string name="formatting_help_code_body_2">Markdown-ek kode-eskrima deituriko zerbait ere onartzen du, koskarik gabe hainbat lerro ahalbidetzen dituena:</string>
<string name="formatting_help_code_body_3">Eta sintaxi nabarmentzea erabili nahi baduzu, gehitu hizkuntza:</string>
+ <string name="formatting_help_tables_title">Taulak</string>
+ <!-- Column header of a sample table -->
+ <string name="formatting_help_tables_column">%1dzutabea</string>
+ <!-- Table cell value of a sample table -->
+ <string name="formatting_help_tables_value">%1dbalioa</string>
+
+ <string name="formatting_help_images_title">Irudiak</string>
+ <string name="formatting_help_images_alt">Irudi dotorea</string>
+
<string name="simple_other">Beste bat</string>
<string name="sort_last_modified">Ordenatu aldatze-dataren arabera</string>
<string name="sort_alphabetically">Ordenatu alfabetikoki</string>
<string name="error_action_open_battery_settings">Bateria ezarpenak</string>
<string name="error_action_open_deck_info">Ireki aplikazioaren informazioa</string>
<string name="error_action_open_network">Sareko ezarpenak</string>
+ <string name="no_account_configured_yet">Oraindik ez da konturik konfiguratu </string>
<string name="no_other_accounts">Oraindik ez duzu konturik konfiguratu.</string>
+ <string name="context_based_formatting">Testuinguruan oinarritutako formateatze leiho gainerakorra </string>
</resources>
diff --git a/app/src/main/res/values-fa/strings.xml b/app/src/main/res/values-fa/strings.xml
index 37b8acb1..937361ca 100644
--- a/app/src/main/res/values-fa/strings.xml
+++ b/app/src/main/res/values-fa/strings.xml
@@ -1,59 +1,59 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
- <string name="app_name">یادداشت ها</string>
+ <string name="app_name">یادداشت‌ها</string>
<string name="app_name_long">یادداشت های نکست کلود</string>
- <string name="label_all_notes">همه یادداشت ها</string>
- <string name="label_favorites">Favorites</string>
+ <string name="label_all_notes">همه یادداشت‌ها</string>
+ <string name="label_favorites">مورد علاقه‌ها</string>
<string name="action_create">یادداشت جدید</string>
<string name="action_settings">تنظیمات</string>
- <string name="action_trashbin">یادداشتهای حذف شده</string>
+ <string name="action_trashbin">یادداشت‌های حذف شده</string>
<string name="action_search">جستجو</string>
+ <string name="action_sorting_method">روش مرتب‌سازی</string>
<string name="simple_cancel">لغو</string>
<string name="simple_edit">ویرایش</string>
<string name="action_edit_save">ذخیره</string>
<string name="simple_about">درباره</string>
- <string name="simple_link">Link</string>
+ <string name="simple_link">پیوند</string>
<string name="action_note_deleted">حذف شد %1$s</string>
<string name="action_note_restored">بازیابی شد %1$s</string>
<string name="action_undo">برگرداندن</string>
- <string name="action_uncategorized">دستهبندی نشده</string>
+ <string name="action_uncategorized">دسته‌بندی نشده</string>
<string name="menu_delete">حذف</string>
<string name="menu_change_category">دسته‌بندی</string>
- <string name="menu_favorite">برگزیده</string>
- <string name="menu_preview">پیش نمایش</string>
+ <string name="menu_favorite">مورد‌ ‌علاقه‌</string>
+ <string name="menu_preview">پیش‌نمایش</string>
<string name="menu_share">هم‌رسانی</string>
- <string name="change_category_title">انتخاب یک دسته بندی</string>
+ <string name="search_in_category">جستجو در %1$s</string>
+ <string name="search_in_all">جستجو در همه یادداشت‌ها</string>
- <string name="listview_updated_today">Today</string>
+ <string name="change_category_title">انتخاب یک دسته‌بندی</string>
+
+ <string name="listview_updated_today">امروز</string>
<string name="listview_updated_yesterday">دیروز</string>
<string name="listview_updated_this_week">این هفته</string>
<string name="listview_updated_last_week">هفته گذشته</string>
<string name="listview_updated_this_month">این ماه</string>
<string name="listview_updated_last_month">ماه گذشته</string>
- <!-- Settings -->
- <string name="settings_note_mode">حالت نمایش یادداشت ها</string>
- <string name="settings_theme_title">تم تاریک</string>
- <string name="settings_font_title">فونت Monospace</string>
+ <string name="settings_note_mode">حالت نمایش یادداشت‌ها</string>
+ <string name="settings_theme_title">"تم "</string>
+ <string name="settings_font_title">قلم Monospace</string>
<string name="settings_font_size">اندازهٔ قلم</string>
- <string name="settings_wifi_only">همگام سازی فقط در Wi-Fi</string>
+ <string name="settings_wifi_only">همگام‌سازی فقط در Wi-Fi</string>
<string name="settings_lock">محافظت از رمز عبور</string>
- <string name="settings_background_sync">همگام سازی پس زمینه</string>
-
- <!-- Network -->
+ <string name="settings_background_sync">همگام‌سازی پس زمینه</string>
- <!-- Error -->
- <string name="error_sync">همگام سازی انجام نشد:%1$s</string>
+ <string name="error_sync">همگام‌سازی انجام نشد:%1$s</string>
+ <string name="error_synchronization">همگام‌سازی انجام نشد</string>
<string name="error_no_network">هیچ ارتباطی به شبکه موجود نیست</string>
<string name="error_unknown">یک خطای ناشناخته رخ داده است.</string>
- <!-- About -->
<string name="about_version_title">نسخه</string>
<string name="about_version">شما در حال استفاده هستیدstrong>%1$s&lt;/strong></string>
- <string name="about_maintainer_title">نگهدار</string>
- <string name="about_developers_title">Developers</string>
+ <string name="about_maintainer_title">نگاه‌دارنده</string>
+ <string name="about_developers_title">توسعه دهندگان</string>
<string name="about_translators_title">مترجم</string>
<string name="about_translators_transifex">انجمن نکست کلود در &lt;a href=\"%1$s\">Transifex&lt;/a></string>
<string name="about_testers_title">آزمایش کنندگان</string>
@@ -61,46 +61,43 @@
<string name="about_source">این پروژه در GitHub میزبانی شده است: &lt;a href=\"%1$s\">%1$s&lt;/a></string>
<string name="about_issues_title">مسائل</string>
<string name="about_issues">شما می توانید اشکالات ، پیشنهادات پیشرفت و درخواست ویژگی را در ردیاب شماره GitHub گزارش دهید: &lt;a href=\"%1$s\">%1$s&lt;/a></string>
- <string name="about_translate_title">Translate</string>
+ <string name="about_translate_title">ترجمه</string>
<string name="about_translate">در Transferx به تیم Nextcloud بپیوندید و در ترجمه این برنامه به ما کمک کنید: &lt;a href=\"%1$s\">%1$s&lt;/a></string>
<string name="about_app_license_title">مجوز برنامه</string>
<string name="about_app_license">این برنامه تحت مجوز GNU GENERAL PUBLIC LICENSE v3 + مجاز است.</string>
<string name="about_app_license_button">مشاهده مجوز</string>
- <string name="about_icons_disclaimer_title">آیکون ها</string>
+ <string name="about_icons_disclaimer_title">آیکون‌ها</string>
<string name="about_icons_disclaimer">&lt;p>نماد اصلی ساخته شده توسط %1$s&lt;/p>&lt;p>تمام نمادهای دیگر مورد استفاده این برنامه هستند &lt;a href=\"https://materialdesignicons.com/\">شمایل طراحی مواد&lt;/a> ساخته شده توسط Google Inc. و تحت مجوز Apache 2.0 مجوز گرفته شده است.&lt;/p></string>
<string name="about_credits_tab_title">اعتبارات</string>
<string name="about_contribution_tab_title">مشارکت</string>
- <string name="about_license_tab_title">License</string>
+ <string name="about_license_tab_title">مجوز</string>
- <!-- Widgets -->
- <string name="widget_note_list_title">لیست یادداشت</string>
+ <string name="widget_note_list_title">لیست یادداشت‌ها</string>
<string name="widget_note_list_placeholder">بدون یادداشت</string>
<string name="widget_single_note_title">یادداشت واحد</string>
<string name="widget_single_note_placeholder_tv">یادداشت یافت نشد</string>
<string name="widget_create_note">ساختن یادداشت</string>
- <string name="widget_not_logged_in">لطفاً قبل از استفاده از این ویجت به یادداشت ها وارد شوید</string>
- <string name="widget_entry_fav_contentDescription">از نماد ستاره برای مشخص کردن یک مورد به عنوان مورد علاقه استفاده می شود</string>
- <string name="widget_app_launcher_contentDescription">برنامه راه اندازی می شود</string>
+ <string name="widget_not_logged_in">لطفاً قبل از استفاده از این ویجت، به یادداشت‌ها وارد شوید</string>
+ <string name="widget_entry_fav_contentDescription">از آیکون ستاره برای مشخص کردن یک مورد به عنوان مورد علاقه استفاده می‌شود</string>
+ <string name="widget_app_launcher_contentDescription">برنامه راه اندازی می‌شود</string>
<string name="activity_select_single_note">انتخاب یادداشت</string>
- <!-- Shortcuts -->
<string name="shortcut_create_long">ساختن یادداشت جدید</string>
- <!-- These values should not be translatable. They should be migrated at some point. -->
<string name="pref_value_font_normal">معمولی</string>
- <string name="pref_value_wifi_and_mobile">همگام سازی داده های Wi-Fi و تلفن همراه</string>
+ <string name="pref_value_wifi_and_mobile">همگام‌سازی در حالت اتصال به Wi-Fi و اینترنت همراه</string>
<string name="pref_value_lock">محافظت از رمز عبور</string>
<string name="simple_error">خطا</string>
<string name="simple_close">بستن</string>
- <string name="simple_copy">کپی کردن</string>
+ <string name="simple_copy">رونوشت</string>
<string name="simple_exception">استثنا</string>
- <string name="pin_to_homescreen">پین به صفحه اصلی</string>
+ <string name="pin_to_homescreen">اتصال به صفحه اصلی</string>
<string name="note_has_been_deleted">این یادداشت حذف شده است</string>
- <string name="add_account">ایحاد حساب کاربری</string>
+ <string name="add_account">افزودن حساب کاربری</string>
<string name="category_music">موسیقی</string>
- <string name="category_movies">فیلم ها</string>
+ <string name="category_movies">فیلم‌ها</string>
<string name="category_movie">فیلم</string>
<string name="category_work">کار</string>
<string name="account_already_imported">حساب قبلاً وارد شده است</string>
@@ -109,28 +106,55 @@
<string name="simple_more">بیش‌تر</string>
<string name="simple_move">انتقال</string>
<string name="category_readonly">فقط خواندنی</string>
- <string name="no_category">بدون دسته بندی</string>
+ <string name="no_category">بدون دسته‌بندی</string>
<string name="add_category">افزودن%1$s</string>
<string name="simple_checkbox">جعبه علامت</string>
+ <string name="unlock_notes">یادداشت‌های باز</string>
+ <string name="simple_beta">بتا</string>
+ <string name="error_dialog_title">وای نه - حالا چی کار کنیم؟</string>
+ <string name="error_dialog_tip_token_mismatch_retry">"لطفا از طریق توقف اجباری برنامه را بسته و دوباره اجرا کنید. ممکن است یک اتصال نادرست با ابر سانا ایجاد شده باشد. "</string>
+ <string name="error_dialog_tip_token_mismatch_clear_storage">اگر این مشکل استمرار داشت، سعی کنید با پاک کردن فضای ذخیره‌سازی هردو برنامک : ابر سانا و یادداشت سانا، این مورد را برطرف کنید.</string>
+ <string name="error_dialog_tip_clear_storage">شما می‌توانید فضای ذخیره‌سازی برنامک را با بازکردن اطلاعات برنامه و انتخاب «فضای ذخیره‌سازی و حافظه پنهان» -> «پاک‌کردن محل ذخیره‌سازی»، پاک‌سازی کنید.</string>
+ <string name="error_dialog_tip_files_outdated">ظاهرا برنامک یادداشت منسوخ شده است. لطفا آخرین نسخه را از سانا مارکت دانلود کنید. </string>
+ <string name="error_dialog_tip_files_force_stop">به نظر می‌رسد که مشکلی در برنامک نکست‌کلود ایجاد شده است. لطفا سعی کنید با توقف اجباری هر دو برنامک ابر سانا و یادداشت سانا را ببندید. </string>
+ <string name="error_dialog_tip_files_delete_storage">"اگر توقف اجباری برنامه‌ها کمکی نکرد، می‌توانید پاک‌کردن فضای ذخیره‌سازی هردو برنامه را پاک کنید. "</string>
+ <string name="error_dialog_timeout_instance">پاسخ از سمت سرور شما با نام داده شده دریافت نشد. لطفا بررسی کنید که نمونه شما به درستی کار می‌کند.</string>
+ <string name="error_dialog_timeout_toggle">"اتصال اینترنت خود را بررسی کنید. خاموش کردن اینترنت همراه و وای‌فای و روشن کردن مجدد آنها در برخی ار مواقع می‌تواند کارساز باشد. "</string>
+ <string name="error_dialog_check_server">پاسخ درستی از سرور شما دریافت نشد. لطفا دسترسی به یادداشت‌های خود را از طریق وب بررسی کنید.</string>
+ <string name="error_dialog_check_server_logs">" مشکلی در نصب ابر سانا وجود دارد. لطفا لاگ‌های سرور را بررسی کنید."</string>
+ <string name="error_dialog_check_maintenance">لطفا بررسی کنید که نسخه ابر سانای شما در حال حاضر در حالت تعمیر و نگهداری نباشد.</string>
+ <string name="error_dialog_insufficient_storage">فضای برنامک نکست‌کلود شما پر شده است.لطفا یعضی از فایل‌های خود در را فضای ابری برای همگام‌سازی تغییرات محلی پاک کنید. </string>
+ <string name="error_dialog_contact_us">لطفا بدون هیچ تردیدی در صورت استمرار مشکل با ما تماس بگیرید.</string>
+ <string name="error_dialog_we_need_info">ما برای کمک به شما احتیاج به دنبال کردن اطلاعات فنی داریم:</string>
+ <string name="error_dialog_server_app_enabled">لطفا از نصب و فعال بودن برنامک یادداشت بر روی سرور، اطمینان حاصل کنید.</string>
+ <string name="error_dialog_redirect">پاسخ سرور شما کد حالت HTTP 302 است. که دلالت بر عدم نصب برنامک یادداشت بر روی سرور و یا پیکربندی نامناسب دارد. این مشکل می‌تواند به دلیل تغییرات نامناسب ایجاد شده در فایل .htaccess و یا به دلیل برنامه‌های مرتبط با Nextcloud مثل OID Client رخ دهد.</string>
+ <string name="error_dialog_tip_disable_battery_optimizations">لطفا تمامی فرایند‌های بهینه‌سازی مصرف باتری برای ابر سانا و برنامک یادداشت را غیر فعال کنید.</string>
+ <string name="added_content">اضافه ‌شده %1$s</string>
+ <string name="shared_text_empty">متن به اشتراک گذاشته‌شده خالی است</string>
+ <string name="append_to_note">به یادداشت اضافه کنید</string>
+ <string name="change_note_title">عوض‌کردن عنوان یادداشت</string>
+ <string name="menu_edit_title">ویرایش عنوان</string>
+ <string name="settings_branding">شخصی‌سازی</string>
+ <string name="settings_gridview">حالت شبکه‌ای جدید</string>
<string name="simple_security">امنیت</string>
<string name="simple_appearance">ظاهر</string>
- <string name="simple_synchronization">هم‌گام‌سازی</string>
+ <string name="simple_synchronization">همگام‌سازی</string>
+ <string name="simple_behavior">رفتار</string>
<string name="manage_accounts">مدیریت حساب‌ها</string>
- <!-- Array: note modes -->
+ <string name="action_formatting_help">قالب‌بندی</string>
+
<string-array name="noteMode_entries">
<item>در حالت ویرایش باز کنید</item>
<item>در حالت پیش نمایش باز کنید</item>
<item>آخرین انتخاب من را به خاطر بسپار</item>
</string-array>
- <!-- Array: font size -->
<string-array name="fontSize_entries">
<item>کوچک</item>
<item>متوسط</item>
<item>بزرگ</item>
</string-array>
- <!-- Array: background synchronization -->
<string-array name="sync_entries">
<item>خاموش</item>
<item>۱۵ دقیقه</item>
@@ -144,9 +168,56 @@
<item>پیش فرض سیستم</item>
</string-array>
- <!-- Plurals -->
<plurals name="ab_selected">
<item quantity="one">%d انتخاب شد</item>
<item quantity="other">%d انتخاب شد</item>
</plurals>
+ <string name="formatting_help_cbf_title">قالب‌بندی مبتنی بر متن</string>
+ <string name="formatting_help_cbf_body_1">هدف اصلی از طراحی برنامک یادداشت، ارائه دادن یک ابزار رایگان یادداشت کارها است. همچنین شما قادر خواهید بود متن‌ها را با Markdown قالب‌بندی کنید. برای انواع مختلفی از مثالهای ذکر شده در زیر ، می توانید از میانبرها استفاده کنید تا بتوانید یادداشت های خود را بدون تایپ کد، قالب بندی کنید.</string>
+ <string name="formatting_help_cbf_body_2">فقط کافی است یک دامنه متن را انتخاب کنید یا روی مکان نما در هر موقعیتی ضربه بزنید و یک منوی بازشونده دریافت می کنید که در کنار ورودی‌های پیش‌فرض %1$s و %2$s و %3$s شامل ورودی‌‌هایی مانند %4$s و %5$s می‌باشد.</string>
+
+ <string name="formatting_help_text_title">متن</string>
+ <string name="formatting_help_text_body">به راحتی می‌توان با Markdown کلمات را به حالت %1$sbold%1$s و کلمات دیگر را به حالت %2$sitalic%2$s درآورد. همچنین می‌توانید کلمات را به حالت %3$sstrike%3$s وحتی به صورت [link to Nextcloud](https://nextcloud.com) درآورید:</string>
+
+ <string name="formatting_help_lists_title">فهرست</string>
+ <string name="formatting_help_lists_body_1">زمانی که قصد استفاده از فهرست با شماره دارید:</string>
+ <string name="formatting_help_lists_body_2">" یک"</string>
+ <string name="formatting_help_lists_body_3">" دو"</string>
+ <string name="formatting_help_lists_body_4">" سه"</string>
+ <string name="formatting_help_lists_body_5">زمانی که شما قصد گذاشتن بولت پوینت دارید:</string>
+ <string name="formatting_help_lists_body_6">شروع خط با خط‌ تیره</string>
+ <string name="formatting_help_lists_body_7">اگر قصد گذاشتن ساب‌پونت دارید، قبل از خط تیره یا ستاره، به اندازه ۲ کاراکتر فضای خالی قرار دهید:</string>
+ <string name="formatting_help_lists_body_8">مانند این</string>
+ <string name="formatting_help_lists_body_9">و این</string>
+
+ <string name="formatting_help_checkboxes_title">جعبه علامت</string>
+ <string name="formatting_help_checkboxes_body_1">برای ساختن جعبه ‌علامت در ابتدای اجزای فهرست، براکت قرار دهید:</string>
+ <string name="formatting_help_checkboxes_body_2">ایتم 1</string>
+ <string name="formatting_help_checkboxes_body_3">ایتم 2</string>
+
+ <string name="formatting_help_structured_documents_title">ساختار مستند‌ها</string>
+ <string name="formatting_help_structured_documents_body_1">" گاهی اوقات برای بهسازی ساختار مستند‌های خود، بهتر است که سرفصل‌های موجود در مستند را در سطوح متفاوتی داشته باشیم. برای ایجاد سرفصل‌ها در متون، باید ابتدای خط‌ها را با یک %1$s آغاز کنیم. استفاده از چند %2$s در یک ردیف، نمایان‌گر سطوح پایین‌تر سرفصل‌ها با اندازه کوچکتر است."</string>
+ <string name="formatting_help_structured_documents_body_2">برای نمونه این متن یک سرفصل لایه سوم است</string>
+ <string name="formatting_help_structured_documents_body_3">می‌توان از یک علامت %1$s تا شش علامت %2$s برای نمایش اندازه‌های مختلف سرفصل‌ها استفاده کرد.</string>
+ <string name="formatting_help_structured_documents_body_4">اگر شما تمایل دارید نقل قول از شخصی بگذارید، قبل از شروع خط، از کاراکتر > استفاده کنید:</string>
+ <string name="formatting_help_structured_documents_body_5">تصور، از دانش مهم‌تر است. دانش، محدود است. تخیل، دنیا را احاطه می‌کند.</string>
+ <string name="formatting_help_structured_documents_body_6">- آلبرت انیشتین</string>
+
+ <string name="formatting_help_code_title">کد</string>
+ <string name="formatting_help_code_body_1">راه‌های مختلفی برای قرار‌دادن کد در Markdown وجود دارد. اگر شما قصد قرار دادن بلوک‌های کد در داخل متون را دارید، آنها را بین دو ` قرار دهید.</string>
+ <string name="formatting_help_code_body_2">همچنین Markdown قادر به پشتیبانی از code fencing می‌باشد، چیزی که به شما اجازه قرار‌دادن چندین خط، بدون تورفتگی را می‌دهد:</string>
+ <string name="formatting_help_code_body_3">اگر شما نیاز به مشخص کردن syntax در یک زبان دارید:</string>
+
+ <string name="formatting_help_tables_title">جدول‌ها</string>
+ <string name="formatting_help_images_title">تصاویر</string>
+ <string name="formatting_help_images_alt">تصویر فانتزی</string>
+
+ <string name="simple_other">دیگر</string>
+ <string name="sort_last_modified">مرتب‌سازی طبق تاریخ</string>
+ <string name="sort_alphabetically">مرتب‌سازی طبق الفبا</string>
+ <string name="error_action_open_battery_settings">تنظیمات باتری</string>
+ <string name="error_action_open_deck_info">باز کردن اطلاعات برنامه</string>
+ <string name="error_action_open_network">تنظیمات شبکه</string>
+ <string name="no_other_accounts">شما تاکنون هیچ حساب کاربری دیگری را ایجاد نکرده‌اید.</string>
+ <string name="context_based_formatting">بازپخش قالب بندی مبتنی بر متن</string>
</resources>
diff --git a/app/src/main/res/values-fi-rFI/strings.xml b/app/src/main/res/values-fi-rFI/strings.xml
index 2afc9194..0a20aace 100644
--- a/app/src/main/res/values-fi-rFI/strings.xml
+++ b/app/src/main/res/values-fi-rFI/strings.xml
@@ -232,4 +232,4 @@
<string name="error_action_open_deck_info">Avaa sovelluksen tiedot</string>
<string name="error_action_open_network">Verkkoasetukset</string>
<string name="no_other_accounts">Et ole vielä määrittänyt muita tilejä.</string>
-</resources>
+ </resources>
diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml
index 2604ae27..a879a96d 100644
--- a/app/src/main/res/values-fr/strings.xml
+++ b/app/src/main/res/values-fr/strings.xml
@@ -189,6 +189,7 @@
<string name="formatting_help_codefence_inline" translateable="false">`%1$s`</string>
<string name="formatting_help_codefence_inline_escaped" translateable="false">\\`%1$s\\`</string>
<string name="formatting_help_codefence" translateable="false">```</string>
+ <string name="formatting_help_codefence_outer" translateable="false">````</string>
<string name="formatting_help_codefence_javascript" translateable="false">```javascript</string>
<string name="formatting_help_cbf_title">Mise en forme contextuelle</string>
<string name="formatting_help_cbf_body_1">Un but majeur de l\'app Notes est de fournir une application de note sans distraction, bien que vous pussiez formater vos textes avec Markdown. Pour les divers exemples mentionnés ci-dessous, vous pouvez utiliser des raccourcis afin de pouvoir formater vos notes sans taper les codes ci-dessous. </string>
@@ -226,11 +227,22 @@
<string name="formatting_help_code_body_2">Markdown supporte aussi quelque chose appelé \"code fencing\", qui permet plusieurs lignes sans indentation.</string>
<string name="formatting_help_code_body_3">Et si vous voulez utiliser la coloration syntaxique, incluez le langage.</string>
+ <string name="formatting_help_tables_title">Tableaux</string>
+ <!-- Column header of a sample table -->
+ <string name="formatting_help_tables_column">Colonne %1d</string>
+ <!-- Table cell value of a sample table -->
+ <string name="formatting_help_tables_value">Valeur %1d</string>
+
+ <string name="formatting_help_images_title">Images</string>
+ <string name="formatting_help_images_alt">Image retouchée</string>
+
<string name="simple_other">Divers</string>
<string name="sort_last_modified">Tirer par date de dernière modification</string>
<string name="sort_alphabetically">Trier alphabétiquement</string>
<string name="error_action_open_battery_settings">Paramètres de batterie</string>
<string name="error_action_open_deck_info">Ouvrir les informations de l\'application</string>
<string name="error_action_open_network">Paramètres réseau</string>
+ <string name="no_account_configured_yet">Aucun compte n\'est encore configuré</string>
<string name="no_other_accounts">Vous n\'avez pas encore configuré d\'autres comptes.</string>
+ <string name="context_based_formatting">Suggestions de mise en forme contextuelle</string>
</resources>
diff --git a/app/src/main/res/values-gl/strings.xml b/app/src/main/res/values-gl/strings.xml
index f90b703c..07dab5e3 100644
--- a/app/src/main/res/values-gl/strings.xml
+++ b/app/src/main/res/values-gl/strings.xml
@@ -189,6 +189,7 @@
<string name="formatting_help_codefence_inline" translateable="false">«%1$s»</string>
<string name="formatting_help_codefence_inline_escaped" translateable="false">«%1$s»</string>
<string name="formatting_help_codefence" translateable="false">```</string>
+ <string name="formatting_help_codefence_outer" translateable="false">````</string>
<string name="formatting_help_codefence_javascript" translateable="false">```javascript</string>
<string name="formatting_help_cbf_title">Formatado baseado no contexto</string>
<string name="formatting_help_cbf_body_1">Un dos principais obxectivos de deseño da aplicación Notes é fornecer unha ferramenta sen distracción. Aínda que poderá formatar os seus textos con Markdown. Para varios dos exemplos mencionados deseguido, pode utilizar atallos de teclado para poder formatar as súas notas sen escribir os códigos de embaixo.</string>
@@ -226,11 +227,22 @@
<string name="formatting_help_code_body_2">Markdown tamén admite algo chamado «código cercado», que permite múltiples liñas sen sangría:</string>
<string name="formatting_help_code_body_3">E se quere utilizar o destaque de sintaxe, inclúa a linguaxe:</string>
+ <string name="formatting_help_tables_title">Táboas</string>
+ <!-- Column header of a sample table -->
+ <string name="formatting_help_tables_column">Columna %1d</string>
+ <!-- Table cell value of a sample table -->
+ <string name="formatting_help_tables_value">Valor %1d</string>
+
+ <string name="formatting_help_images_title">Imaxes</string>
+ <string name="formatting_help_images_alt">Imaxe elegante</string>
+
<string name="simple_other">Outro</string>
<string name="sort_last_modified">Ordenar por data de modificación</string>
<string name="sort_alphabetically">Ordenar alfabéticamente</string>
<string name="error_action_open_battery_settings">Axustes da batería</string>
<string name="error_action_open_deck_info">Abrir a info da apli</string>
<string name="error_action_open_network">Axustes da rede</string>
+ <string name="no_account_configured_yet">Aínda non hai ningunha conta configurada</string>
<string name="no_other_accounts">Aínda non ten configurada ningunha outra conta.</string>
+ <string name="context_based_formatting">Xanela emerxente de formato baseado no contexto</string>
</resources>
diff --git a/app/src/main/res/values-hr/strings.xml b/app/src/main/res/values-hr/strings.xml
index 7a3f29ae..72aa1ce9 100644
--- a/app/src/main/res/values-hr/strings.xml
+++ b/app/src/main/res/values-hr/strings.xml
@@ -237,4 +237,4 @@
<string name="error_action_open_deck_info">Otvori informacije o aplikaciji</string>
<string name="error_action_open_network">Postavke mreže</string>
<string name="no_other_accounts">Nemate konfiguriranih računa.</string>
-</resources>
+ </resources>
diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml
index 6a063c1a..ef8ac5f7 100644
--- a/app/src/main/res/values-it/strings.xml
+++ b/app/src/main/res/values-it/strings.xml
@@ -189,6 +189,7 @@
<string name="formatting_help_codefence_inline" translateable="false">`%1$s`</string>
<string name="formatting_help_codefence_inline_escaped" translateable="false">\\`%1$s\\`</string>
<string name="formatting_help_codefence" translateable="false">```</string>
+ <string name="formatting_help_codefence_outer" translateable="false">````</string>
<string name="formatting_help_codefence_javascript" translateable="false">```javascript</string>
<string name="formatting_help_cbf_title">Formattazione basata sul contesto</string>
<string name="formatting_help_cbf_body_1">Un obiettivo fondamentale dell\'applicazione Note è di fornire uno strumento senza distrazioni. Potrai comunque formattare i tuoi testi con Markdown. Per i vari esempi sotto indicati, puoi usare le scorciatoie in modo da formattare le note senza digitare i codici sottostanti.</string>
@@ -226,11 +227,22 @@
<string name="formatting_help_code_body_2">Markdown supporta anche raggruppamenti di codice, che consente a righe multiple senza indentazione:</string>
<string name="formatting_help_code_body_3">E se desideri utilizzare l\'evidenziazione della sintassi, includi il linguaggio:</string>
+ <string name="formatting_help_tables_title">Tabelle</string>
+ <!-- Column header of a sample table -->
+ <string name="formatting_help_tables_column">Colonna %1d</string>
+ <!-- Table cell value of a sample table -->
+ <string name="formatting_help_tables_value">Valore %1d</string>
+
+ <string name="formatting_help_images_title">Immagini</string>
+ <string name="formatting_help_images_alt">Immagine di fantasia</string>
+
<string name="simple_other">Altro</string>
<string name="sort_last_modified">Ordina per data di modifica</string>
<string name="sort_alphabetically">Ordine alfabetico</string>
<string name="error_action_open_battery_settings">Impostazioni batteria</string>
<string name="error_action_open_deck_info">Apri informazioni applicazione</string>
<string name="error_action_open_network">Impostazioni di rete</string>
+ <string name="no_account_configured_yet">Ancora nessun account configurato</string>
<string name="no_other_accounts">Non hai configurato ancora alcun account.</string>
+ <string name="context_based_formatting">Finestra di formattazione basata sul contesto</string>
</resources>
diff --git a/app/src/main/res/values-ja-rJP/strings.xml b/app/src/main/res/values-ja-rJP/strings.xml
index d0a2f974..1aedf33f 100644
--- a/app/src/main/res/values-ja-rJP/strings.xml
+++ b/app/src/main/res/values-ja-rJP/strings.xml
@@ -229,4 +229,4 @@
<string name="error_action_open_deck_info">アプリ情報を開く</string>
<string name="error_action_open_network">ネットワーク設定</string>
<string name="no_other_accounts">他のアカウントはまだ設定されていません。</string>
-</resources>
+ </resources>
diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml
index f0d81b09..39f41db0 100644
--- a/app/src/main/res/values-ko/strings.xml
+++ b/app/src/main/res/values-ko/strings.xml
@@ -222,6 +222,15 @@
<string name="formatting_help_code_body_2">Markdown은 코드 펜싱이라는 것을 지원하여 들여쓰기 없이 여러 줄을 허용합니다.</string>
<string name="formatting_help_code_body_3">구문 강조 표시를 사용하려면 다음 언어를 포함합니다.</string>
+ <string name="formatting_help_tables_title">표</string>
+ <!-- Column header of a sample table -->
+ <string name="formatting_help_tables_column">열%1d</string>
+ <!-- Table cell value of a sample table -->
+ <string name="formatting_help_tables_value">값%1d</string>
+
+ <string name="formatting_help_images_title">이미지</string>
+ <string name="formatting_help_images_alt">멋진 이미지</string>
+
<string name="simple_other">기타</string>
<string name="sort_last_modified">수정된 날짜로 정렬</string>
<string name="sort_alphabetically">알파벳순으로 정렬</string>
@@ -229,4 +238,5 @@
<string name="error_action_open_deck_info">앱 정보 열기</string>
<string name="error_action_open_network">네트워크 환경설정</string>
<string name="no_other_accounts">아직 다른 계정을 구성하지 않았습니다.</string>
+ <string name="context_based_formatting">컨텍스트 기반의 양식 팝오버</string>
</resources>
diff --git a/app/src/main/res/values-lt-rLT/strings.xml b/app/src/main/res/values-lt-rLT/strings.xml
index b8cdd8d8..3544df8f 100644
--- a/app/src/main/res/values-lt-rLT/strings.xml
+++ b/app/src/main/res/values-lt-rLT/strings.xml
@@ -221,4 +221,4 @@
<string name="error_action_open_deck_info">Atidaryti programos informaciją</string>
<string name="error_action_open_network">Tinklo nustatymai</string>
<string name="no_other_accounts">Dar nesukonfigūravote kitų paskyrų.</string>
-</resources>
+ </resources>
diff --git a/app/src/main/res/values-nb-rNO/strings.xml b/app/src/main/res/values-nb-rNO/strings.xml
index 8aafe894..e07a6dc7 100644
--- a/app/src/main/res/values-nb-rNO/strings.xml
+++ b/app/src/main/res/values-nb-rNO/strings.xml
@@ -213,6 +213,13 @@
<string name="formatting_help_code_body_2">Markdown støtter også noe som kalles kodegjerding, som tillater flere linjer uten innrykk:</string>
<string name="formatting_help_code_body_3">Og hvis du vil bruke syntaksmarkering, inkluder språket:</string>
+ <string name="formatting_help_tables_title">Tabeller</string>
+ <!-- Column header of a sample table -->
+ <string name="formatting_help_tables_column">Kolonne%1d</string>
+ <!-- Table cell value of a sample table -->
+ <string name="formatting_help_tables_value">Verdi %1d</string>
+
+ <string name="formatting_help_images_title">Bilder</string>
<string name="simple_other">Annet</string>
<string name="sort_last_modified">Sorter etter dato endret</string>
<string name="sort_alphabetically">Sorter alfabetisk</string>
@@ -220,4 +227,4 @@
<string name="error_action_open_deck_info">Åpne App info</string>
<string name="error_action_open_network">Nettverksinnstillinger</string>
<string name="no_other_accounts">Du har ikke konfigurert noen konto enda.</string>
-</resources>
+ </resources>
diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml
index 48327065..e6d8e445 100644
--- a/app/src/main/res/values-nl/strings.xml
+++ b/app/src/main/res/values-nl/strings.xml
@@ -189,6 +189,7 @@
<string name="formatting_help_codefence_inline" translateable="false">`%1$s`</string>
<string name="formatting_help_codefence_inline_escaped" translateable="false">\\`%1$s\\`</string>
<string name="formatting_help_codefence" translateable="false">```</string>
+ <string name="formatting_help_codefence_outer" translateable="false">````</string>
<string name="formatting_help_codefence_javascript" translateable="false">```javascript</string>
<string name="formatting_help_cbf_title">Opmaat context gebaseerd</string>
<string name="formatting_help_cbf_body_1">Het ontwerpdoel van de Notes-app is om een afleidingsvrij hulpmiddel te bieden. Maar je kunt altijd je teksten opmaken met Markdown. Voor verschillende van de onderstaande voorbeelden kunt je snelcodes gebruiken, zodat je notities kunt opmaken zonder de onderstaande codes in te typen.</string>
@@ -226,11 +227,22 @@
<string name="formatting_help_code_body_2">Markdown ondersteunt ook iets dat \"code fencing\" wordt genoemd, wat meerdere regels mogelijk maakt zonder inspringen:</string>
<string name="formatting_help_code_body_3">En als je syntaxisaccentuering wilt gebruiken, neemt dan deze taal op:</string>
+ <string name="formatting_help_tables_title">Tabellen</string>
+ <!-- Column header of a sample table -->
+ <string name="formatting_help_tables_column">Kolom %1d</string>
+ <!-- Table cell value of a sample table -->
+ <string name="formatting_help_tables_value">Waarde %1d</string>
+
+ <string name="formatting_help_images_title">Afbeeldingen</string>
+ <string name="formatting_help_images_alt">Leuke afbeelding</string>
+
<string name="simple_other">Ander</string>
<string name="sort_last_modified">Op wijzigingsdatum sorteren</string>
<string name="sort_alphabetically">Op alfabet sorteren</string>
<string name="error_action_open_battery_settings">Batterij instellingen</string>
<string name="error_action_open_deck_info">Open App informatie</string>
<string name="error_action_open_network">Netwerk instellingen</string>
+ <string name="no_account_configured_yet">Nog geen account geconfigureerd</string>
<string name="no_other_accounts">U heeft nog geen andere accounts geconfigureerd.</string>
+ <string name="context_based_formatting">Context gebaseerde formatterings-popover</string>
</resources>
diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml
index b0334cb4..b627de18 100644
--- a/app/src/main/res/values-pl/strings.xml
+++ b/app/src/main/res/values-pl/strings.xml
@@ -197,6 +197,7 @@
<string name="formatting_help_codefence_inline" translateable="false">`%1$s`</string>
<string name="formatting_help_codefence_inline_escaped" translateable="false">\\`%1$s\\`</string>
<string name="formatting_help_codefence" translateable="false">```</string>
+ <string name="formatting_help_codefence_outer" translateable="false">````</string>
<string name="formatting_help_codefence_javascript" translateable="false">```javascript</string>
<string name="formatting_help_cbf_title">Formatowanie kontekstowe</string>
<string name="formatting_help_cbf_body_1">Głównym celem projektowym aplikacji Notes jest zapewnienie narzędzia bez rozpraszania uwagi. Chociaż będziesz mógł sformatować swoje teksty za pomocą Markdown. W przypadku różnych wymienionych poniżej przykładów możesz użyć skrótów, dzięki czemu możesz sformatować swoje notatki bez wpisywania poniższych kodów.</string>
@@ -234,11 +235,22 @@
<string name="formatting_help_code_body_2">Markdown obsługuje również coś, co nazywa się szermierką kodu, która pozwala na wiele linii bez wcięć:</string>
<string name="formatting_help_code_body_3">A jeśli chcesz użyć podświetlania składni, uwzględnij język:</string>
+ <string name="formatting_help_tables_title">Tabele</string>
+ <!-- Column header of a sample table -->
+ <string name="formatting_help_tables_column">Kolumna %1d</string>
+ <!-- Table cell value of a sample table -->
+ <string name="formatting_help_tables_value">Wartość %1d</string>
+
+ <string name="formatting_help_images_title">Obrazy</string>
+ <string name="formatting_help_images_alt">Fantazyjny obraz</string>
+
<string name="simple_other">Inne</string>
<string name="sort_last_modified">Sortuj według daty modyfikacji</string>
<string name="sort_alphabetically">Sortuj alfabetycznie</string>
<string name="error_action_open_battery_settings">Ustawienia baterii</string>
<string name="error_action_open_deck_info">Otwórz informacje o aplikacji</string>
<string name="error_action_open_network">Ustawienia sieci</string>
+ <string name="no_account_configured_yet">Nie skonfigurowano jeszcze konta</string>
<string name="no_other_accounts">Nie masz jeszcze skonfigurowanych żadnych innych kont.</string>
+ <string name="context_based_formatting">Okno podręczne formatowania opartego na kontekście</string>
</resources>
diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml
index 5f2e0e58..ce947069 100644
--- a/app/src/main/res/values-pt-rBR/strings.xml
+++ b/app/src/main/res/values-pt-rBR/strings.xml
@@ -189,6 +189,7 @@
<string name="formatting_help_codefence_inline" translateable="false">`%1$s`</string>
<string name="formatting_help_codefence_inline_escaped" translateable="false">\\`%1$s\\`</string>
<string name="formatting_help_codefence" translateable="false">```</string>
+ <string name="formatting_help_codefence_outer" translateable="false">````</string>
<string name="formatting_help_codefence_javascript" translateable="false">```javascript</string>
<string name="formatting_help_cbf_title">Formatação baseada em contexto</string>
<string name="formatting_help_cbf_body_1">Um dos principais objetivos de design do aplicativo Notes é fornecer uma ferramenta sem distrações. Então você pode formatar seus textos com o Markdown. Para vários dos exemplos mencionados abaixo, você pode usar atalhos para formatar suas anotações sem digitar os códigos abaixo.</string>
@@ -224,7 +225,16 @@
<string name="formatting_help_code_title">Código</string>
<string name="formatting_help_code_body_1">Existem muitas maneiras diferentes de estilizar o código com o Markdown. Se você tiver blocos de códigos embutidos, envolva-os em barras de proteção:</string>
<string name="formatting_help_code_body_2">O Markdown também suporta algo chamado código de cercas, que permite várias linhas sem recuo:</string>
- <string name="formatting_help_code_body_3">E se você quiser usar destaque de sintaxe, inclua a linguagem:</string>
+ <string name="formatting_help_code_body_3">E se você quiser destacar a sintaxe, inclua a linguagem:</string>
+
+ <string name="formatting_help_tables_title">Tabelas</string>
+ <!-- Column header of a sample table -->
+ <string name="formatting_help_tables_column">Coluna %1d</string>
+ <!-- Table cell value of a sample table -->
+ <string name="formatting_help_tables_value">Valor %1d</string>
+
+ <string name="formatting_help_images_title">Imagens</string>
+ <string name="formatting_help_images_alt">Imagens bonita</string>
<string name="simple_other">Outro</string>
<string name="sort_last_modified">Ordenar por data de modificação</string>
@@ -232,5 +242,7 @@
<string name="error_action_open_battery_settings">Configurações da bateria</string>
<string name="error_action_open_deck_info">Abra as informações do Aplicativo</string>
<string name="error_action_open_network">Configurações da rede</string>
+ <string name="no_account_configured_yet">Nenhuma conta foi configurada</string>
<string name="no_other_accounts">Você ainda não configurou nenhuma outra conta.</string>
+ <string name="context_based_formatting">Formatação baseada no contexto popover</string>
</resources>
diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml
index 49967924..c965e6df 100644
--- a/app/src/main/res/values-ru/strings.xml
+++ b/app/src/main/res/values-ru/strings.xml
@@ -241,4 +241,4 @@
<string name="error_action_open_deck_info">Открыть информацию о приложении</string>
<string name="error_action_open_network">Параметры сети</string>
<string name="no_other_accounts">Вы еще не настроили ни одного аккаунта</string>
-</resources>
+ </resources>
diff --git a/app/src/main/res/values-sc/strings.xml b/app/src/main/res/values-sc/strings.xml
new file mode 100644
index 00000000..61c47d2f
--- /dev/null
+++ b/app/src/main/res/values-sc/strings.xml
@@ -0,0 +1,248 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+ <string name="app_name">Notas</string>
+ <string name="app_name_long">Notas de Nextcloud</string>
+ <string name="label_all_notes">Totu is notas</string>
+ <string name="label_favorites">Preferidos</string>
+ <string name="action_create">Notas noas</string>
+ <string name="action_settings">Cunfiguratziones</string>
+ <string name="action_trashbin">Notas cantzelladas</string>
+ <string name="action_search">Chirca</string>
+ <string name="action_sorting_method">Mètodu de ordinamentu</string>
+ <string name="simple_cancel">Cantzella</string>
+ <string name="simple_edit">Modìfica</string>
+ <string name="action_edit_save">Sarva</string>
+ <string name="simple_about">In contu de</string>
+ <string name="simple_link">Ligòngiu</string>
+ <string name="action_note_deleted">Cantzelladu %1$s</string>
+ <string name="action_note_restored">Recuperadu %1$s</string>
+ <string name="action_undo">Annulla</string>
+ <string name="action_uncategorized">Sena categoria</string>
+ <string name="menu_delete">Cantzella</string>
+ <string name="menu_change_category">Categoria</string>
+ <string name="menu_favorite">Preferidu</string>
+ <string name="menu_preview">Anteprima</string>
+ <string name="menu_share">Cumpartzi</string>
+
+ <string name="search_in_category">Chirca in %1$s</string>
+ <string name="search_in_all">Chirca totu is notas</string>
+
+ <string name="change_category_title">Sèbera una categoria</string>
+
+ <string name="listview_updated_today">Oe</string>
+ <string name="listview_updated_yesterday">Eris</string>
+ <string name="listview_updated_this_week">Custa chida</string>
+ <string name="listview_updated_last_week">Sa chida passada</string>
+ <string name="listview_updated_this_month">Custu mese</string>
+ <string name="listview_updated_last_month">Su mese passadu</string>
+
+ <string name="settings_note_mode">Modalidades de visualizatzione de is notas</string>
+ <string name="settings_theme_title">Tema</string>
+ <string name="settings_font_title">Caràtere a ispatziadura fissa</string>
+ <string name="settings_font_size">Dimensione caràtere</string>
+ <string name="settings_wifi_only">Sincroniza isceti cun su Wi-Fi</string>
+ <string name="settings_lock">Bardiadura cun crae</string>
+ <string name="settings_background_sync">Sincronizatzione isfundu</string>
+
+ <string name="error_sync">Sincronizatzione faddida: %1$s</string>
+ <string name="error_synchronization">Sincronizatzione faddida</string>
+ <string name="error_no_network">Peruna connessione de rete</string>
+ <string name="error_unknown">Ddoe at àpidu un\'errore disconnotu.</string>
+
+ <string name="about_version_title">Versione</string>
+ <string name="about_version">Como ses impreende &lt;strong>%1$s&lt;/strong></string>
+ <string name="about_maintainer_title">Responsàbile</string>
+ <string name="about_developers_title">Isvilupadores</string>
+ <string name="about_translators_title">Tradutores</string>
+ <string name="about_translators_transifex">Sa comunidade Nextcloud in &lt;a href=\"%1$s\">Transifex&lt;/a></string>
+ <string name="about_testers_title">Collaudadores</string>
+ <string name="about_source_title">Còdighe fonte</string>
+ <string name="about_source">Custu progetu nch\'est allogadu in GitHub: &lt;a href=\"%1$s\">%1$s&lt;/a></string>
+ <string name="about_issues_title">Problemas</string>
+ <string name="about_issues">Podes sinnalare unu problema, fàghere propostas de megioramentu e rechestas de funtzionalidades a su rilevadore de problemas de GitHub: &lt;a href=\"%1$s\">%1$s&lt;/a></string>
+ <string name="about_translate_title">Borta</string>
+ <string name="about_translate">Intra a s\'iscuadra de Nextcloud in Transifex e agiuda·nos a bortare custa aplicatzione: &lt;a href=\"%1$s\">%1$s&lt;/a></string>
+ <string name="about_app_license_title">Lissèntzia</string>
+ <string name="about_app_license">Custa aplicatzione est suta lissèntzia GNU GENERAL PUBLIC LICENSE v3+.</string>
+ <string name="about_app_license_button">Càstia lissèntzia</string>
+ <string name="about_icons_disclaimer_title">Iconas</string>
+ <string name="about_icons_disclaimer">&lt;p>Icona originale realizada cun %1$s&lt;/p>&lt;p>Totu is iconas in prus impreadas dae custa aplicatzione sunt &lt;a href=\"https://materialdesignicons.com/\">Iconas Material Design &lt;/a> creadas dae Google Inc. e suta lissèntzia Apache 2.0 License.&lt;/p></string>
+ <string name="about_credits_tab_title">Crèditos</string>
+ <string name="about_contribution_tab_title">Contributos</string>
+ <string name="about_license_tab_title">Lissèntzia</string>
+
+ <string name="widget_note_list_title">Lista de notas</string>
+ <string name="widget_note_list_placeholder">Peruna nota</string>
+ <string name="widget_single_note_title">Nota sìngula</string>
+ <string name="widget_single_note_placeholder_tv">Nota no agatada</string>
+ <string name="widget_create_note">Crea Nota</string>
+ <string name="widget_not_logged_in">Incarca su butone + pro creare una nota noa</string>
+ <string name="widget_entry_fav_contentDescription">S\'icona de s\'isteddu s\'impreat pro marcare un\'elementu comente preferidu</string>
+ <string name="widget_app_launcher_contentDescription">Avia aplicatzione</string>
+
+ <string name="activity_select_single_note">Seletziona nota</string>
+
+ <string name="shortcut_create_long">Crea una nota noa</string>
+
+ <string name="pref_value_font_normal">Normale</string>
+ <string name="pref_value_wifi_and_mobile">Sincroniza cun Wi-Fi e datos mòbiles</string>
+ <string name="pref_value_lock">Bardiadura cun crae</string>
+
+ <string name="simple_error">Errore</string>
+ <string name="simple_close">Serra</string>
+ <string name="simple_copy">Còpia</string>
+ <string name="simple_exception">Etzetzione</string>
+ <string name="pin_to_homescreen">Apìtziga a s\'ischermada initziale</string>
+ <string name="note_has_been_deleted">Custa nota est istada cantzellada</string>
+ <string name="add_account">Agiunghe contu</string>
+ <string name="category_music">Mùsica</string>
+ <string name="category_movies">Film</string>
+ <string name="category_movie">Film</string>
+ <string name="category_work">Traballu</string>
+ <string name="account_already_imported">Su contu nch\'est giai importadu</string>
+ <string name="no_notes_yet">Peruna nota ancora</string>
+ <string name="no_notes_yet_description">Incarca su butone + pro creare una nota noa</string>
+ <string name="simple_more">Àteru</string>
+ <string name="simple_move">Tràmuda</string>
+ <string name="category_readonly">Letura ebbia</string>
+ <string name="no_category">Peruna categoria</string>
+ <string name="add_category">Agiunghe %1$s</string>
+ <string name="simple_checkbox">Casella de seletzione</string>
+ <string name="unlock_notes">Isbloca notas</string>
+ <string name="simple_beta">Beta</string>
+ <string name="error_dialog_title">Oh no - Immoe ite ddoe at? 🙁</string>
+ <string name="error_dialog_tip_token_mismatch_retry">Proa a serrare a fortza s\'aplicatzione e torrala a aviare. Fortzis ddoe at àpidu unu problema de connessione a s\'aplicatzione de Nextcloud. </string>
+ <string name="error_dialog_tip_token_mismatch_clear_storage">Si sighit su problema, proa a cantzellare s\'archiviatzione de ambas is aplicatziones Nextcloud e Nextcloud Notes pro isorvere su problema.</string>
+ <string name="error_dialog_tip_clear_storage">Podes limpiare s\'archiviatzione aberende is informatziones de s\'aplicatzione e seberende Archiviatzione → Lìmpia archiviatzione.</string>
+ <string name="error_dialog_tip_files_outdated">S\'aplicatzione tua de Nextcloud paret foras d\'usu. Pro praghere, bìsita su Play Store o F-Droid pro otènnere s\'ùrtima versione.</string>
+ <string name="error_dialog_tip_files_force_stop">Paret chi b\'at àpidu problemas cun s\'aplicatzione de Nextcloud. Pro praghere proa a ddas firmare ambas, s\'aplicatzione Nextcloud e s\'aplicatzione Nexcloud Notes. </string>
+ <string name="error_dialog_tip_files_delete_storage">Si a ddas firmare a fortza no agiudat, podes proare a limpiare s\'archiviatzione de ambas is aplicatziones.</string>
+ <string name="error_dialog_timeout_instance">Non ddoe at àpidu peruna risposta dae su serbidore in su tempus istabilidu. Segura·ti chi sa rechesta tua siat esecutada in manera curreta.</string>
+ <string name="error_dialog_timeout_toggle">Controlla sa connesione tua a sa rete. A bortas podet agiudare a disativare is datos mòbiles o su Wi-Fi e a ddos torrare a ativare.</string>
+ <string name="error_dialog_check_server">Sa risposta de su serbidore tuo non fiat curreta. Controlla su podet atzèdere a is notas tuas tràmite interfache web.</string>
+ <string name="error_dialog_check_server_logs">Ddoe at unu problema cun s\'installatzione tua de Nextcloud. Pro praghere càstia in is archìvios de registru de su serbidore.</string>
+ <string name="error_dialog_check_maintenance">Controlla chi s\'istantza tua de Nextcloud non siat in fase de mantenimentu.</string>
+ <string name="error_dialog_insufficient_storage">In su Nextcloud tuo non ddoe at prus logu lìberu. Pro praghere cantzella unos cantos archìvios pro sincronizare is modìficas locales tuas con sa nue virtuale.</string>
+ <string name="error_dialog_contact_us">Pro praghere no istentes a nos cuntatare si su problema sighit. Podes agatare is informatziones de cuntatu nostras in sa setzione Informatziones in sa barra laterale.</string>
+ <string name="error_dialog_we_need_info">Nos bisòngiant is sighentes informatziones tècnicas pro t\'agiuare:</string>
+ <string name="error_dialog_server_app_enabled">Segurati de àere installadu e abilitadu s\'aplicatzione \"Notes\" in su serbidore tuo.</string>
+ <string name="error_dialog_redirect">Su serbidore tuo at rispostu cun unu còdighe de istadu HTTP 302, chi ìmplicat chi no as installadu s\'aplicatzione Note in su serbidore tuo o calicuna cosa no est cunfigurada in manera curreta. Custu podet èssere dèpidu a cunfiguratziones personalizadas in su documentu .htaccess o a aplicatziones de Nextcloud comente OID Client.</string>
+ <string name="error_dialog_tip_disable_battery_optimizations">Disabilita totu is otimizatziones de sa bateria pro is aplicatziones Nextcloud e Note.</string>
+ <string name="added_content">Agiuntu \"%1$s\"</string>
+ <string name="shared_text_empty">Su testu cumpartzidu fiat bòidu</string>
+ <string name="append_to_note">Agiunghe a sa nota</string>
+ <string name="change_note_title">Càmbia su tìtulu de sa nota</string>
+ <string name="menu_edit_title">Modìfica tìtulu</string>
+ <string name="settings_branding">Marca</string>
+ <string name="settings_gridview">Vista grìllia</string>
+ <string name="simple_security">Seguresa</string>
+ <string name="simple_appearance">Aparèntzia</string>
+ <string name="simple_synchronization">Sincronizatzione</string>
+ <string name="simple_behavior">Cumportamentu</string>
+ <string name="manage_accounts">Gesti contos</string>
+ <string name="action_formatting_help">Formatatzione</string>
+
+ <string-array name="noteMode_entries">
+ <item>Aberi in modalidade modìfica</item>
+ <item>Aberi in modalidade anteprima</item>
+ <item>Regorda s\'ùrtimu sèberu</item>
+ </string-array>
+
+ <string-array name="fontSize_entries">
+ <item>Piticu</item>
+ <item>Mesanu</item>
+ <item>Mannu</item>
+ </string-array>
+
+ <string-array name="sync_entries">
+ <item>Istudadu</item>
+ <item>15 minùtos</item>
+ <item>1 ora</item>
+ <item>6 oras</item>
+ </string-array>
+
+ <string-array name="darkmode_entries">
+ <item>Craru</item>
+ <item>Iscuru</item>
+ <item>Predefinidos de Sistema</item>
+ </string-array>
+
+ <plurals name="ab_selected">
+ <item quantity="one">%d seletzionadu</item>
+ <item quantity="other">%d seletzionados</item>
+ </plurals>
+ <plurals name="bulk_notes_deleted">
+ <item quantity="one">Deleted one note</item>
+ <item quantity="other">Notas %1$d cantzelladas</item>
+ </plurals>
+ <plurals name="bulk_notes_restored">
+ <item quantity="one">Restored one note</item>
+ <item quantity="other">Notas %1$d ripristinadas</item>
+ </plurals>
+ <plurals name="share_multiple">
+ <item quantity="one">Cumpartzi su cuntenutu de sa%1$d nota</item>
+ <item quantity="other">Cumpartzi su cuntenutu de%1$d notas</item>
+ </plurals>
+
+ <string name="formatting_help_divider" translateable="false">---</string>
+ <string name="formatting_help_codefence_inline" translateable="false">`%1$s`</string>
+ <string name="formatting_help_codefence_inline_escaped" translateable="false">\\`%1$s\\`</string>
+ <string name="formatting_help_codefence" translateable="false">```</string>
+ <string name="formatting_help_codefence_outer" translateable="false">````</string>
+ <string name="formatting_help_codefence_javascript" translateable="false">```javascript</string>
+ <string name="formatting_help_cbf_title">Formatatzione basada subra de su cuntenutu</string>
+ <string name="formatting_help_cbf_body_1">Un\'obietivu de importu mannu de s\'aplicatzione Note est su de frunire unu trastu sena distratziones. In cada manera, as a pòdere formatare is testos tuos cun Markdown. Pro is esempros inditados inoghe in bassu, podes impreare is curtziadòrgios pro formatare is notas sena digitare is còdighes in bassu.</string>
+ <string name="formatting_help_cbf_body_2">Ti bastat de seletzionare un\'intervallu de testu o tocare su cursore in cale si siat positzione e at a apàrrere unu menu cun accanta is boghes predefinidas %1$s, %2$s, %3$s elementos comente%4$s o %5$s.</string>
+
+ <string name="formatting_help_text_title">Testu</string>
+ <string name="formatting_help_text_body">Est fàtzile meda a pònnere faeddos in %1$sgrassetu%1$s e àteros faeddos in %2$scursivu%2$s cun Markdown. Como podes %3$sbarrare%3$s calicunos faeddos e puru [link to Nextcloud](https://nextcloud.com).</string>
+
+ <string name="formatting_help_lists_title">Listas</string>
+ <string name="formatting_help_lists_body_1">A bortas ti serbint listas numeradas:</string>
+ <string name="formatting_help_lists_body_2">Unu</string>
+ <string name="formatting_help_lists_body_3">Duos</string>
+ <string name="formatting_help_lists_body_4">Tres</string>
+ <string name="formatting_help_lists_body_5">A bortas ti serbint puntos de elencu:</string>
+ <string name="formatting_help_lists_body_6">Cumintza una lìnia cun unu tretigheddu</string>
+ <string name="formatting_help_lists_body_7">E si tenes suta-puntos, pone duos ispàtzios in antis de su tretigheddu o de s\'asteriscu:</string>
+ <string name="formatting_help_lists_body_8">Comente a custu</string>
+ <string name="formatting_help_lists_body_9">E custu</string>
+
+ <string name="formatting_help_checkboxes_title">Casellas de seletzione</string>
+ <string name="formatting_help_checkboxes_body_1">Pro creare una casella de seletzione, imprea una lista cun in fatu is parèntesis</string>
+ <string name="formatting_help_checkboxes_body_2">Elementu 1</string>
+ <string name="formatting_help_checkboxes_body_3">Elementos 2</string>
+
+ <string name="formatting_help_structured_documents_title">Documentos istruturados</string>
+ <string name="formatting_help_structured_documents_body_1">A bortas cumbenit a tènnere livellos de intestatzione diferentes pro istruturare is documentos tuos. Cumintza is lìnias cun unu %1$s pro creare intestatziones. Prus %2$s in una lìnia inditant un\'intestatzione prus pitica.</string>
+ <string name="formatting_help_structured_documents_body_2">Custa est un\'intestatzione a tres livellos</string>
+ <string name="formatting_help_structured_documents_body_3">Podes impreare dae unu %1$s finas a %2$s ses livellos diferentes de intestatzione.</string>
+ <string name="formatting_help_structured_documents_body_4">Si cheres mentovare a calicunu, imprea su caràtere %1$s in antis de sa lìnia:</string>
+ <string name="formatting_help_structured_documents_body_5">Sa fantasia contat prus de sa connoschèntzia. Sa connoschèntzia est limitada, sa fantasia agollit totu su mundu.</string>
+ <string name="formatting_help_structured_documents_body_6">- Albert Einstein</string>
+
+ <string name="formatting_help_code_title">Còdighe</string>
+ <string name="formatting_help_code_body_1">Ddoe at medas maneras pro modellare s\'istile de su còdighe cun Markdown. Si tenes cantos de còdighe in lìnia, serra·ddos intre cabos invertidos:</string>
+ <string name="formatting_help_code_body_2">Markdown disponet puru de trumas de còdighe, a prus lìnias e sena indentatzione:</string>
+ <string name="formatting_help_code_body_3">E si detzides de impreare su marcadore de sa sintassi, inclue su limbàgiu:</string>
+
+ <string name="formatting_help_tables_title">Tabellas</string>
+ <!-- Column header of a sample table -->
+ <string name="formatting_help_tables_column">Colunna %1d</string>
+ <!-- Table cell value of a sample table -->
+ <string name="formatting_help_tables_value">Balore %1d</string>
+
+ <string name="formatting_help_images_title">Immàgines</string>
+ <string name="formatting_help_images_alt">Immàgine de fantasia</string>
+
+ <string name="simple_other">Àteru</string>
+ <string name="sort_last_modified">Pone in òrdine de data de modìfica</string>
+ <string name="sort_alphabetically">Pone in òrdine alfabèticu</string>
+ <string name="error_action_open_battery_settings">Impostatziones bateria</string>
+ <string name="error_action_open_deck_info">Aberi informatziones aplicatzione</string>
+ <string name="error_action_open_network">Impostatziones de rete</string>
+ <string name="no_account_configured_yet">Perunu contu configuradu ancora</string>
+ <string name="no_other_accounts">No as configuradu perunu contu ancora.</string>
+ <string name="context_based_formatting">Bentana de formatatzione basada subra de su cuntestu</string>
+</resources>
diff --git a/app/src/main/res/values-sk-rSK/strings.xml b/app/src/main/res/values-sk-rSK/strings.xml
index 4999c97c..3b4bf5ca 100644
--- a/app/src/main/res/values-sk-rSK/strings.xml
+++ b/app/src/main/res/values-sk-rSK/strings.xml
@@ -241,4 +241,4 @@
<string name="error_action_open_deck_info">Otvoriť informácie o aplikácii</string>
<string name="error_action_open_network">Nastavenia siete</string>
<string name="no_other_accounts">Zatiaľ nemáte nastavené žiadne ďalšie účty.</string>
-</resources>
+ </resources>
diff --git a/app/src/main/res/values-sl/strings.xml b/app/src/main/res/values-sl/strings.xml
index f53b8c8b..8564afba 100644
--- a/app/src/main/res/values-sl/strings.xml
+++ b/app/src/main/res/values-sl/strings.xml
@@ -197,6 +197,7 @@
<string name="formatting_help_codefence_inline" translateable="false">» %1$s «</string>
<string name="formatting_help_codefence_inline_escaped" translateable="false">\\`%1$s\\`</string>
<string name="formatting_help_codefence" translateable="false">```</string>
+ <string name="formatting_help_codefence_outer" translateable="false">````</string>
<string name="formatting_help_codefence_javascript" translateable="false">```javascript</string>
<string name="formatting_help_cbf_title">Vsebinsko oblikovanje</string>
<string name="formatting_help_cbf_body_1">Najpomembnejša funkcija programa Notes je enostavno in hitro beleženje besedila, ki ga je mogoče tudi oblikovati z oblikovnim jezikom Markdown. Za spodaj omenjeno oblikovanje, je mogoče uporabiti tipkovne bližnjice, kar še dodatno poenostavi vnos..</string>
@@ -234,6 +235,15 @@
<string name="formatting_help_code_body_2">Oblikovni jezik Markdown podpira tudi tako imenovano obrobljanje kode, kar omogoča zapis več vrstic brez zamika:</string>
<string name="formatting_help_code_body_3">Če bi želeli uporabiti poudarjanje skladnje, vključite tudi jezik:</string>
+ <string name="formatting_help_tables_title">Razpredelnice</string>
+ <!-- Column header of a sample table -->
+ <string name="formatting_help_tables_column">Stolpec %1d</string>
+ <!-- Table cell value of a sample table -->
+ <string name="formatting_help_tables_value">Vrednost %1d</string>
+
+ <string name="formatting_help_images_title">Slike</string>
+ <string name="formatting_help_images_alt">Posebna slika</string>
+
<string name="simple_other">Drugo</string>
<string name="sort_last_modified">Razvrsti po datumu spremembe</string>
<string name="sort_alphabetically">Razvrsti abecedno</string>
@@ -241,4 +251,5 @@
<string name="error_action_open_deck_info">Odpri podrobnosti programa</string>
<string name="error_action_open_network">Nastavitve omrežja</string>
<string name="no_other_accounts">Ni nastavljenega nobenega drugega računa</string>
+ <string name="context_based_formatting">Pojavno okno vsebinskega oblikovanja</string>
</resources>
diff --git a/app/src/main/res/values-sr/strings.xml b/app/src/main/res/values-sr/strings.xml
index 02a159a8..2c087a8d 100644
--- a/app/src/main/res/values-sr/strings.xml
+++ b/app/src/main/res/values-sr/strings.xml
@@ -237,4 +237,4 @@
<string name="error_action_open_deck_info">Отвори инфо о апликацији</string>
<string name="error_action_open_network">Поставке мреже</string>
<string name="no_other_accounts">Нисте подесили ниједан други налог.</string>
-</resources>
+ </resources>
diff --git a/app/src/main/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml
index 2722a7bc..4ac8996a 100644
--- a/app/src/main/res/values-sv/strings.xml
+++ b/app/src/main/res/values-sv/strings.xml
@@ -229,4 +229,4 @@
<string name="error_action_open_deck_info">Öppna appinformation</string>
<string name="error_action_open_network">Nätverksinställningar</string>
<string name="no_other_accounts">Du har inte konfigurerat några andra konton än.</string>
-</resources>
+ </resources>
diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml
index edb2487b..16fe5e0a 100644
--- a/app/src/main/res/values-tr/strings.xml
+++ b/app/src/main/res/values-tr/strings.xml
@@ -189,6 +189,7 @@
<string name="formatting_help_codefence_inline" translateable="false">`%1$s`</string>
<string name="formatting_help_codefence_inline_escaped" translateable="false">\\`%1$s\\`</string>
<string name="formatting_help_codefence" translateable="false">```</string>
+ <string name="formatting_help_codefence_outer" translateable="false">````</string>
<string name="formatting_help_codefence_javascript" translateable="false">```javascript</string>
<string name="formatting_help_cbf_title">Bağlama göre biçimlendirme</string>
<string name="formatting_help_cbf_body_1">Notlar uygulamasının önemli bir tasarım amacı, dikkat dağıtmayan bir araç sağlamaktır. Yine de metinlerinizi Markdown kullanarak biçimlendirebilirsiniz. Aşağıdaki örneklerden bazılarında kısayolları kullanarak notlarınızı aşağıdaki kodları yazmadan biçimlendirebilirsiniz.</string>
@@ -226,11 +227,22 @@
<string name="formatting_help_code_body_2">Markdown ayrıca kod çiti olarak adlandırılan ve girinti olmadan birden fazla satıra izin veren bir şeyi destekler:</string>
<string name="formatting_help_code_body_3">Ve söz dizimi vurgulamasını kullanmak istiyorsanız, dili ekleyin:</string>
+ <string name="formatting_help_tables_title">Tablolar</string>
+ <!-- Column header of a sample table -->
+ <string name="formatting_help_tables_column">Sütun: %1d</string>
+ <!-- Table cell value of a sample table -->
+ <string name="formatting_help_tables_value">Değer: %1d</string>
+
+ <string name="formatting_help_images_title">Görseller</string>
+ <string name="formatting_help_images_alt">Süslü görsel</string>
+
<string name="simple_other">Diğer</string>
<string name="sort_last_modified">Değişiklik tarihine göre sırala</string>
<string name="sort_alphabetically">Alfabeye göre sırala</string>
<string name="error_action_open_battery_settings">Pil ayarları</string>
<string name="error_action_open_deck_info">Uygulama bilgilerini aç</string>
<string name="error_action_open_network">Ağ ayarları</string>
+ <string name="no_account_configured_yet">Henüz bir hesap yapılandırılmamış</string>
<string name="no_other_accounts">Henüz başka bir hesap yapılandırmamışsınız.</string>
+ <string name="context_based_formatting">Bağlam tabanlı biçimlendirme açılan penceresi</string>
</resources>
diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml
index 58f978c7..ff778cf8 100644
--- a/app/src/main/res/values-uk/strings.xml
+++ b/app/src/main/res/values-uk/strings.xml
@@ -221,4 +221,4 @@
<string name="error_action_open_deck_info">Відкрити інформацію про застосунок</string>
<string name="error_action_open_network">Налаштування мережі</string>
<string name="no_other_accounts">Ви ще не налаштували жодного іншого облікового запису.</string>
-</resources>
+ </resources>
diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml
index 98aaa507..e1cefcfb 100644
--- a/app/src/main/res/values-zh-rCN/strings.xml
+++ b/app/src/main/res/values-zh-rCN/strings.xml
@@ -185,6 +185,7 @@
<string name="formatting_help_codefence_inline" translateable="false">‘%1$s’</string>
<string name="formatting_help_codefence_inline_escaped" translateable="false">\\`%1$s\\`</string>
<string name="formatting_help_codefence" translateable="false">```</string>
+ <string name="formatting_help_codefence_outer" translateable="false">```` </string>
<string name="formatting_help_codefence_javascript" translateable="false">```javascript</string>
<string name="formatting_help_cbf_title">基于格式的文本</string>
<string name="formatting_help_cbf_body_1">Notes应用程序的主要设计目标是提供无干扰的工具。 因此您将能够使用Markdown设置文本格式。 对于下面提到的各种示例,您可以使用快捷方式,以便无需输入以下代码即可格式化笔记。</string>
@@ -222,11 +223,22 @@
<string name="formatting_help_code_body_2">Markdown支持代码块,可以允许您写数行无格式文本</string>
<string name="formatting_help_code_body_3">如果您想使用代码着色,请在这里设定使用的语言:</string>
+ <string name="formatting_help_tables_title">表格</string>
+ <!-- Column header of a sample table -->
+ <string name="formatting_help_tables_column">列 %1d</string>
+ <!-- Table cell value of a sample table -->
+ <string name="formatting_help_tables_value">值 %1d</string>
+
+ <string name="formatting_help_images_title">图片</string>
+ <string name="formatting_help_images_alt">精致图片</string>
+
<string name="simple_other">其他</string>
<string name="sort_last_modified">按修改日期排序</string>
<string name="sort_alphabetically">按照字母表顺序排序</string>
<string name="error_action_open_battery_settings">电池设置</string>
<string name="error_action_open_deck_info">打开应用信息</string>
<string name="error_action_open_network">网络设置</string>
+ <string name="no_account_configured_yet">尚未配置账户</string>
<string name="no_other_accounts">您尚未配置任何其他帐户。</string>
+ <string name="context_based_formatting">基于上下文的格式弹出窗口 </string>
</resources>
diff --git a/app/src/main/res/values-zh-rHK/strings.xml b/app/src/main/res/values-zh-rHK/strings.xml
new file mode 100644
index 00000000..c6f03157
--- /dev/null
+++ b/app/src/main/res/values-zh-rHK/strings.xml
@@ -0,0 +1,203 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+ <string name="app_name">筆記</string>
+ <string name="app_name_long">Nextcloud 筆記</string>
+ <string name="label_all_notes">所有筆記</string>
+ <string name="label_favorites">我的最愛</string>
+ <string name="action_create">新筆記</string>
+ <string name="action_settings">設定</string>
+ <string name="action_trashbin">已刪除筆記</string>
+ <string name="action_search">搜尋</string>
+ <string name="action_sorting_method">排序方法</string>
+ <string name="simple_cancel">取消</string>
+ <string name="simple_edit">修改</string>
+ <string name="action_edit_save">儲存</string>
+ <string name="simple_about">關於</string>
+ <string name="simple_link">連結</string>
+ <string name="action_note_deleted">已刪除 %1$s</string>
+ <string name="action_note_restored">已還原 %1$s</string>
+ <string name="action_undo">上一步</string>
+ <string name="action_uncategorized">未分類</string>
+ <string name="menu_delete">刪除</string>
+ <string name="menu_change_category">分類</string>
+ <string name="menu_favorite">我的最愛</string>
+ <string name="menu_preview">預覽</string>
+ <string name="menu_share">分享</string>
+
+ <string name="search_in_category">在 %1$s 中搜尋</string>
+ <string name="search_in_all">搜尋所有的筆記</string>
+
+ <string name="change_category_title">選一個分類</string>
+
+ <string name="listview_updated_today">今日</string>
+ <string name="listview_updated_yesterday">昨日</string>
+ <string name="listview_updated_this_week">本星期</string>
+ <string name="listview_updated_last_week">上星期</string>
+ <string name="listview_updated_this_month">這個月</string>
+ <string name="listview_updated_last_month">上個月</string>
+
+ <string name="settings_note_mode">筆記顯示模式</string>
+ <string name="settings_theme_title">佈景主題</string>
+ <string name="settings_font_title">等寬字體</string>
+ <string name="settings_font_size">字體大小</string>
+ <string name="settings_wifi_only">只在有 Wi-Fi 時同步</string>
+ <string name="settings_lock">密碼保護</string>
+ <string name="settings_background_sync">背景同步</string>
+
+ <string name="error_sync">同步失敗:%1$s</string>
+ <string name="error_synchronization">同步失敗</string>
+ <string name="error_no_network">沒有網路連線</string>
+ <string name="error_unknown">發生未知錯誤。</string>
+
+ <string name="about_version_title">版本</string>
+ <string name="about_version">您目前正在使用 &lt;strong>%1$s&lt;/strong></string>
+ <string name="about_maintainer_title">保養員</string>
+ <string name="about_developers_title">開發員</string>
+ <string name="about_translators_title">翻譯員</string>
+ <string name="about_translators_transifex">&lt;a href=\"%1$s\">Transifex&lt;/a> 上的 Nextcloud 社群</string>
+ <string name="about_testers_title">測試員</string>
+ <string name="about_source_title">原始碼</string>
+ <string name="about_source">此專案寄存在 GitHub 上:&lt;a href=\"%1$s\">%1$s&lt;/a></string>
+ <string name="about_issues_title">問題</string>
+ <string name="about_issues">您可以在 GitHub 問題回報系統回報錯誤、改善建議及功能需求:&lt;a href=\"%1$s\">%1$s&lt;/a></string>
+ <string name="about_translate_title">翻譯</string>
+ <string name="about_translate">歡迎加入 Transifex 的 Nextcloud 團隊並協助翻譯此 App:&lt;a href=\"%1$s\">%1$s&lt;/a></string>
+ <string name="about_app_license_title">程式授權條款</string>
+ <string name="about_app_license">此程式依照 GNU GENERAL PUBLIC LICENSE v3+ 方式授權使用</string>
+ <string name="about_app_license_button">檢視授權條款</string>
+ <string name="about_icons_disclaimer_title">圖示</string>
+ <string name="about_icons_disclaimer">&lt;p>原創圖示由 %1$s 製作&lt;/p>&lt;p>其他 App 使用的圖示均為 Google Inc. 製作的 &lt;a href=\"https://materialdesignicons.com/\">Material Design 圖示&lt;/a>,並依 Apache 2.0 條款授權。&lt;/p></string>
+ <string name="about_credits_tab_title">致謝</string>
+ <string name="about_contribution_tab_title">貢獻</string>
+ <string name="about_license_tab_title">授權條款</string>
+
+ <string name="widget_note_list_title">筆記清單</string>
+ <string name="widget_note_list_placeholder">沒有筆記</string>
+ <string name="widget_single_note_title">單則筆記</string>
+ <string name="widget_single_note_placeholder_tv">找不到筆記</string>
+ <string name="widget_create_note">建立筆記</string>
+ <string name="widget_not_logged_in">在使用此小工具之前,請先登入到 Notes</string>
+ <string name="widget_entry_fav_contentDescription">星星圖示用來標示某則筆記在「我的最愛」中。</string>
+ <string name="widget_app_launcher_contentDescription">啟動 App</string>
+
+ <string name="activity_select_single_note">選擇筆記</string>
+
+ <string name="shortcut_create_long">建立新筆記</string>
+
+ <string name="pref_value_font_normal">一般</string>
+ <string name="pref_value_wifi_and_mobile">在使用 Wi-Fi 及行動網路時同步</string>
+ <string name="pref_value_lock">密碼保護</string>
+
+ <string name="simple_error">錯誤</string>
+ <string name="simple_close">關閉</string>
+ <string name="simple_copy">複製</string>
+ <string name="simple_exception">例外</string>
+ <string name="pin_to_homescreen">釘選至主畫面</string>
+ <string name="note_has_been_deleted">此則筆記已被刪除</string>
+ <string name="add_account">新增帳戶</string>
+ <string name="category_music">音樂</string>
+ <string name="category_movies">電影</string>
+ <string name="category_movie">電影</string>
+ <string name="category_work">工作</string>
+ <string name="account_already_imported">已成功匯入帳戶</string>
+ <string name="no_notes_yet">尚沒有筆記</string>
+ <string name="no_notes_yet_description">請按 + 按鈕建立新筆記</string>
+ <string name="simple_more">更多</string>
+ <string name="simple_move">移動</string>
+ <string name="category_readonly">唯讀</string>
+ <string name="no_category">沒有分類</string>
+ <string name="add_category">新增%1$s</string>
+ <string name="simple_checkbox">複選框</string>
+ <string name="unlock_notes">解鎖筆記</string>
+ <string name="simple_beta">Beta 測試版</string>
+ <string name="error_dialog_title">喔不 - 現在怎麼辦?🙁</string>
+ <string name="error_dialog_we_need_info">我們需要以下的技術資訊來幫助您:</string>
+ <string name="added_content">已加入「%1$s」</string>
+ <string name="shared_text_empty">分享的文字是空的</string>
+ <string name="append_to_note">附加到筆記</string>
+ <string name="change_note_title">改變筆記標題</string>
+ <string name="menu_edit_title">編輯標題</string>
+ <string name="settings_gridview">格線檢視 </string>
+ <string name="simple_security">安全性</string>
+ <string name="simple_appearance">外觀</string>
+ <string name="simple_synchronization">同步</string>
+ <string name="simple_behavior">行為</string>
+ <string name="manage_accounts">帳戶管理</string>
+ <string name="action_formatting_help">正在格式化</string>
+
+ <string-array name="noteMode_entries">
+ <item>以編輯模式開啟</item>
+ <item>以預覽模式開啟</item>
+ <item>記住上次選擇</item>
+ </string-array>
+
+ <string-array name="fontSize_entries">
+ <item>小</item>
+ <item>中</item>
+ <item>大</item>
+ </string-array>
+
+ <string-array name="sync_entries">
+ <item>關閉</item>
+ <item>15 分鐘</item>
+ <item>1 小時</item>
+ <item>6 小時</item>
+ </string-array>
+
+ <string-array name="darkmode_entries">
+ <item>亮色</item>
+ <item>暗色</item>
+ <item>系統預設值</item>
+ </string-array>
+
+ <plurals name="ab_selected">
+ <item quantity="other">已選擇 %d 則</item>
+ </plurals>
+ <plurals name="bulk_notes_deleted">
+ <item quantity="other">已刪除 %1$d 記事</item>
+ </plurals>
+ <plurals name="bulk_notes_restored">
+ <item quantity="other">已回復 %1$d 記事</item>
+ </plurals>
+ <plurals name="share_multiple">
+ <item quantity="other">共享 %1$d 記事內容</item>
+ </plurals>
+
+ <string name="formatting_help_divider" translateable="false">---</string>
+ <string name="formatting_help_codefence_inline" translateable="false">`%1$s`</string>
+ <string name="formatting_help_codefence_inline_escaped" translateable="false">\\`%1$s\\`</string>
+ <string name="formatting_help_codefence" translateable="false">```</string>
+ <string name="formatting_help_codefence_outer" translateable="false">````</string>
+ <string name="formatting_help_codefence_javascript" translateable="false">```javascript</string>
+ <string name="formatting_help_text_title">文字編輯器</string>
+ <string name="formatting_help_lists_title">清單</string>
+ <string name="formatting_help_lists_body_1">有時您想要編號列表:</string>
+ <string name="formatting_help_lists_body_2">一</string>
+ <string name="formatting_help_lists_body_3">二</string>
+ <string name="formatting_help_lists_body_4">三</string>
+ <string name="formatting_help_lists_body_6">以短劃線 (dash) 開頭</string>
+ <string name="formatting_help_lists_body_8">類似這個</string>
+ <string name="formatting_help_lists_body_9">還有這個</string>
+
+ <string name="formatting_help_checkboxes_title">勾選框</string>
+ <string name="formatting_help_checkboxes_body_2">項目 1</string>
+ <string name="formatting_help_checkboxes_body_3">項目 2</string>
+
+ <string name="formatting_help_structured_documents_body_6">- 愛因斯坦</string>
+
+ <string name="formatting_help_tables_title">表</string>
+ <!-- Column header of a sample table -->
+ <string name="formatting_help_tables_column">欄 %1d</string>
+ <!-- Table cell value of a sample table -->
+ <string name="formatting_help_tables_value">值 %1d</string>
+
+ <string name="formatting_help_images_title">圖像</string>
+ <string name="simple_other">其他</string>
+ <string name="sort_last_modified">依修改日期排序</string>
+ <string name="sort_alphabetically">依字母排序</string>
+ <string name="error_action_open_battery_settings">電池設定</string>
+ <string name="error_action_open_deck_info">開啟 App 資訊</string>
+ <string name="error_action_open_network">網路設定</string>
+ <string name="no_other_accounts">你尚未設定其它帳號。</string>
+ </resources>
diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml
index d4e368b0..be810c87 100644
--- a/app/src/main/res/values-zh-rTW/strings.xml
+++ b/app/src/main/res/values-zh-rTW/strings.xml
@@ -111,6 +111,7 @@
<string name="simple_checkbox">核取方塊</string>
<string name="unlock_notes">解鎖筆記</string>
<string name="simple_beta">Beta 測試版</string>
+ <string name="error_dialog_title">喔不 - 現在怎麼辦?🙁</string>
<string name="error_dialog_we_need_info">我們需要以下的技術資訊來幫助您:</string>
<string name="added_content">已加入「%1$s」</string>
<string name="shared_text_empty">分享的文字是空的</string>
@@ -186,4 +187,4 @@
<string name="error_action_open_deck_info">開啟 App 資訊</string>
<string name="error_action_open_network">網路設定</string>
<string name="no_other_accounts">你尚未設定其它帳號。</string>
-</resources>
+ </resources>
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 266ae373..22ed8077 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -293,6 +293,7 @@
<string name="error_action_open_battery_settings">Battery settings</string>
<string name="error_action_open_deck_info">Open App info</string>
<string name="error_action_open_network">Network settings</string>
+ <string name="no_account_configured_yet">No account configured yet</string>
<string name="no_other_accounts">You don\'t have configured any other accounts yet.</string>
<string name="choose_account">Choose account</string>
<string name="context_based_formatting">Context based formatting popover</string>
diff --git a/app/src/test/java/it/niedermann/owncloud/notes/shared/model/NoteTest.java b/app/src/test/java/it/niedermann/owncloud/notes/shared/model/NoteTest.java
deleted file mode 100644
index bd15fe17..00000000
--- a/app/src/test/java/it/niedermann/owncloud/notes/shared/model/NoteTest.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package it.niedermann.owncloud.notes.shared.model;
-
-import junit.framework.TestCase;
-
-import it.niedermann.owncloud.notes.shared.util.NoteUtil;
-
-/**
- * Tests the Note Model
- * Created by stefan on 06.10.15.
- */
-public class NoteTest extends TestCase {
-
- public void testMarkDownStrip() {
- assertEquals("Title", NoteUtil.removeMarkDown("# Title"));
- assertEquals("Aufzählung", NoteUtil.removeMarkDown("* Aufzählung"));
- }
-}
diff --git a/app/src/test/java/it/niedermann/owncloud/notes/shared/util/NoteUtilTest.java b/app/src/test/java/it/niedermann/owncloud/notes/shared/util/NoteUtilTest.java
index 90ee505f..baa58536 100644
--- a/app/src/test/java/it/niedermann/owncloud/notes/shared/util/NoteUtilTest.java
+++ b/app/src/test/java/it/niedermann/owncloud/notes/shared/util/NoteUtilTest.java
@@ -7,36 +7,6 @@ import junit.framework.TestCase;
* Created by stefan on 06.10.15.
*/
public class NoteUtilTest extends TestCase {
- public void testRemoveMarkDown() {
- assertEquals("Test", NoteUtil.removeMarkDown("Test"));
- assertEquals("Foo\nBar", NoteUtil.removeMarkDown("Foo\nBar"));
- assertEquals("Foo\nBar", NoteUtil.removeMarkDown("Foo\n Bar"));
- assertEquals("Foo\nBar", NoteUtil.removeMarkDown("Foo \nBar"));
- assertEquals("Foo-Bar", NoteUtil.removeMarkDown("Foo-Bar"));
- assertEquals("Foo*Bar", NoteUtil.removeMarkDown("Foo*Bar"));
- assertEquals("Foo/Bar", NoteUtil.removeMarkDown("Foo/Bar"));
- assertEquals("FooTestBar", NoteUtil.removeMarkDown("Foo*Test*Bar"));
- assertEquals("FooTestBar", NoteUtil.removeMarkDown("Foo**Test**Bar"));
- assertEquals("FooTestBar", NoteUtil.removeMarkDown("Foo***Test***Bar"));
- assertEquals("FooTest*Bar", NoteUtil.removeMarkDown("Foo*Test**Bar"));
- assertEquals("Foo*TestBar", NoteUtil.removeMarkDown("Foo***Test**Bar"));
- assertEquals("FooTestBar", NoteUtil.removeMarkDown("Foo_Test_Bar"));
- assertEquals("FooTestBar", NoteUtil.removeMarkDown("Foo__Test__Bar"));
- assertEquals("FooTestBar", NoteUtil.removeMarkDown("Foo___Test___Bar"));
- assertEquals("Foo\nHeader\nBar", NoteUtil.removeMarkDown("Foo\n# Header\nBar"));
- assertEquals("Foo\nHeader\nBar", NoteUtil.removeMarkDown("Foo\n### Header\nBar"));
- assertEquals("Foo\nHeader\nBar", NoteUtil.removeMarkDown("Foo\n# Header #\nBar"));
- assertEquals("Foo\nHeader\nBar", NoteUtil.removeMarkDown("Foo\n## Header ####\nBar"));
- assertEquals("Foo\nNo Header #\nBar", NoteUtil.removeMarkDown("Foo\nNo Header #\nBar"));
- assertEquals("Foo\nHeader\nBar", NoteUtil.removeMarkDown("Foo\nHeader\n=\nBar"));
- assertEquals("Foo\nHeader\nBar", NoteUtil.removeMarkDown("Foo\nHeader\n-----\nBar"));
- assertEquals("Foo\nHeader\n--=--\nBar", NoteUtil.removeMarkDown("Foo\nHeader\n--=--\nBar"));
- assertEquals("Foo\nAufzählung\nBar", NoteUtil.removeMarkDown("Foo\n* Aufzählung\nBar"));
- assertEquals("Foo\nAufzählung\nBar", NoteUtil.removeMarkDown("Foo\n+ Aufzählung\nBar"));
- assertEquals("Foo\nAufzählung\nBar", NoteUtil.removeMarkDown("Foo\n- Aufzählung\nBar"));
- assertEquals("Foo\nAufzählung\nBar", NoteUtil.removeMarkDown("Foo\n - Aufzählung\nBar"));
- assertEquals("Foo\nAufzählung *\nBar", NoteUtil.removeMarkDown("Foo\n* Aufzählung *\nBar"));
- }
public void testIsEmptyLine() {
assertTrue(NoteUtil.isEmptyLine(" "));
@@ -47,11 +17,11 @@ public class NoteUtilTest extends TestCase {
assertFalse(NoteUtil.isEmptyLine("a \n "));
}
- public void testGetLineWithoutMarkDown() {
- assertEquals("Test", NoteUtil.getLineWithoutMarkDown("Test", 0));
- assertEquals("Test", NoteUtil.getLineWithoutMarkDown("\nTest", 0));
- assertEquals("Foo", NoteUtil.getLineWithoutMarkDown("Foo\nBar", 0));
- assertEquals("Bar", NoteUtil.getLineWithoutMarkDown("Foo\nBar", 1));
+ public void testGetLineWithoutMarkdown() {
+ assertEquals("Test", NoteUtil.getLineWithoutMarkdown("Test", 0));
+ assertEquals("Test", NoteUtil.getLineWithoutMarkdown("\nTest", 0));
+ assertEquals("Foo", NoteUtil.getLineWithoutMarkdown("Foo\nBar", 0));
+ assertEquals("Bar", NoteUtil.getLineWithoutMarkdown("Foo\nBar", 1));
}
public void testGenerateNoteTitle() {
diff --git a/build.gradle b/build.gradle
index fca73e9a..4f2fb41c 100644
--- a/build.gradle
+++ b/build.gradle
@@ -4,11 +4,10 @@ buildscript {
repositories {
google()
jcenter()
-
}
dependencies {
apply plugin: 'maven'
- classpath 'com.android.tools.build:gradle:4.1.1'
+ classpath 'com.android.tools.build:gradle:4.1.2'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
@@ -20,5 +19,6 @@ allprojects {
google()
jcenter()
maven { url "https://jitpack.io" }
+ maven { url 'https://oss.sonatype.org/content/repositories/snapshots/' }
}
}
diff --git a/fastlane/metadata/android/en-US/changelogs/2019001.txt b/fastlane/metadata/android/en-US/changelogs/2019001.txt
deleted file mode 100644
index 95c66267..00000000
--- a/fastlane/metadata/android/en-US/changelogs/2019001.txt
+++ /dev/null
@@ -1 +0,0 @@
-- ❓ Update formatting section (#1020) \ No newline at end of file
diff --git a/fastlane/metadata/android/en-US/changelogs/3000000.txt b/fastlane/metadata/android/en-US/changelogs/3000000.txt
new file mode 100644
index 00000000..3c8e982c
--- /dev/null
+++ b/fastlane/metadata/android/en-US/changelogs/3000000.txt
@@ -0,0 +1,18 @@
+3.0.0
+
+- ❓ Update formatting section (#1020)
+- 🌍 Updated translations
+
+2.19.0
+
+- 🆕 Replace RxMarkdown viewer with Markwon viewer (#549)
+- 📈 Render markdown tables (#190)
+- 🖼️ Show images in view mode (#807)
+- ✅ Multi level checkboxes
+- ✏️ Readonly mode must not allow editing of title (#983)
+- 🔍 Matched content does not been rendered while search (#999)
+- 🐞 Fix StringIndexOutOfBoundsException (#908)
+
+2.18.0
+
+- Replace RxMarkdown editor with Markwon editor (Does not yet affect the viewer) (#549) \ No newline at end of file
diff --git a/fastlane/metadata/android/en-US/changelogs/3000001.txt b/fastlane/metadata/android/en-US/changelogs/3000001.txt
new file mode 100644
index 00000000..a8332aae
--- /dev/null
+++ b/fastlane/metadata/android/en-US/changelogs/3000001.txt
@@ -0,0 +1,24 @@
+3.0.1
+
+- 🐞 Fix overriding of manually set title when editing/exiting a new note (#935) (❤️ @johahauf)
+- 🐞 Switch to View mode crashes (#1038)
+- 🌍 Updated translations
+
+3.0.0
+
+- ❓ Update formatting section (#1020)
+- 🌍 Updated translations
+
+2.19.0
+
+- 🆕 Replace RxMarkdown viewer with Markwon viewer (#549)
+- 📈 Render markdown tables (#190)
+- 🖼️ Show images in view mode (#807)
+- ✅ Multi level checkboxes
+- ✏️ Readonly mode must not allow editing of title (#983)
+- 🔍 Matched content does not been rendered while search (#999)
+- 🐞 Fix StringIndexOutOfBoundsException (#908)
+
+2.18.0
+
+- Replace RxMarkdown editor with Markwon editor (Does not yet affect the viewer) (#549) \ No newline at end of file
diff --git a/fastlane/metadata/android/en-US/changelogs/3001000.txt b/fastlane/metadata/android/en-US/changelogs/3001000.txt
new file mode 100644
index 00000000..460f4546
--- /dev/null
+++ b/fastlane/metadata/android/en-US/changelogs/3001000.txt
@@ -0,0 +1,28 @@
+3.1.0
+- 🌐 Save page title when sharing from browser (#1032)
+- ↩️ Soft break adds new line
+
+3.0.1
+
+- 🐞 Fix overriding of manually set title when editing/exiting a new note (#935) (❤️ @johahauf)
+- 🐞 Switch to View mode crashes (#1038)
+- 🌍 Updated translations
+
+3.0.0
+
+- ❓ Update formatting section (#1020)
+- 🌍 Updated translations
+
+2.19.0
+
+- 🆕 Replace RxMarkdown viewer with Markwon viewer (#549)
+- 📈 Render markdown tables (#190)
+- 🖼️ Show images in view mode (#807)
+- ✅ Multi level checkboxes
+- ✏️ Readonly mode must not allow editing of title (#983)
+- 🔍 Matched content does not been rendered while search (#999)
+- 🐞 Fix StringIndexOutOfBoundsException (#908)
+
+2.18.0
+
+- Replace RxMarkdown editor with Markwon editor (Does not yet affect the viewer) (#549) \ No newline at end of file
diff --git a/fastlane/metadata/android/en-US/changelogs/3001001.txt b/fastlane/metadata/android/en-US/changelogs/3001001.txt
new file mode 100644
index 00000000..38c5397c
--- /dev/null
+++ b/fastlane/metadata/android/en-US/changelogs/3001001.txt
@@ -0,0 +1,2 @@
+- 🐞 Fix list auto continuation for some scenarios (#1040, #1050)
+- 🐞 Catch creation shortcuts when no account is configured yet (#1047) \ No newline at end of file
diff --git a/fastlane/metadata/android/en-US/changelogs/3001002.txt b/fastlane/metadata/android/en-US/changelogs/3001002.txt
new file mode 100644
index 00000000..0b8258c3
--- /dev/null
+++ b/fastlane/metadata/android/en-US/changelogs/3001002.txt
@@ -0,0 +1 @@
+- 🐞 Fix crash for Android < 7 when open a note in preview mode (#1056) \ No newline at end of file
diff --git a/fastlane/metadata/android/en-US/changelogs/3001003.txt b/fastlane/metadata/android/en-US/changelogs/3001003.txt
new file mode 100644
index 00000000..cf524deb
--- /dev/null
+++ b/fastlane/metadata/android/en-US/changelogs/3001003.txt
@@ -0,0 +1 @@
+- 🖼 Downscale and display huge images in preview mode instead of crash (#1034) \ No newline at end of file
diff --git a/fastlane/metadata/android/en-US/full_description.txt b/fastlane/metadata/android/en-US/full_description.txt
index 70f449f4..9128f526 100644
--- a/fastlane/metadata/android/en-US/full_description.txt
+++ b/fastlane/metadata/android/en-US/full_description.txt
@@ -9,7 +9,7 @@ Companion app to Nextcloud Notes.
* Notizen als Favoriten markieren⭐
* Massenhaftes Löschen 🗑️
* Notizen durchsuchen 🔍
- * MarkDown-Rendering ✨
+ * Markdown-Rendering ✨
* Kontext-basierte Formatierung 🧰
* Dark Mode 🌙
* Single note widget and note list widget 📊
diff --git a/markdown/build.gradle b/markdown/build.gradle
index 8d09fa64..672e407b 100644
--- a/markdown/build.gradle
+++ b/markdown/build.gradle
@@ -23,7 +23,7 @@ android {
}
ext {
- markwonVersion = "4.6.1"
+ markwonVersion = "4.6.2"
rxMarkdownVersion = "0.1.3"
}
@@ -32,7 +32,7 @@ dependencies {
implementation 'com.github.stefan-niedermann:android-commons:0.2.0'
implementation 'androidx.appcompat:appcompat:1.2.0'
- implementation "androidx.lifecycle:lifecycle-livedata:2.2.0"
+ implementation "androidx.lifecycle:lifecycle-livedata:2.3.0"
implementation "io.noties.markwon:core:$markwonVersion"
implementation "io.noties.markwon:editor:$markwonVersion"
diff --git a/markdown/src/androidTest/java/it/niedermann/android/markdown/MarkwonMarkdownUtilTest.java b/markdown/src/androidTest/java/it/niedermann/android/markdown/MarkdownUtilTest.java
index dbbcc4e0..d09e8bca 100644
--- a/markdown/src/androidTest/java/it/niedermann/android/markdown/MarkwonMarkdownUtilTest.java
+++ b/markdown/src/androidTest/java/it/niedermann/android/markdown/MarkdownUtilTest.java
@@ -21,12 +21,11 @@ import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
-import it.niedermann.android.markdown.markwon.MarkwonMarkdownUtil;
-import it.niedermann.android.markdown.markwon.model.EListType;
-import it.niedermann.android.markdown.markwon.span.SearchSpan;
+import it.niedermann.android.markdown.model.EListType;
+import it.niedermann.android.markdown.model.SearchSpan;
@RunWith(AndroidJUnit4.class)
-public class MarkwonMarkdownUtilTest extends TestCase {
+public class MarkdownUtilTest extends TestCase {
@Test
public void testGetStartOfLine() {
@@ -42,7 +41,7 @@ public class MarkwonMarkdownUtilTest extends TestCase {
);
for (int i = 0; i < test.length(); i++) {
- int startOfLine = MarkwonMarkdownUtil.getStartOfLine(test, i);
+ int startOfLine = MarkdownUtil.getStartOfLine(test, i);
if (i <= 11) {
assertEquals(0, startOfLine);
} else if (i <= 12) {
@@ -73,7 +72,7 @@ public class MarkwonMarkdownUtilTest extends TestCase {
"\n"; // line 78 - 79
for (int i = 0; i < test.length(); i++) {
- int endOfLine = MarkwonMarkdownUtil.getEndOfLine(test, i);
+ int endOfLine = MarkdownUtil.getEndOfLine(test, i);
if (i <= 11) {
assertEquals(11, endOfLine);
} else if (i <= 12) {
@@ -159,7 +158,7 @@ public class MarkwonMarkdownUtilTest extends TestCase {
lines.put("*[]", false);
lines.put("+[]", false);
- lines.forEach((key, value) -> assertEquals(value, (Boolean) MarkwonMarkdownUtil.lineStartsWithCheckbox(key)));
+ lines.forEach((key, value) -> assertEquals(value, (Boolean) MarkdownUtil.lineStartsWithCheckbox(key)));
}
@Test
@@ -168,121 +167,121 @@ public class MarkwonMarkdownUtilTest extends TestCase {
// Add italic
builder = new SpannableStringBuilder("Lorem ipsum dolor sit amet.");
- assertEquals(13, MarkwonMarkdownUtil.togglePunctuation(builder, 6, 11, "*"));
+ assertEquals(13, MarkdownUtil.togglePunctuation(builder, 6, 11, "*"));
assertEquals("Lorem *ipsum* dolor sit amet.", builder.toString());
// Remove italic
builder = new SpannableStringBuilder("Lorem *ipsum* dolor sit amet.");
- assertEquals(11, MarkwonMarkdownUtil.togglePunctuation(builder, 7, 12, "*"));
+ assertEquals(11, MarkdownUtil.togglePunctuation(builder, 7, 12, "*"));
assertEquals("Lorem ipsum dolor sit amet.", builder.toString());
// Add bold
builder = new SpannableStringBuilder("Lorem ipsum dolor sit amet.");
- assertEquals(15, MarkwonMarkdownUtil.togglePunctuation(builder, 6, 11, "**"));
+ assertEquals(15, MarkdownUtil.togglePunctuation(builder, 6, 11, "**"));
assertEquals("Lorem **ipsum** dolor sit amet.", builder.toString());
// Remove bold
builder = new SpannableStringBuilder("Lorem **ipsum** dolor sit amet.");
- assertEquals(11, MarkwonMarkdownUtil.togglePunctuation(builder, 8, 13, "**"));
+ assertEquals(11, MarkdownUtil.togglePunctuation(builder, 8, 13, "**"));
assertEquals("Lorem ipsum dolor sit amet.", builder.toString());
// Add strike
builder = new SpannableStringBuilder("Lorem ipsum dolor sit amet.");
- assertEquals(15, MarkwonMarkdownUtil.togglePunctuation(builder, 6, 11, "~~"));
+ assertEquals(15, MarkdownUtil.togglePunctuation(builder, 6, 11, "~~"));
assertEquals("Lorem ~~ipsum~~ dolor sit amet.", builder.toString());
// Remove strike
builder = new SpannableStringBuilder("Lorem ~~ipsum~~ dolor sit amet.");
- assertEquals(11, MarkwonMarkdownUtil.togglePunctuation(builder, 8, 13, "~~"));
+ assertEquals(11, MarkdownUtil.togglePunctuation(builder, 8, 13, "~~"));
assertEquals("Lorem ipsum dolor sit amet.", builder.toString());
// Add italic at first position
builder = new SpannableStringBuilder("Lorem ipsum dolor sit amet.");
- assertEquals(7, MarkwonMarkdownUtil.togglePunctuation(builder, 0, 5, "*"));
+ assertEquals(7, MarkdownUtil.togglePunctuation(builder, 0, 5, "*"));
assertEquals("*Lorem* ipsum dolor sit amet.", builder.toString());
// Remove italic from first position
builder = new SpannableStringBuilder("*Lorem* ipsum dolor sit amet.");
- assertEquals(5, MarkwonMarkdownUtil.togglePunctuation(builder, 1, 6, "*"));
+ assertEquals(5, MarkdownUtil.togglePunctuation(builder, 1, 6, "*"));
assertEquals("Lorem ipsum dolor sit amet.", builder.toString());
// Add italic at last position
builder = new SpannableStringBuilder("Lorem ipsum dolor sit amet.");
- assertEquals(29, MarkwonMarkdownUtil.togglePunctuation(builder, 22, 27, "*"));
+ assertEquals(29, MarkdownUtil.togglePunctuation(builder, 22, 27, "*"));
assertEquals("Lorem ipsum dolor sit *amet.*", builder.toString());
// Remove italic from last position
builder = new SpannableStringBuilder("Lorem ipsum dolor sit *amet.*");
- assertEquals(27, MarkwonMarkdownUtil.togglePunctuation(builder, 23, 28, "*"));
+ assertEquals(27, MarkdownUtil.togglePunctuation(builder, 23, 28, "*"));
assertEquals("Lorem ipsum dolor sit amet.", builder.toString());
// Text is not directly surrounded by punctuation but contains it
// Do nothing when the same punctuation is contained only one time
builder = new SpannableStringBuilder("Lorem *ipsum dolor sit amet.");
- assertEquals(28, MarkwonMarkdownUtil.togglePunctuation(builder, 0, 28, "*"));
+ assertEquals(28, MarkdownUtil.togglePunctuation(builder, 0, 28, "*"));
assertEquals("Lorem *ipsum dolor sit amet.", builder.toString());
// Do nothing when the same punctuation is contained only one time
builder = new SpannableStringBuilder("Lorem **ipsum dolor sit amet.");
- assertEquals(29, MarkwonMarkdownUtil.togglePunctuation(builder, 0, 29, "**"));
+ assertEquals(29, MarkdownUtil.togglePunctuation(builder, 0, 29, "**"));
assertEquals("Lorem **ipsum dolor sit amet.", builder.toString());
// Remove containing punctuation
builder = new SpannableStringBuilder("Lorem *ipsum* dolor sit amet.");
- assertEquals(11, MarkwonMarkdownUtil.togglePunctuation(builder, 6, 13, "*"));
+ assertEquals(11, MarkdownUtil.togglePunctuation(builder, 6, 13, "*"));
assertEquals("Lorem ipsum dolor sit amet.", builder.toString());
// Remove containing punctuation
builder = new SpannableStringBuilder("Lorem *ipsum* dolor sit amet.");
- assertEquals(27, MarkwonMarkdownUtil.togglePunctuation(builder, 0, 29, "*"));
+ assertEquals(27, MarkdownUtil.togglePunctuation(builder, 0, 29, "*"));
assertEquals("Lorem ipsum dolor sit amet.", builder.toString());
// Remove multiple containing punctuations
builder = new SpannableStringBuilder("Lorem *ipsum* dolor *sit* amet.");
- assertEquals(27, MarkwonMarkdownUtil.togglePunctuation(builder, 0, 31, "*"));
+ assertEquals(27, MarkdownUtil.togglePunctuation(builder, 0, 31, "*"));
assertEquals("Lorem ipsum dolor sit amet.", builder.toString());
// Special use-case: toggle from italic to bold and back
// TODO Toggle italic on bold text
// builder = new SpannableStringBuilder("Lorem **ipsum** dolor sit amet.");
-// assertEquals(17, MarkwonMarkdownUtil.togglePunctuation(builder, 8, 13, "*"));
+// assertEquals(17, MarkdownUtil.togglePunctuation(builder, 8, 13, "*"));
// assertEquals("Lorem ***ipsum*** dolor sit amet.", builder.toString());
// TODO Toggle bold on italic text
// builder = new SpannableStringBuilder("Lorem *ipsum* dolor sit amet.");
-// assertEquals(17, MarkwonMarkdownUtil.togglePunctuation(builder, 7, 12, "**"));
+// assertEquals(17, MarkdownUtil.togglePunctuation(builder, 7, 12, "**"));
// assertEquals("Lorem ***ipsum*** dolor sit amet.", builder.toString());
// TODO Toggle bold to italic
// builder = new SpannableStringBuilder("Lorem **ipsum** dolor sit amet.");
-// assertEquals(33, MarkwonMarkdownUtil.togglePunctuation(builder, 0, 31, "*"));
+// assertEquals(33, MarkdownUtil.togglePunctuation(builder, 0, 31, "*"));
// assertEquals("Lorem ***ipsum*** dolor sit amet.", builder.toString());
// TODO Toggle multiple bold parts to italic
// builder = new SpannableStringBuilder("Lorem **ipsum** dolor **sit** amet.");
-// assertEquals(38, MarkwonMarkdownUtil.togglePunctuation(builder, 0, 34, "*"));
+// assertEquals(38, MarkdownUtil.togglePunctuation(builder, 0, 34, "*"));
// assertEquals("Lorem ***ipsum*** dolor ***sit*** amet.", builder.toString());
// TODO Toggle italic and bold to bold
// builder = new SpannableStringBuilder("Lorem ***ipsum*** dolor sit amet.");
-// assertEquals(13, MarkwonMarkdownUtil.togglePunctuation(builder, 0, 14, "*"));
+// assertEquals(13, MarkdownUtil.togglePunctuation(builder, 0, 14, "*"));
// assertEquals("Lorem **ipsum** dolor sit amet.", builder.toString());
// TODO Toggle italic and bold to italic
// builder = new SpannableStringBuilder("Lorem ***ipsum*** dolor sit amet.");
-// assertEquals(12, MarkwonMarkdownUtil.togglePunctuation(builder, 9, 14, "**"));
+// assertEquals(12, MarkdownUtil.togglePunctuation(builder, 9, 14, "**"));
// assertEquals("Lorem *ipsum* dolor sit amet.", builder.toString());
// TODO Toggle multiple italic and bold to bold
// builder = new SpannableStringBuilder("Lorem ***ipsum*** dolor ***sit*** amet.");
-// assertEquals(34, MarkwonMarkdownUtil.togglePunctuation(builder, 0, 38, "*"));
+// assertEquals(34, MarkdownUtil.togglePunctuation(builder, 0, 38, "*"));
// assertEquals("Lorem **ipsum** dolor **sit** amet.", builder.toString());
// TODO Toggle multiple italic and bold to italic
// builder = new SpannableStringBuilder("Lorem ***ipsum*** dolor ***sit*** amet.");
-// assertEquals(30, MarkwonMarkdownUtil.togglePunctuation(builder, 0, 38, "**"));
+// assertEquals(30, MarkdownUtil.togglePunctuation(builder, 0, 38, "**"));
// assertEquals("Lorem *ipsum* dolor *sit* amet.", builder.toString());
}
@@ -292,59 +291,59 @@ public class MarkwonMarkdownUtilTest extends TestCase {
// Add link without clipboardUrl to normal text
builder = new SpannableStringBuilder("Lorem ipsum dolor sit amet.");
- assertEquals(14, MarkwonMarkdownUtil.insertLink(builder, 6, 11, null));
+ assertEquals(14, MarkdownUtil.insertLink(builder, 6, 11, null));
assertEquals("Lorem [ipsum]() dolor sit amet.", builder.toString());
// Add link without clipboardUrl to url
builder = new SpannableStringBuilder("Lorem https://example.com dolor sit amet.");
- assertEquals(7, MarkwonMarkdownUtil.insertLink(builder, 6, 25, null));
+ assertEquals(7, MarkdownUtil.insertLink(builder, 6, 25, null));
assertEquals("Lorem [](https://example.com) dolor sit amet.", builder.toString());
// TODO Add link without clipboardUrl to empty selection before space character
// builder = new SpannableStringBuilder("Lorem ipsum dolor sit amet.");
-// assertEquals(13, MarkwonMarkdownUtil.insertLink(builder, 11, 11, null));
+// assertEquals(13, MarkdownUtil.insertLink(builder, 11, 11, null));
// assertEquals("Lorem ipsum []() dolor sit amet.", builder.toString());
// TODO Add link without clipboardUrl to empty selection after space character
// builder = new SpannableStringBuilder("Lorem ipsum dolor sit amet.");
-// assertEquals(13, MarkwonMarkdownUtil.insertLink(builder, 12, 12, null));
+// assertEquals(13, MarkdownUtil.insertLink(builder, 12, 12, null));
// assertEquals("Lorem ipsum []() dolor sit amet.", builder.toString());
// TODO Add link without clipboardUrl to empty selection in word
// builder = new SpannableStringBuilder("Lorem ipsum dolor sit amet.");
-// assertEquals(20, MarkwonMarkdownUtil.insertLink(builder, 14, 14, null));
+// assertEquals(20, MarkdownUtil.insertLink(builder, 14, 14, null));
// assertEquals("Lorem ipsum [dolor]() sit amet.", builder.toString());
// Add link with clipboardUrl to normal text
builder = new SpannableStringBuilder("Lorem ipsum dolor sit amet.");
- assertEquals(33, MarkwonMarkdownUtil.insertLink(builder, 6, 11, "https://example.com"));
+ assertEquals(33, MarkdownUtil.insertLink(builder, 6, 11, "https://example.com"));
assertEquals("Lorem [ipsum](https://example.com) dolor sit amet.", builder.toString());
// Add link with clipboardUrl to url
builder = new SpannableStringBuilder("Lorem https://example.com dolor sit amet.");
- assertEquals(46, MarkwonMarkdownUtil.insertLink(builder, 6, 25, "https://example.de"));
+ assertEquals(46, MarkdownUtil.insertLink(builder, 6, 25, "https://example.de"));
assertEquals("Lorem [https://example.com](https://example.de) dolor sit amet.", builder.toString());
// TODO Add link with clipboardUrl to empty selection before space character
// builder = new SpannableStringBuilder("Lorem ipsum dolor sit amet.");
-// assertEquals(13, MarkwonMarkdownUtil.insertLink(builder, 11, 11, "https://example.de"));
+// assertEquals(13, MarkdownUtil.insertLink(builder, 11, 11, "https://example.de"));
// assertEquals("Lorem ipsum []("https://example.de") dolor sit amet.", builder.toString());
// TODO Add link with clipboardUrl to empty selection after space character
// builder = new SpannableStringBuilder("Lorem ipsum dolor sit amet.");
-// assertEquals(13, MarkwonMarkdownUtil.insertLink(builder, 12, 12, "https://example.de"));
+// assertEquals(13, MarkdownUtil.insertLink(builder, 12, 12, "https://example.de"));
// assertEquals("Lorem ipsum []("https://example.de") dolor sit amet.", builder.toString());
// TODO Add link with clipboardUrl to empty selection in word
// builder = new SpannableStringBuilder("Lorem ipsum dolor sit amet.");
-// assertEquals(18, MarkwonMarkdownUtil.insertLink(builder, 14, 14, "https://example.de"));
+// assertEquals(18, MarkdownUtil.insertLink(builder, 14, 14, "https://example.de"));
// assertEquals("Lorem ipsum [dolor]("https://example.de") sit amet.", builder.toString());
}
@Test
public void testRemoveContainingPunctuation() {
try {
- final Method m = MarkwonMarkdownUtil.class.getDeclaredMethod("removeContainingPunctuation", Editable.class, int.class, int.class, String.class);
+ final Method m = MarkdownUtil.class.getDeclaredMethod("removeContainingPunctuation", Editable.class, int.class, int.class, String.class);
m.setAccessible(true);
Editable builder;
@@ -384,7 +383,7 @@ public class MarkwonMarkdownUtilTest extends TestCase {
@SuppressWarnings("ConstantConditions")
public void testSelectionIsSurroundedByPunctuation() {
try {
- final Method m = MarkwonMarkdownUtil.class.getDeclaredMethod("selectionIsSurroundedByPunctuation", CharSequence.class, int.class, int.class, String.class);
+ final Method m = MarkdownUtil.class.getDeclaredMethod("selectionIsSurroundedByPunctuation", CharSequence.class, int.class, int.class, String.class);
m.setAccessible(true);
assertTrue((Boolean) m.invoke(null, "*Lorem ipsum*", 1, 12, "*"));
assertTrue((Boolean) m.invoke(null, "**Lorem ipsum**", 2, 13, "*"));
@@ -402,7 +401,7 @@ public class MarkwonMarkdownUtilTest extends TestCase {
@SuppressWarnings("ConstantConditions")
public void testGetContainedPunctuationCount() {
try {
- final Method m = MarkwonMarkdownUtil.class.getDeclaredMethod("getContainedPunctuationCount", CharSequence.class, int.class, int.class, String.class);
+ final Method m = MarkdownUtil.class.getDeclaredMethod("getContainedPunctuationCount", CharSequence.class, int.class, int.class, String.class);
m.setAccessible(true);
assertEquals(0, (int) m.invoke(null, "*Lorem ipsum*", 1, 12, "*"));
assertEquals(1, (int) m.invoke(null, "*Lorem ipsum*", 1, 13, "*"));
@@ -419,7 +418,7 @@ public class MarkwonMarkdownUtilTest extends TestCase {
@SuppressWarnings("ConstantConditions")
public void testSelectionIsInLink() {
try {
- final Method m = MarkwonMarkdownUtil.class.getDeclaredMethod("selectionIsInLink", CharSequence.class, int.class, int.class);
+ final Method m = MarkdownUtil.class.getDeclaredMethod("selectionIsInLink", CharSequence.class, int.class, int.class);
m.setAccessible(true);
assertTrue((Boolean) m.invoke(null, "Lorem [ipsum](https://example.com) dolor sit amet.", 7, 12));
@@ -457,35 +456,35 @@ public class MarkwonMarkdownUtilTest extends TestCase {
@Test
public void testGetListItemIfIsEmpty() {
- assertEquals("- ", MarkwonMarkdownUtil.getListItemIfIsEmpty("- "));
- assertEquals("+ ", MarkwonMarkdownUtil.getListItemIfIsEmpty("+ "));
- assertEquals("* ", MarkwonMarkdownUtil.getListItemIfIsEmpty("* "));
- assertEquals("1. ", MarkwonMarkdownUtil.getListItemIfIsEmpty("1. "));
-
- assertNull(MarkwonMarkdownUtil.getListItemIfIsEmpty("- Test"));
- assertNull(MarkwonMarkdownUtil.getListItemIfIsEmpty("+ Test"));
- assertNull(MarkwonMarkdownUtil.getListItemIfIsEmpty("* Test"));
- assertNull(MarkwonMarkdownUtil.getListItemIfIsEmpty("1. s"));
- assertNull(MarkwonMarkdownUtil.getListItemIfIsEmpty("1. "));
+ assertEquals("- ", MarkdownUtil.getListItemIfIsEmpty("- "));
+ assertEquals("+ ", MarkdownUtil.getListItemIfIsEmpty("+ "));
+ assertEquals("* ", MarkdownUtil.getListItemIfIsEmpty("* "));
+ assertEquals("1. ", MarkdownUtil.getListItemIfIsEmpty("1. "));
+
+ assertNull(MarkdownUtil.getListItemIfIsEmpty("- Test"));
+ assertNull(MarkdownUtil.getListItemIfIsEmpty("+ Test"));
+ assertNull(MarkdownUtil.getListItemIfIsEmpty("* Test"));
+ assertNull(MarkdownUtil.getListItemIfIsEmpty("1. s"));
+ assertNull(MarkdownUtil.getListItemIfIsEmpty("1. "));
}
@Test
public void testLineStartsWithOrderedList() {
- assertEquals(1, MarkwonMarkdownUtil.getOrderedListNumber("1. Test"));
- assertEquals(2, MarkwonMarkdownUtil.getOrderedListNumber("2. Test"));
- assertEquals(3, MarkwonMarkdownUtil.getOrderedListNumber("3. Test"));
- assertEquals(10, MarkwonMarkdownUtil.getOrderedListNumber("10. Test"));
- assertEquals(11, MarkwonMarkdownUtil.getOrderedListNumber("11. Test"));
- assertEquals(12, MarkwonMarkdownUtil.getOrderedListNumber("12. Test"));
- assertEquals(1, MarkwonMarkdownUtil.getOrderedListNumber("1. 1"));
- assertEquals(1, MarkwonMarkdownUtil.getOrderedListNumber("1. Test 1"));
-
- assertEquals(-1, MarkwonMarkdownUtil.getOrderedListNumber(""));
- assertEquals(-1, MarkwonMarkdownUtil.getOrderedListNumber("1."));
- assertEquals(-1, MarkwonMarkdownUtil.getOrderedListNumber("1. "));
- assertEquals(-1, MarkwonMarkdownUtil.getOrderedListNumber("11. "));
- assertEquals(-1, MarkwonMarkdownUtil.getOrderedListNumber("-1. Test"));
- assertEquals(-1, MarkwonMarkdownUtil.getOrderedListNumber(" 1. Test"));
+ assertEquals(1, MarkdownUtil.getOrderedListNumber("1. Test"));
+ assertEquals(2, MarkdownUtil.getOrderedListNumber("2. Test"));
+ assertEquals(3, MarkdownUtil.getOrderedListNumber("3. Test"));
+ assertEquals(10, MarkdownUtil.getOrderedListNumber("10. Test"));
+ assertEquals(11, MarkdownUtil.getOrderedListNumber("11. Test"));
+ assertEquals(12, MarkdownUtil.getOrderedListNumber("12. Test"));
+ assertEquals(1, MarkdownUtil.getOrderedListNumber("1. 1"));
+ assertEquals(1, MarkdownUtil.getOrderedListNumber("1. Test 1"));
+
+ assertEquals(-1, MarkdownUtil.getOrderedListNumber(""));
+ assertEquals(-1, MarkdownUtil.getOrderedListNumber("1."));
+ assertEquals(-1, MarkdownUtil.getOrderedListNumber("1. "));
+ assertEquals(-1, MarkdownUtil.getOrderedListNumber("11. "));
+ assertEquals(-1, MarkdownUtil.getOrderedListNumber("-1. Test"));
+ assertEquals(-1, MarkdownUtil.getOrderedListNumber(" 1. Test"));
}
@Test
@@ -493,19 +492,19 @@ public class MarkwonMarkdownUtilTest extends TestCase {
for (EListType listType : EListType.values()) {
final String origin_1 = listType.checkboxUnchecked + " Item";
final String expected_1 = listType.checkboxChecked + " Item";
- assertEquals(expected_1, MarkwonMarkdownUtil.setCheckboxStatus(origin_1, 0, true));
+ assertEquals(expected_1, MarkdownUtil.setCheckboxStatus(origin_1, 0, true));
final String origin_2 = listType.checkboxChecked + " Item";
final String expected_2 = listType.checkboxChecked + " Item";
- assertEquals(expected_2, MarkwonMarkdownUtil.setCheckboxStatus(origin_2, 0, true));
+ assertEquals(expected_2, MarkdownUtil.setCheckboxStatus(origin_2, 0, true));
final String origin_3 = listType.checkboxChecked + " Item";
final String expected_3 = listType.checkboxChecked + " Item";
- assertEquals(expected_3, MarkwonMarkdownUtil.setCheckboxStatus(origin_3, -1, true));
+ assertEquals(expected_3, MarkdownUtil.setCheckboxStatus(origin_3, -1, true));
final String origin_4 = listType.checkboxChecked + " Item";
final String expected_4 = listType.checkboxChecked + " Item";
- assertEquals(expected_4, MarkwonMarkdownUtil.setCheckboxStatus(origin_4, 3, true));
+ assertEquals(expected_4, MarkdownUtil.setCheckboxStatus(origin_4, 3, true));
final String origin_5 = "" +
listType.checkboxChecked + " Item\n" +
@@ -513,7 +512,7 @@ public class MarkwonMarkdownUtilTest extends TestCase {
final String expected_5 = "" +
listType.checkboxChecked + " Item\n" +
listType.checkboxUnchecked + " Item";
- assertEquals(expected_5, MarkwonMarkdownUtil.setCheckboxStatus(origin_5, 1, false));
+ assertEquals(expected_5, MarkdownUtil.setCheckboxStatus(origin_5, 1, false));
// Checkboxes in fenced code block aren't rendered by Markwon and therefore don't count to the checkbox index
final String origin_6 = "" +
@@ -528,7 +527,7 @@ public class MarkwonMarkdownUtilTest extends TestCase {
listType.checkboxUnchecked + " Item\n" +
"```\n" +
listType.checkboxChecked + " Item";
- assertEquals(expected_6, MarkwonMarkdownUtil.setCheckboxStatus(origin_6, 1, true));
+ assertEquals(expected_6, MarkdownUtil.setCheckboxStatus(origin_6, 1, true));
// Checkbox in partial nested fenced code block does not count as rendered checkbox
final String origin_7 = "" +
@@ -545,7 +544,7 @@ public class MarkwonMarkdownUtilTest extends TestCase {
listType.checkboxUnchecked + " Item\n" +
"````\n" +
listType.checkboxChecked + " Item";
- assertEquals(expected_7, MarkwonMarkdownUtil.setCheckboxStatus(origin_7, 1, true));
+ assertEquals(expected_7, MarkdownUtil.setCheckboxStatus(origin_7, 1, true));
// Checkbox in complete nested fenced code block does not count as rendered checkbox
final String origin_8 = "" +
@@ -564,7 +563,7 @@ public class MarkwonMarkdownUtilTest extends TestCase {
"```\n" +
"````\n" +
listType.checkboxChecked + " Item";
- assertEquals(expected_8, MarkwonMarkdownUtil.setCheckboxStatus(origin_8, 1, true));
+ assertEquals(expected_8, MarkdownUtil.setCheckboxStatus(origin_8, 1, true));
// If checkbox has no content, it doesn't get rendered by Markwon and therefore can not be checked
final String origin_9 = "" +
@@ -585,30 +584,30 @@ public class MarkwonMarkdownUtilTest extends TestCase {
"````\n" +
listType.checkboxUnchecked + " \n" +
listType.checkboxChecked + " Item";
- assertEquals(expected_9, MarkwonMarkdownUtil.setCheckboxStatus(origin_9, 1, true));
+ assertEquals(expected_9, MarkdownUtil.setCheckboxStatus(origin_9, 1, true));
}
}
@Test
public void testRemoveSpans() {
try {
- final Method removeSpans = MarkwonMarkdownUtil.class.getDeclaredMethod("removeSpans", Spannable.class, Class.class);
+ final Method removeSpans = MarkdownUtil.class.getDeclaredMethod("removeSpans", Spannable.class, Class.class);
removeSpans.setAccessible(true);
final Context context = ApplicationProvider.getApplicationContext();
final Editable editable_1 = new SpannableStringBuilder("Lorem Ipsum dolor sit amet");
- editable_1.setSpan(new SearchSpan(context, Color.RED, false), 0, 5, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+ editable_1.setSpan(new SearchSpan(Color.RED, Color.GRAY, false, false), 0, 5, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
editable_1.setSpan(new ForegroundColorSpan(Color.BLUE), 6, 11, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
- editable_1.setSpan(new SearchSpan(context, Color.GREEN, true), 12, 17, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+ editable_1.setSpan(new SearchSpan(Color.BLUE, Color.GREEN, true, false), 12, 17, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
removeSpans.invoke(null, editable_1, SearchSpan.class);
assertEquals(0, editable_1.getSpans(0, editable_1.length(), SearchSpan.class).length);
assertEquals(1, editable_1.getSpans(0, editable_1.length(), ForegroundColorSpan.class).length);
final Editable editable_2 = new SpannableStringBuilder("Lorem Ipsum dolor sit amet");
- editable_2.setSpan(new SearchSpan(context, Color.RED, false), 0, 5, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+ editable_2.setSpan(new SearchSpan(Color.GRAY, Color.RED, false, true), 0, 5, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
editable_2.setSpan(new ForegroundColorSpan(Color.BLUE), 2, 7, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
- editable_2.setSpan(new SearchSpan(context, Color.GREEN, true), 3, 9, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+ editable_2.setSpan(new SearchSpan(Color.BLUE, Color.GREEN, true, false), 3, 9, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
removeSpans.invoke(null, editable_2, SearchSpan.class);
assertEquals(0, editable_2.getSpans(0, editable_2.length(), SearchSpan.class).length);
assertEquals(1, editable_2.getSpans(0, editable_2.length(), ForegroundColorSpan.class).length);
@@ -627,4 +626,39 @@ public class MarkwonMarkdownUtilTest extends TestCase {
e.printStackTrace();
}
}
+
+ @Test
+ public void testRemoveMarkdown() {
+ assertEquals("Test", MarkdownUtil.removeMarkdown("Test"));
+ assertEquals("Foo\nBar", MarkdownUtil.removeMarkdown("Foo\nBar"));
+ assertEquals("Foo\nBar", MarkdownUtil.removeMarkdown("Foo\n Bar"));
+ assertEquals("Foo\nBar", MarkdownUtil.removeMarkdown("Foo \nBar"));
+ assertEquals("Foo-Bar", MarkdownUtil.removeMarkdown("Foo-Bar"));
+ assertEquals("Foo*Bar", MarkdownUtil.removeMarkdown("Foo*Bar"));
+ assertEquals("Foo/Bar", MarkdownUtil.removeMarkdown("Foo/Bar"));
+ assertEquals("FooTestBar", MarkdownUtil.removeMarkdown("Foo*Test*Bar"));
+ assertEquals("FooTestBar", MarkdownUtil.removeMarkdown("Foo**Test**Bar"));
+ assertEquals("FooTestBar", MarkdownUtil.removeMarkdown("Foo***Test***Bar"));
+ assertEquals("FooTest*Bar", MarkdownUtil.removeMarkdown("Foo*Test**Bar"));
+ assertEquals("Foo*TestBar", MarkdownUtil.removeMarkdown("Foo***Test**Bar"));
+ assertEquals("FooTestBar", MarkdownUtil.removeMarkdown("Foo_Test_Bar"));
+ assertEquals("FooTestBar", MarkdownUtil.removeMarkdown("Foo__Test__Bar"));
+ assertEquals("FooTestBar", MarkdownUtil.removeMarkdown("Foo___Test___Bar"));
+ assertEquals("Foo\nHeader\nBar", MarkdownUtil.removeMarkdown("Foo\n# Header\nBar"));
+ assertEquals("Foo\nHeader\nBar", MarkdownUtil.removeMarkdown("Foo\n### Header\nBar"));
+ assertEquals("Foo\nHeader\nBar", MarkdownUtil.removeMarkdown("Foo\n# Header #\nBar"));
+ assertEquals("Foo\nHeader\nBar", MarkdownUtil.removeMarkdown("Foo\n## Header ####\nBar"));
+ assertEquals("Foo\nNo Header #\nBar", MarkdownUtil.removeMarkdown("Foo\nNo Header #\nBar"));
+ assertEquals("Foo\nHeader\nBar", MarkdownUtil.removeMarkdown("Foo\nHeader\n=\nBar"));
+ assertEquals("Foo\nHeader\nBar", MarkdownUtil.removeMarkdown("Foo\nHeader\n-----\nBar"));
+ assertEquals("Foo\nHeader\n--=--\nBar", MarkdownUtil.removeMarkdown("Foo\nHeader\n--=--\nBar"));
+ assertEquals("Foo\nAufzählung\nBar", MarkdownUtil.removeMarkdown("Foo\n* Aufzählung\nBar"));
+ assertEquals("Foo\nAufzählung\nBar", MarkdownUtil.removeMarkdown("Foo\n+ Aufzählung\nBar"));
+ assertEquals("Foo\nAufzählung\nBar", MarkdownUtil.removeMarkdown("Foo\n- Aufzählung\nBar"));
+ assertEquals("Foo\nAufzählung\nBar", MarkdownUtil.removeMarkdown("Foo\n - Aufzählung\nBar"));
+ assertEquals("Foo\nAufzählung *\nBar", MarkdownUtil.removeMarkdown("Foo\n* Aufzählung *\nBar"));
+ assertEquals("Title", MarkdownUtil.removeMarkdown("# Title"));
+ assertEquals("Aufzählung", MarkdownUtil.removeMarkdown("* Aufzählung"));
+// assertEquals("Foo Link Bar", MarkdownUtil.removeMarkdown("Foo [Link](https://example.com) Bar"));
+ }
} \ No newline at end of file
diff --git a/markdown/src/main/java/it/niedermann/android/markdown/MarkdownUtil.java b/markdown/src/main/java/it/niedermann/android/markdown/MarkdownUtil.java
index b6d04b7d..546dffc9 100644
--- a/markdown/src/main/java/it/niedermann/android/markdown/MarkdownUtil.java
+++ b/markdown/src/main/java/it/niedermann/android/markdown/MarkdownUtil.java
@@ -1,25 +1,52 @@
package it.niedermann.android.markdown;
import android.content.Context;
+import android.text.Editable;
+import android.text.Spannable;
+import android.text.SpannableString;
import android.text.Spanned;
import android.text.TextUtils;
+import android.util.Log;
import android.widget.RemoteViews.RemoteView;
+import android.widget.TextView;
+import androidx.annotation.ColorInt;
import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
import androidx.core.text.HtmlCompat;
import com.yydcdut.markdown.MarkdownProcessor;
import com.yydcdut.markdown.syntax.text.TextFactory;
import com.yydcdut.rxmarkdown.RxMarkdown;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
import io.noties.markwon.Markwon;
+import it.niedermann.android.markdown.model.EListType;
+import it.niedermann.android.markdown.model.SearchSpan;
public class MarkdownUtil {
+
+ private static final String TAG = MarkdownUtil.class.getSimpleName();
+
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};
+ private static final Pattern PATTERN_LISTS = Pattern.compile("^\\s*[*+-]\\s+", Pattern.MULTILINE);
+ private static final Pattern PATTERN_HEADINGS = Pattern.compile("^#+\\s+(.*?)\\s*#*$", Pattern.MULTILINE);
+ private static final Pattern PATTERN_HEADING_LINE = Pattern.compile("^(?:=*|-*)$", Pattern.MULTILINE);
+ private static final Pattern PATTERN_EMPHASIS = Pattern.compile("(\\*+|_+)(.*?)\\1", Pattern.MULTILINE);
+ private static final Pattern PATTERN_SPACE_1 = Pattern.compile("^\\s+", Pattern.MULTILINE);
+ private static final Pattern PATTERN_SPACE_2 = Pattern.compile("\\s+$", Pattern.MULTILINE);
+
+ private static final Pattern PATTERN_CODE_FENCE = Pattern.compile("^(`{3,})");
+ private static final Pattern PATTERN_ORDERED_LIST_ITEM = Pattern.compile("^(\\d+).\\s.+$");
+ private static final Pattern PATTERN_ORDERED_LIST_ITEM_EMPTY = Pattern.compile("^(\\d+).\\s$");
+ private static final Pattern PATTERN_MARKDOWN_LINK = Pattern.compile("\\[(.+)?]\\(([^ ]+?)?( \"(.+)\")?\\)");
+
private MarkdownUtil() {
// Util class
}
@@ -58,4 +85,287 @@ public class MarkdownUtil {
return markdownProcessor.parse(text);
}
+
+ 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;
+ }
+
+ public static String getListItemIfIsEmpty(@NonNull String line) {
+ for (EListType listType : EListType.values()) {
+ if (line.equals(listType.checkboxUncheckedWithTrailingSpace)) {
+ return listType.checkboxUncheckedWithTrailingSpace;
+ } else if (line.equals(listType.listSymbolWithTrailingSpace)) {
+ return listType.listSymbolWithTrailingSpace;
+ }
+ }
+ final Matcher matcher = PATTERN_ORDERED_LIST_ITEM_EMPTY.matcher(line);
+ if (matcher.find()) {
+ return matcher.group();
+ }
+ return null;
+ }
+
+ public static CharSequence setCheckboxStatus(@NonNull String markdownString, int targetCheckboxIndex, boolean newCheckedState) {
+ final String[] lines = markdownString.split("\n");
+ int checkboxIndex = 0;
+ boolean isInFencedCodeBlock = false;
+ int fencedCodeBlockSigns = 0;
+ for (int i = 0; i < lines.length; i++) {
+ final Matcher matcher = PATTERN_CODE_FENCE.matcher(lines[i]);
+ if (matcher.find()) {
+ final String fence = matcher.group(1);
+ if (fence != null) {
+ int currentFencedCodeBlockSigns = fence.length();
+ if (isInFencedCodeBlock) {
+ if (currentFencedCodeBlockSigns == fencedCodeBlockSigns) {
+ isInFencedCodeBlock = false;
+ fencedCodeBlockSigns = 0;
+ }
+ } else {
+ isInFencedCodeBlock = true;
+ fencedCodeBlockSigns = currentFencedCodeBlockSigns;
+ }
+ }
+ }
+ if (!isInFencedCodeBlock) {
+ if (lineStartsWithCheckbox(lines[i]) && lines[i].trim().length() > EListType.DASH.checkboxChecked.length()) {
+ if (checkboxIndex == targetCheckboxIndex) {
+ final int indexOfStartingBracket = lines[i].indexOf("[");
+ final String toggledLine = lines[i].substring(0, indexOfStartingBracket + 1) +
+ (newCheckedState ? 'x' : ' ') +
+ lines[i].substring(indexOfStartingBracket + 2);
+ lines[i] = toggledLine;
+ break;
+ }
+ checkboxIndex++;
+ }
+ }
+ }
+ return TextUtils.join("\n", lines);
+ }
+
+ public static boolean lineStartsWithCheckbox(@NonNull String line) {
+ for (EListType listType : EListType.values()) {
+ if (lineStartsWithCheckbox(line, listType)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public static boolean lineStartsWithCheckbox(@NonNull String line, @NonNull EListType listType) {
+ final String trimmedLine = line.trim();
+ return (trimmedLine.startsWith(listType.checkboxUnchecked) || trimmedLine.startsWith(listType.checkboxChecked));
+ }
+
+ /**
+ * @return the number of the ordered list item if the line is an ordered list, otherwise -1.
+ */
+ public static int getOrderedListNumber(@NonNull String line) {
+ final Matcher matcher = PATTERN_ORDERED_LIST_ITEM.matcher(line);
+ if (matcher.find()) {
+ final String groupNumber = matcher.group(1);
+ if (groupNumber != null) {
+ try {
+ return Integer.parseInt(groupNumber);
+ } catch (NumberFormatException e) {
+ return -1;
+ }
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * Modifies the {@param editable} and adds the given {@param punctuation} from
+ * {@param selectionStart} to {@param selectionEnd} or removes the {@param punctuation} in case
+ * it already is around the selected part.
+ *
+ * @return the new cursor position
+ */
+ public static int togglePunctuation(@NonNull Editable editable, int selectionStart, int selectionEnd, @NonNull String punctuation) {
+ switch (punctuation) {
+ case "**":
+ case "__":
+ case "*":
+ case "_":
+ case "~~": {
+ final boolean selectionIsSurroundedByPunctuation = selectionIsSurroundedByPunctuation(editable, selectionStart, selectionEnd, punctuation);
+ if (selectionIsSurroundedByPunctuation) {
+ editable.delete(selectionEnd, selectionEnd + punctuation.length());
+ editable.delete(selectionStart - punctuation.length(), selectionStart);
+ return selectionEnd - punctuation.length();
+ } else {
+ final int containedPunctuationCount = getContainedPunctuationCount(editable, selectionStart, selectionEnd, punctuation);
+ if (containedPunctuationCount == 0) {
+ editable.insert(selectionEnd, punctuation);
+ editable.insert(selectionStart, punctuation);
+ return selectionEnd + punctuation.length() * 2;
+ } else if (containedPunctuationCount % 2 > 0) {
+ return selectionEnd;
+ } else {
+ removeContainingPunctuation(editable, selectionStart, selectionEnd, punctuation);
+ return selectionEnd - containedPunctuationCount * punctuation.length();
+ }
+ }
+ }
+ default:
+ throw new UnsupportedOperationException("This kind of punctuation is not yet supported: " + punctuation);
+ }
+ }
+
+ /**
+ * Inserts a link into the given {@param editable} from {@param selectionStart} to {@param selectionEnd} and uses the {@param clipboardUrl} if available.
+ *
+ * @return the new cursor position
+ */
+ public static int insertLink(@NonNull Editable editable, int selectionStart, int selectionEnd, @Nullable String clipboardUrl) {
+ if (selectionStart == selectionEnd) {
+ editable.insert(selectionStart, "[](" + (clipboardUrl == null ? "" : clipboardUrl) + ")");
+ return selectionStart + 1;
+ } else {
+ final boolean textToFormatIsLink = TextUtils.indexOf(editable.subSequence(selectionStart, selectionEnd), "http") == 0;
+ if (textToFormatIsLink) {
+ if (clipboardUrl == null) {
+ editable.insert(selectionEnd, ")");
+ editable.insert(selectionStart, "[](");
+ } else {
+ editable.insert(selectionEnd, "](" + clipboardUrl + ")");
+ editable.insert(selectionStart, "[");
+ selectionEnd += clipboardUrl.length();
+ }
+ } else {
+ if (clipboardUrl == null) {
+ editable.insert(selectionEnd, "]()");
+ } else {
+ editable.insert(selectionEnd, "](" + clipboardUrl + ")");
+ selectionEnd += clipboardUrl.length();
+ }
+ editable.insert(selectionStart, "[");
+ }
+ return textToFormatIsLink && clipboardUrl == null
+ ? selectionStart + 1
+ : selectionEnd + 3;
+ }
+ }
+
+ /**
+ * @return whether or not the selection of {@param text} from {@param start} to {@param end} is
+ * surrounded or not by the given {@param punctuation}.
+ */
+ private static boolean selectionIsSurroundedByPunctuation(@NonNull CharSequence text, int start, int end, @NonNull String punctuation) {
+ if (text.length() < end + punctuation.length()) {
+ return false;
+ }
+ if (start - punctuation.length() < 0 || end + punctuation.length() > text.length()) {
+ return false;
+ }
+ return punctuation.contentEquals(text.subSequence(start - punctuation.length(), start))
+ && punctuation.contentEquals(text.subSequence(end, end + punctuation.length()));
+ }
+
+ private static int getContainedPunctuationCount(@NonNull CharSequence text, int start, int end, @NonNull String punctuation) {
+ final Matcher matcher = Pattern.compile(Pattern.quote(punctuation)).matcher(text.subSequence(start, end));
+ int counter = 0;
+ while (matcher.find()) {
+ counter++;
+ }
+ return counter;
+ }
+
+ private static void removeContainingPunctuation(@NonNull Editable editable, int start, int end, @NonNull String punctuation) {
+ final Matcher matcher = Pattern.compile(Pattern.quote(punctuation)).matcher(editable.subSequence(start, end));
+ int countDeletedPunctuations = 0;
+ while (matcher.find()) {
+ editable.delete(start + matcher.start() - countDeletedPunctuations * punctuation.length(), start + matcher.end() - countDeletedPunctuations * punctuation.length());
+ countDeletedPunctuations++;
+ }
+ }
+
+ public static boolean selectionIsInLink(@NonNull CharSequence text, int start, int end) {
+ final Matcher matcher = PATTERN_MARKDOWN_LINK.matcher(text);
+ while (matcher.find()) {
+ if ((start >= matcher.start() && start < matcher.end()) || (end > matcher.start() && end <= matcher.end())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public static void searchAndColor(@NonNull Spannable editable, @Nullable CharSequence searchText, @Nullable Integer current, @ColorInt int mainColor, @ColorInt int highlightColor, boolean darkTheme) {
+ if (searchText != null) {
+ final Matcher m = Pattern
+ .compile(searchText.toString(), Pattern.CASE_INSENSITIVE | Pattern.LITERAL)
+ .matcher(editable);
+
+ int i = 1;
+ while (m.find()) {
+ int start = m.start();
+ int end = m.end();
+ editable.setSpan(new SearchSpan(mainColor, highlightColor, (current != null && i == current), darkTheme), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+ i++;
+ }
+ }
+ }
+
+ /**
+ * Removes all spans of {@param spanType} from {@param spannable}.
+ */
+ public static <T> void removeSpans(@NonNull Spannable spannable, @SuppressWarnings("SameParameterValue") Class<T> spanType) {
+ for (T span : spannable.getSpans(0, spannable.length(), spanType)) {
+ spannable.removeSpan(span);
+ }
+ }
+
+ /**
+ * @return When the content of the {@param textView} is already of type {@link Spannable}, it will cast and return it directly.
+ * Otherwise it will create a new {@link SpannableString} from the content, set this as new content of the {@param textView} and return it.
+ */
+ public static Spannable getContentAsSpannable(@NonNull TextView textView) {
+ final CharSequence content = textView.getText();
+ if (content.getClass() == SpannableString.class || content instanceof Spannable) {
+ return (Spannable) content;
+ } else {
+ Log.w(TAG, "Expected " + TextView.class.getSimpleName() + " content to be of type " + Spannable.class.getSimpleName() + ", but was of type " + content.getClass() + ". Search highlighting will be not performant.");
+ final Spannable spannableContent = new SpannableString(content);
+ textView.setText(spannableContent, TextView.BufferType.SPANNABLE);
+ return spannableContent;
+ }
+ }
+
+ public static String getMarkdownLink(@NonNull String text, @NonNull String url) {
+ return "[" + text + "](" + url + ")";
+ }
+
+ /**
+ * Strips all Markdown from the given String
+ *
+ * @param s Markdown string
+ * @return Plain text string
+ */
+ @NonNull
+ public static String removeMarkdown(@Nullable String s) {
+ if (s == null)
+ return "";
+ String result = s;
+ result = PATTERN_LISTS.matcher(result).replaceAll("");
+ result = PATTERN_HEADINGS.matcher(result).replaceAll("$1");
+ result = PATTERN_HEADING_LINE.matcher(result).replaceAll("");
+ result = PATTERN_EMPHASIS.matcher(result).replaceAll("$2");
+ result = PATTERN_SPACE_1.matcher(result).replaceAll("");
+ result = PATTERN_SPACE_2.matcher(result).replaceAll("");
+ return result;
+ }
}
diff --git a/markdown/src/main/java/it/niedermann/android/markdown/markwon/MarkwonMarkdownEditor.java b/markdown/src/main/java/it/niedermann/android/markdown/markwon/MarkwonMarkdownEditor.java
index 1100da77..11d98e4e 100644
--- a/markdown/src/main/java/it/niedermann/android/markdown/markwon/MarkwonMarkdownEditor.java
+++ b/markdown/src/main/java/it/niedermann/android/markdown/markwon/MarkwonMarkdownEditor.java
@@ -18,6 +18,10 @@ import io.noties.markwon.Markwon;
import io.noties.markwon.editor.MarkwonEditor;
import io.noties.markwon.editor.handler.EmphasisEditHandler;
import io.noties.markwon.editor.handler.StrongEmphasisEditHandler;
+import io.noties.markwon.ext.strikethrough.StrikethroughPlugin;
+import io.noties.markwon.image.ImagesPlugin;
+import io.noties.markwon.inlineparser.MarkwonInlineParserPlugin;
+import io.noties.markwon.simple.ext.SimpleExtPlugin;
import it.niedermann.android.markdown.MarkdownEditor;
import it.niedermann.android.markdown.markwon.format.ContextBasedFormattingCallback;
import it.niedermann.android.markdown.markwon.format.ContextBasedRangeFormattingCallback;
@@ -26,6 +30,8 @@ import it.niedermann.android.markdown.markwon.handler.CodeBlockEditHandler;
import it.niedermann.android.markdown.markwon.handler.CodeEditHandler;
import it.niedermann.android.markdown.markwon.handler.HeadingEditHandler;
import it.niedermann.android.markdown.markwon.handler.StrikethroughEditHandler;
+import it.niedermann.android.markdown.markwon.plugins.SearchHighlightPlugin;
+import it.niedermann.android.markdown.markwon.plugins.ThemePlugin;
import it.niedermann.android.markdown.markwon.textwatcher.CombinedTextWatcher;
import it.niedermann.android.markdown.markwon.textwatcher.SearchHighlightTextWatcher;
@@ -46,16 +52,10 @@ public class MarkwonMarkdownEditor extends AppCompatEditText implements Markdown
public MarkwonMarkdownEditor(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
- final Markwon markwon = MarkwonMarkdownUtil.initMarkwonEditor(context).build();
- final MarkwonEditor editor = MarkwonEditor.builder(markwon)
- .useEditHandler(new EmphasisEditHandler())
- .useEditHandler(new StrongEmphasisEditHandler())
- .useEditHandler(new StrikethroughEditHandler())
- .useEditHandler(new CodeEditHandler())
- .useEditHandler(new CodeBlockEditHandler())
- .useEditHandler(new BlockQuoteEditHandler())
- .useEditHandler(new HeadingEditHandler())
- .build();
+
+ final Markwon markwon = createMarkwonBuilder(context).build();
+ final MarkwonEditor editor = createMarkwonEditorBuilder(markwon).build();
+
combinedWatcher = new CombinedTextWatcher(editor, this);
addTextChangedListener(combinedWatcher);
setCustomSelectionActionModeCallback(new ContextBasedRangeFormattingCallback(this));
@@ -64,6 +64,27 @@ public class MarkwonMarkdownEditor extends AppCompatEditText implements Markdown
}
}
+ private static Markwon.Builder createMarkwonBuilder(@NonNull Context context) {
+ return Markwon.builder(context)
+ .usePlugin(ThemePlugin.create(context))
+ .usePlugin(StrikethroughPlugin.create())
+ .usePlugin(SimpleExtPlugin.create())
+ .usePlugin(ImagesPlugin.create())
+ .usePlugin(MarkwonInlineParserPlugin.create())
+ .usePlugin(SearchHighlightPlugin.create(context));
+ }
+
+ private static MarkwonEditor.Builder createMarkwonEditorBuilder(@NonNull Markwon markwon) {
+ return MarkwonEditor.builder(markwon)
+ .useEditHandler(new EmphasisEditHandler())
+ .useEditHandler(new StrongEmphasisEditHandler())
+ .useEditHandler(new StrikethroughEditHandler())
+ .useEditHandler(new CodeEditHandler())
+ .useEditHandler(new CodeBlockEditHandler())
+ .useEditHandler(new BlockQuoteEditHandler())
+ .useEditHandler(new HeadingEditHandler());
+ }
+
@Override
public void setSearchColor(@ColorInt int color) {
final SearchHighlightTextWatcher searchHighlightTextWatcher = combinedWatcher.get(SearchHighlightTextWatcher.class);
diff --git a/markdown/src/main/java/it/niedermann/android/markdown/markwon/MarkwonMarkdownUtil.java b/markdown/src/main/java/it/niedermann/android/markdown/markwon/MarkwonMarkdownUtil.java
index f2863ebc..a49b0691 100644
--- a/markdown/src/main/java/it/niedermann/android/markdown/markwon/MarkwonMarkdownUtil.java
+++ b/markdown/src/main/java/it/niedermann/android/markdown/markwon/MarkwonMarkdownUtil.java
@@ -2,344 +2,17 @@ package it.niedermann.android.markdown.markwon;
import android.content.Context;
import android.content.res.Configuration;
-import android.text.Editable;
-import android.text.Spannable;
-import android.text.SpannableString;
-import android.text.TextUtils;
-import android.util.Log;
-import android.widget.TextView;
-import androidx.annotation.ColorInt;
import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.annotation.RestrictTo;
-import java.util.Map;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import io.noties.markwon.Markwon;
-import io.noties.markwon.ext.strikethrough.StrikethroughPlugin;
-import io.noties.markwon.ext.tables.TablePlugin;
-import io.noties.markwon.ext.tasklist.TaskListPlugin;
-import io.noties.markwon.image.ImagesPlugin;
-import io.noties.markwon.inlineparser.MarkwonInlineParserPlugin;
-import io.noties.markwon.linkify.LinkifyPlugin;
-import io.noties.markwon.simple.ext.SimpleExtPlugin;
-import io.noties.markwon.syntax.Prism4jTheme;
-import io.noties.markwon.syntax.Prism4jThemeDarkula;
-import io.noties.markwon.syntax.Prism4jThemeDefault;
-import io.noties.markwon.syntax.SyntaxHighlightPlugin;
-import io.noties.prism4j.Prism4j;
-import io.noties.prism4j.annotations.PrismBundle;
-import it.niedermann.android.markdown.markwon.model.EListType;
-import it.niedermann.android.markdown.markwon.plugins.LinkClickInterceptorPlugin;
-import it.niedermann.android.markdown.markwon.plugins.NextcloudMentionsPlugin;
-import it.niedermann.android.markdown.markwon.plugins.SearchHighlightPlugin;
-import it.niedermann.android.markdown.markwon.plugins.ThemePlugin;
-import it.niedermann.android.markdown.markwon.span.SearchSpan;
-
-@RestrictTo(value = RestrictTo.Scope.LIBRARY)
-@PrismBundle(includeAll = true, grammarLocatorClassName = ".MarkwonGrammarLocator")
public class MarkwonMarkdownUtil {
- private static final String TAG = MarkwonMarkdownUtil.class.getSimpleName();
- private static final Pattern PATTERN_CODE_FENCE = Pattern.compile("^(`{3,})");
- private static final Pattern PATTERN_ORDERED_LIST_ITEM = Pattern.compile("^(\\d+).\\s.+$");
- private static final Pattern PATTERN_ORDERED_LIST_ITEM_EMPTY = Pattern.compile("^(\\d+).\\s$");
- private static final Pattern PATTERN_MARKDOWN_LINK = Pattern.compile("\\[(.+)?]\\(([^ ]+?)?( \"(.+)\")?\\)");
-
private MarkwonMarkdownUtil() {
// Util class
}
- public static Markwon.Builder initMarkwonEditor(@NonNull Context context) {
- return Markwon.builder(context)
- .usePlugin(ThemePlugin.create(context))
- .usePlugin(StrikethroughPlugin.create())
- .usePlugin(SimpleExtPlugin.create())
- .usePlugin(ImagesPlugin.create())
- .usePlugin(MarkwonInlineParserPlugin.create())
- .usePlugin(SearchHighlightPlugin.create(context));
- }
-
- public static Markwon.Builder initMarkwonViewer(@NonNull Context context) {
- final Prism4j prism4j = new Prism4j(new MarkwonGrammarLocator());
- final Prism4jTheme prism4jTheme = isDarkThemeActive(context)
- ? Prism4jThemeDarkula.create()
- : Prism4jThemeDefault.create();
- return initMarkwonEditor(context)
- .usePlugin(TablePlugin.create(context))
- .usePlugin(TaskListPlugin.create(context))
- .usePlugin(LinkifyPlugin.create(true))
- .usePlugin(LinkClickInterceptorPlugin.create())
- .usePlugin(ImagesPlugin.create())
- .usePlugin(SyntaxHighlightPlugin.create(prism4j, prism4jTheme));
- }
-
- public static Markwon.Builder initMarkwonViewer(@NonNull Context context, @NonNull Map<String, String> mentions) {
- return initMarkwonViewer(context)
- .usePlugin(NextcloudMentionsPlugin.create(context, mentions));
- }
-
- private static boolean isDarkThemeActive(@NonNull Context context) {
+ public static boolean isDarkThemeActive(@NonNull Context context) {
final int uiMode = context.getResources().getConfiguration().uiMode;
return (uiMode & Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES;
}
-
- 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;
- }
-
- public static String getListItemIfIsEmpty(@NonNull String line) {
- for (EListType listType : EListType.values()) {
- if (line.equals(listType.checkboxUncheckedWithTrailingSpace)) {
- return listType.checkboxUncheckedWithTrailingSpace;
- } else if (line.equals(listType.listSymbolWithTrailingSpace)) {
- return listType.listSymbolWithTrailingSpace;
- }
- }
- final Matcher matcher = PATTERN_ORDERED_LIST_ITEM_EMPTY.matcher(line);
- if (matcher.find()) {
- return matcher.group();
- }
- return null;
- }
-
- public static CharSequence setCheckboxStatus(@NonNull String markdownString, int targetCheckboxIndex, boolean newCheckedState) {
- final String[] lines = markdownString.split("\n");
- int checkboxIndex = 0;
- boolean isInFencedCodeBlock = false;
- int fencedCodeBlockSigns = 0;
- for (int i = 0; i < lines.length; i++) {
- final Matcher matcher = PATTERN_CODE_FENCE.matcher(lines[i]);
- if (matcher.find()) {
- final String fence = matcher.group(1);
- if (fence != null) {
- int currentFencedCodeBlockSigns = fence.length();
- if (isInFencedCodeBlock) {
- if (currentFencedCodeBlockSigns == fencedCodeBlockSigns) {
- isInFencedCodeBlock = false;
- fencedCodeBlockSigns = 0;
- }
- } else {
- isInFencedCodeBlock = true;
- fencedCodeBlockSigns = currentFencedCodeBlockSigns;
- }
- }
- }
- if (!isInFencedCodeBlock) {
- if (lineStartsWithCheckbox(lines[i]) && lines[i].trim().length() > EListType.DASH.checkboxChecked.length()) {
- if (checkboxIndex == targetCheckboxIndex) {
- final int indexOfStartingBracket = lines[i].indexOf("[");
- final String toggledLine = lines[i].substring(0, indexOfStartingBracket + 1) +
- (newCheckedState ? 'x' : ' ') +
- lines[i].substring(indexOfStartingBracket + 2);
- lines[i] = toggledLine;
- break;
- }
- checkboxIndex++;
- }
- }
- }
- return TextUtils.join("\n", lines);
- }
-
- public static boolean lineStartsWithCheckbox(@NonNull String line) {
- for (EListType listType : EListType.values()) {
- if (lineStartsWithCheckbox(line, listType)) {
- return true;
- }
- }
- return false;
- }
-
- public static boolean lineStartsWithCheckbox(@NonNull String line, @NonNull EListType listType) {
- final String trimmedLine = line.trim();
- return (trimmedLine.startsWith(listType.checkboxUnchecked) || trimmedLine.startsWith(listType.checkboxChecked));
- }
-
- /**
- * @return the number of the ordered list item if the line is an ordered list, otherwise -1.
- */
- public static int getOrderedListNumber(@NonNull String line) {
- final Matcher matcher = PATTERN_ORDERED_LIST_ITEM.matcher(line);
- if (matcher.find()) {
- final String groupNumber = matcher.group(1);
- if (groupNumber != null) {
- try {
- return Integer.parseInt(groupNumber);
- } catch (NumberFormatException e) {
- return -1;
- }
- }
- }
- return -1;
- }
-
- /**
- * Modifies the {@param editable} and adds the given {@param punctuation} from
- * {@param selectionStart} to {@param selectionEnd} or removes the {@param punctuation} in case
- * it already is around the selected part.
- *
- * @return the new cursor position
- */
- public static int togglePunctuation(@NonNull Editable editable, int selectionStart, int selectionEnd, @NonNull String punctuation) {
- switch (punctuation) {
- case "**":
- case "__":
- case "*":
- case "_":
- case "~~": {
- final boolean selectionIsSurroundedByPunctuation = selectionIsSurroundedByPunctuation(editable, selectionStart, selectionEnd, punctuation);
- if (selectionIsSurroundedByPunctuation) {
- editable.delete(selectionEnd, selectionEnd + punctuation.length());
- editable.delete(selectionStart - punctuation.length(), selectionStart);
- return selectionEnd - punctuation.length();
- } else {
- final int containedPunctuationCount = getContainedPunctuationCount(editable, selectionStart, selectionEnd, punctuation);
- if (containedPunctuationCount == 0) {
- editable.insert(selectionEnd, punctuation);
- editable.insert(selectionStart, punctuation);
- return selectionEnd + punctuation.length() * 2;
- } else if (containedPunctuationCount % 2 > 0) {
- return selectionEnd;
- } else {
- removeContainingPunctuation(editable, selectionStart, selectionEnd, punctuation);
- return selectionEnd - containedPunctuationCount * punctuation.length();
- }
- }
- }
- default:
- throw new UnsupportedOperationException("This kind of punctuation is not yet supported: " + punctuation);
- }
- }
-
- /**
- * Inserts a link into the given {@param editable} from {@param selectionStart} to {@param selectionEnd} and uses the {@param clipboardUrl} if available.
- *
- * @return the new cursor position
- */
- public static int insertLink(@NonNull Editable editable, int selectionStart, int selectionEnd, @Nullable String clipboardUrl) {
- if (selectionStart == selectionEnd) {
- editable.insert(selectionStart, "[](" + (clipboardUrl == null ? "" : clipboardUrl) + ")");
- return selectionStart + 1;
- } else {
- final boolean textToFormatIsLink = TextUtils.indexOf(editable.subSequence(selectionStart, selectionEnd), "http") == 0;
- if (textToFormatIsLink) {
- if (clipboardUrl == null) {
- editable.insert(selectionEnd, ")");
- editable.insert(selectionStart, "[](");
- } else {
- editable.insert(selectionEnd, "](" + clipboardUrl + ")");
- editable.insert(selectionStart, "[");
- selectionEnd += clipboardUrl.length();
- }
- } else {
- if (clipboardUrl == null) {
- editable.insert(selectionEnd, "]()");
- } else {
- editable.insert(selectionEnd, "](" + clipboardUrl + ")");
- selectionEnd += clipboardUrl.length();
- }
- editable.insert(selectionStart, "[");
- }
- return textToFormatIsLink && clipboardUrl == null
- ? selectionStart + 1
- : selectionEnd + 3;
- }
- }
-
- /**
- * @return whether or not the selection of {@param text} from {@param start} to {@param end} is
- * surrounded or not by the given {@param punctuation}.
- */
- private static boolean selectionIsSurroundedByPunctuation(@NonNull CharSequence text, int start, int end, @NonNull String punctuation) {
- if (text.length() < end + punctuation.length()) {
- return false;
- }
- if (start - punctuation.length() < 0 || end + punctuation.length() > text.length()) {
- return false;
- }
- return punctuation.contentEquals(text.subSequence(start - punctuation.length(), start))
- && punctuation.contentEquals(text.subSequence(end, end + punctuation.length()));
- }
-
- private static int getContainedPunctuationCount(@NonNull CharSequence text, int start, int end, @NonNull String punctuation) {
- final Matcher matcher = Pattern.compile(Pattern.quote(punctuation)).matcher(text.subSequence(start, end));
- int counter = 0;
- while (matcher.find()) {
- counter++;
- }
- return counter;
- }
-
- private static void removeContainingPunctuation(@NonNull Editable editable, int start, int end, @NonNull String punctuation) {
- final Matcher matcher = Pattern.compile(Pattern.quote(punctuation)).matcher(editable.subSequence(start, end));
- int countDeletedPunctuations = 0;
- while (matcher.find()) {
- editable.delete(start + matcher.start() - countDeletedPunctuations * punctuation.length(), start + matcher.end() - countDeletedPunctuations * punctuation.length());
- countDeletedPunctuations++;
- }
- }
-
- public static boolean selectionIsInLink(@NonNull CharSequence text, int start, int end) {
- final Matcher matcher = PATTERN_MARKDOWN_LINK.matcher(text);
- while (matcher.find()) {
- if ((start >= matcher.start() && start < matcher.end()) || (end > matcher.start() && end <= matcher.end())) {
- return true;
- }
- }
- return false;
- }
-
- public static void searchAndColor(@NonNull Spannable editable, @Nullable CharSequence searchText, @NonNull Context context, @Nullable Integer current, @ColorInt int mainColor) {
- if (searchText != null) {
- final Matcher m = Pattern
- .compile(searchText.toString(), Pattern.CASE_INSENSITIVE | Pattern.LITERAL)
- .matcher(editable);
-
- int i = 1;
- while (m.find()) {
- int start = m.start();
- int end = m.end();
- editable.setSpan(new SearchSpan(context, mainColor, (current != null && i == current)), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
- i++;
- }
- }
- }
-
- public static <T> void removeSpans(@NonNull Spannable spannable, @SuppressWarnings("SameParameterValue") Class<T> spanType) {
- for (T span : spannable.getSpans(0, spannable.length(), spanType)) {
- spannable.removeSpan(span);
- }
- }
-
- /**
- * @return When the content of the {@param textView} is already of type {@link Spannable}, it will cast and return it directly.
- * Otherwise it will create a new {@link SpannableString} from the content, set this as new content of the {@param textView} and return it.
- */
- public static Spannable getContentAsSpannable(@NonNull TextView textView) {
- final CharSequence content = textView.getText();
- if (content.getClass() == SpannableString.class || content instanceof Spannable) {
- return (Spannable) content;
- } else {
- Log.w(TAG, "Expected " + TextView.class.getSimpleName() + " content to be of type " + Spannable.class.getSimpleName() + ", but was of type " + content.getClass() + ". Search highlighting will be not performant.");
- final Spannable spannableContent = new SpannableString(content);
- textView.setText(spannableContent, TextView.BufferType.SPANNABLE);
- return spannableContent;
- }
- }
}
diff --git a/markdown/src/main/java/it/niedermann/android/markdown/markwon/MarkwonMarkdownViewer.java b/markdown/src/main/java/it/niedermann/android/markdown/markwon/MarkwonMarkdownViewer.java
index 019e5576..24ce4e51 100644
--- a/markdown/src/main/java/it/niedermann/android/markdown/markwon/MarkwonMarkdownViewer.java
+++ b/markdown/src/main/java/it/niedermann/android/markdown/markwon/MarkwonMarkdownViewer.java
@@ -19,18 +19,38 @@ import java.util.function.Function;
import io.noties.markwon.Markwon;
import io.noties.markwon.MarkwonPlugin;
+import io.noties.markwon.SoftBreakAddsNewLinePlugin;
+import io.noties.markwon.ext.strikethrough.StrikethroughPlugin;
+import io.noties.markwon.ext.tables.TablePlugin;
+import io.noties.markwon.ext.tasklist.TaskListPlugin;
+import io.noties.markwon.image.DefaultDownScalingMediaDecoder;
+import io.noties.markwon.image.ImagesPlugin;
+import io.noties.markwon.inlineparser.MarkwonInlineParserPlugin;
+import io.noties.markwon.linkify.LinkifyPlugin;
+import io.noties.markwon.simple.ext.SimpleExtPlugin;
+import io.noties.markwon.syntax.Prism4jTheme;
+import io.noties.markwon.syntax.Prism4jThemeDarkula;
+import io.noties.markwon.syntax.Prism4jThemeDefault;
+import io.noties.markwon.syntax.SyntaxHighlightPlugin;
+import io.noties.prism4j.Prism4j;
+import io.noties.prism4j.annotations.PrismBundle;
import it.niedermann.android.markdown.MarkdownEditor;
+import it.niedermann.android.markdown.MarkdownUtil;
import it.niedermann.android.markdown.markwon.plugins.LinkClickInterceptorPlugin;
+import it.niedermann.android.markdown.markwon.plugins.NextcloudMentionsPlugin;
import it.niedermann.android.markdown.markwon.plugins.SearchHighlightPlugin;
+import it.niedermann.android.markdown.markwon.plugins.ThemePlugin;
import it.niedermann.android.markdown.markwon.plugins.ToggleableTaskListPlugin;
import static androidx.lifecycle.Transformations.distinctUntilChanged;
-import static it.niedermann.android.markdown.markwon.MarkwonMarkdownUtil.initMarkwonViewer;
+@PrismBundle(includeAll = true, grammarLocatorClassName = ".MarkwonGrammarLocator")
public class MarkwonMarkdownViewer extends AppCompatTextView implements MarkdownEditor {
private static final String TAG = MarkwonMarkdownViewer.class.getSimpleName();
+ private static final Prism4j prism4j = new Prism4j(new MarkwonGrammarLocator());
+
private Markwon markwon;
private final MutableLiveData<CharSequence> unrenderedText$ = new MutableLiveData<>();
@@ -46,27 +66,60 @@ public class MarkwonMarkdownViewer extends AppCompatTextView implements Markdown
public MarkwonMarkdownViewer(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
- this.markwon = initMarkwonViewer(context)
+ this.markwon = createMarkwonBuilder(context).build();
+ this.renderService = Executors.newSingleThreadExecutor();
+ }
+
+ private Markwon.Builder createMarkwonBuilder(@NonNull Context context) {
+ final Prism4jTheme prism4jTheme = MarkwonMarkdownUtil.isDarkThemeActive(context)
+ ? Prism4jThemeDarkula.create()
+ : Prism4jThemeDefault.create();
+ return Markwon.builder(context)
+ .usePlugin(ThemePlugin.create(context))
+ .usePlugin(StrikethroughPlugin.create())
+ .usePlugin(SimpleExtPlugin.create())
+ .usePlugin(MarkwonInlineParserPlugin.create())
+ .usePlugin(SearchHighlightPlugin.create(context))
+ .usePlugin(TablePlugin.create(context))
+ .usePlugin(TaskListPlugin.create(context))
+ .usePlugin(LinkifyPlugin.create(true))
+ .usePlugin(LinkClickInterceptorPlugin.create())
+ .usePlugin(ImagesPlugin.create(plugin -> plugin.defaultMediaDecoder(DefaultDownScalingMediaDecoder.create(context.getResources().getDisplayMetrics().widthPixels, 0))))
+ .usePlugin(SoftBreakAddsNewLinePlugin.create())
+ .usePlugin(SyntaxHighlightPlugin.create(prism4j, prism4jTheme))
.usePlugin(new ToggleableTaskListPlugin((toggledCheckboxPosition, newCheckedState) -> {
final CharSequence oldUnrenderedText = unrenderedText$.getValue();
if (oldUnrenderedText == null) {
throw new IllegalStateException("Checkbox #" + toggledCheckboxPosition + ", but unrenderedText$ value is null.");
}
- final CharSequence newUnrenderedText = MarkwonMarkdownUtil.setCheckboxStatus(oldUnrenderedText.toString(), toggledCheckboxPosition, newCheckedState);
+ final CharSequence newUnrenderedText = MarkdownUtil.setCheckboxStatus(oldUnrenderedText.toString(), toggledCheckboxPosition, newCheckedState);
this.setMarkdownString(newUnrenderedText);
- }))
- .build();
- this.renderService = Executors.newSingleThreadExecutor();
+ }));
+ }
+
+ public Markwon.Builder createMarkwonBuilder(@NonNull Context context, @NonNull Map<String, String> mentions) {
+ return createMarkwonBuilder(context)
+ .usePlugin(NextcloudMentionsPlugin.create(context, mentions));
}
@Override
public void registerOnLinkClickCallback(@NonNull Function<String, Boolean> callback) {
- this.markwon.getPlugin(LinkClickInterceptorPlugin.class).registerOnLinkClickCallback(callback);
+ final LinkClickInterceptorPlugin plugin = this.markwon.getPlugin(LinkClickInterceptorPlugin.class);
+ if (plugin == null) {
+ Log.w(TAG, "Tried to register callback, but " + LinkClickInterceptorPlugin.class.getSimpleName() + " is not a registered " + MarkwonPlugin.class.getSimpleName() + ".");
+ } else {
+ plugin.registerOnLinkClickCallback(callback);
+ }
}
@Override
public void setEnabled(boolean enabled) {
- this.markwon.getPlugin(ToggleableTaskListPlugin.class).setEnabled(enabled);
+ final ToggleableTaskListPlugin plugin = this.markwon.getPlugin(ToggleableTaskListPlugin.class);
+ if (plugin == null) {
+ Log.w(TAG, "Tried to set enabled state for " + ToggleableTaskListPlugin.class.getSimpleName() + ", but " + ToggleableTaskListPlugin.class.getSimpleName() + " is not a registered " + MarkwonPlugin.class.getSimpleName() + ".");
+ } else {
+ plugin.setEnabled(enabled);
+ }
}
@Override
@@ -104,7 +157,7 @@ public class MarkwonMarkdownViewer extends AppCompatTextView implements Markdown
@Override
public void setMarkdownString(CharSequence text, @NonNull Map<String, String> mentions) {
- this.markwon = initMarkwonViewer(getContext(), mentions).build();
+ this.markwon = createMarkwonBuilder(getContext(), mentions).build();
setMarkdownString(text);
}
diff --git a/markdown/src/main/java/it/niedermann/android/markdown/markwon/format/ContextBasedFormattingCallback.java b/markdown/src/main/java/it/niedermann/android/markdown/markwon/format/ContextBasedFormattingCallback.java
index c4469bc3..37d81554 100644
--- a/markdown/src/main/java/it/niedermann/android/markdown/markwon/format/ContextBasedFormattingCallback.java
+++ b/markdown/src/main/java/it/niedermann/android/markdown/markwon/format/ContextBasedFormattingCallback.java
@@ -8,13 +8,13 @@ import android.view.MenuItem;
import it.niedermann.android.markdown.R;
import it.niedermann.android.markdown.markwon.MarkwonMarkdownEditor;
-import it.niedermann.android.markdown.markwon.MarkwonMarkdownUtil;
-import it.niedermann.android.markdown.markwon.model.EListType;
+import it.niedermann.android.markdown.MarkdownUtil;
+import it.niedermann.android.markdown.model.EListType;
import it.niedermann.android.util.ClipboardUtil;
-import static it.niedermann.android.markdown.markwon.MarkwonMarkdownUtil.getEndOfLine;
-import static it.niedermann.android.markdown.markwon.MarkwonMarkdownUtil.getStartOfLine;
-import static it.niedermann.android.markdown.markwon.MarkwonMarkdownUtil.lineStartsWithCheckbox;
+import static it.niedermann.android.markdown.MarkdownUtil.getEndOfLine;
+import static it.niedermann.android.markdown.MarkdownUtil.getStartOfLine;
+import static it.niedermann.android.markdown.MarkdownUtil.lineStartsWithCheckbox;
public class ContextBasedFormattingCallback implements ActionMode.Callback {
@@ -65,7 +65,7 @@ public class ContextBasedFormattingCallback implements ActionMode.Callback {
editText.setSelection(cursorPosition + EListType.DASH.checkboxUncheckedWithTrailingSpace.length());
return true;
} else if (itemId == R.id.link) {
- final int newSelection = MarkwonMarkdownUtil.insertLink(editable, cursorPosition, cursorPosition, ClipboardUtil.INSTANCE.getClipboardURLorNull(editText.getContext()));
+ final int newSelection = MarkdownUtil.insertLink(editable, cursorPosition, cursorPosition, ClipboardUtil.INSTANCE.getClipboardURLorNull(editText.getContext()));
editText.setMarkdownStringModel(editable);
editText.setSelection(newSelection);
return true;
diff --git a/markdown/src/main/java/it/niedermann/android/markdown/markwon/format/ContextBasedRangeFormattingCallback.java b/markdown/src/main/java/it/niedermann/android/markdown/markwon/format/ContextBasedRangeFormattingCallback.java
index 86ce5cdb..f3f90be4 100644
--- a/markdown/src/main/java/it/niedermann/android/markdown/markwon/format/ContextBasedRangeFormattingCallback.java
+++ b/markdown/src/main/java/it/niedermann/android/markdown/markwon/format/ContextBasedRangeFormattingCallback.java
@@ -12,7 +12,7 @@ import android.view.MenuItem;
import it.niedermann.android.markdown.R;
import it.niedermann.android.markdown.markwon.MarkwonMarkdownEditor;
-import it.niedermann.android.markdown.markwon.MarkwonMarkdownUtil;
+import it.niedermann.android.markdown.MarkdownUtil;
import it.niedermann.android.util.ClipboardUtil;
public class ContextBasedRangeFormattingCallback implements ActionMode.Callback {
@@ -55,7 +55,7 @@ public class ContextBasedRangeFormattingCallback implements ActionMode.Callback
final int selectionStart = editText.getSelectionStart();
final int selectionEnd = editText.getSelectionEnd();
if (selectionStart >= 0 && selectionStart <= text.length()) {
- if (MarkwonMarkdownUtil.selectionIsInLink(text, selectionStart, selectionEnd)) {
+ if (MarkdownUtil.selectionIsInLink(text, selectionStart, selectionEnd)) {
menu.findItem(R.id.link).setVisible(false);
Log.i(TAG, "Hide link menu item because the selection is already within a link.");
}
@@ -75,17 +75,17 @@ public class ContextBasedRangeFormattingCallback implements ActionMode.Callback
final int end = editText.getSelectionEnd();
if (itemId == R.id.bold) {
- final int newSelection = MarkwonMarkdownUtil.togglePunctuation(editable, start, end, "**");
+ final int newSelection = MarkdownUtil.togglePunctuation(editable, start, end, "**");
editText.setMarkdownStringModel(editable);
editText.setSelection(newSelection);
return true;
} else if (itemId == R.id.italic) {
- final int newSelection = MarkwonMarkdownUtil.togglePunctuation(editable, start, end, "*");
+ final int newSelection = MarkdownUtil.togglePunctuation(editable, start, end, "*");
editText.setMarkdownStringModel(editable);
editText.setSelection(newSelection);
return true;
} else if (itemId == R.id.link) {
- final int newSelection = MarkwonMarkdownUtil.insertLink(editable, start, end, ClipboardUtil.INSTANCE.getClipboardURLorNull(editText.getContext()));
+ final int newSelection = MarkdownUtil.insertLink(editable, start, end, ClipboardUtil.INSTANCE.getClipboardURLorNull(editText.getContext()));
editText.setMarkdownStringModel(editable);
editText.setSelection(newSelection);
return true;
diff --git a/markdown/src/main/java/it/niedermann/android/markdown/markwon/plugins/LinkClickInterceptorPlugin.java b/markdown/src/main/java/it/niedermann/android/markdown/markwon/plugins/LinkClickInterceptorPlugin.java
index 8896a2a3..e815b54b 100644
--- a/markdown/src/main/java/it/niedermann/android/markdown/markwon/plugins/LinkClickInterceptorPlugin.java
+++ b/markdown/src/main/java/it/niedermann/android/markdown/markwon/plugins/LinkClickInterceptorPlugin.java
@@ -15,7 +15,7 @@ import io.noties.markwon.MarkwonPlugin;
import it.niedermann.android.markdown.markwon.span.InterceptedURLSpan;
import static android.text.Spanned.SPAN_EXCLUSIVE_EXCLUSIVE;
-import static it.niedermann.android.markdown.markwon.MarkwonMarkdownUtil.getContentAsSpannable;
+import static it.niedermann.android.markdown.MarkdownUtil.getContentAsSpannable;
public class LinkClickInterceptorPlugin extends AbstractMarkwonPlugin {
diff --git a/markdown/src/main/java/it/niedermann/android/markdown/markwon/plugins/SearchHighlightPlugin.java b/markdown/src/main/java/it/niedermann/android/markdown/markwon/plugins/SearchHighlightPlugin.java
index 53d4562e..b48db3dd 100644
--- a/markdown/src/main/java/it/niedermann/android/markdown/markwon/plugins/SearchHighlightPlugin.java
+++ b/markdown/src/main/java/it/niedermann/android/markdown/markwon/plugins/SearchHighlightPlugin.java
@@ -12,21 +12,28 @@ import androidx.core.content.ContextCompat;
import io.noties.markwon.AbstractMarkwonPlugin;
import io.noties.markwon.MarkwonPlugin;
+import it.niedermann.android.markdown.MarkdownUtil;
import it.niedermann.android.markdown.R;
import it.niedermann.android.markdown.markwon.MarkwonMarkdownUtil;
-import it.niedermann.android.markdown.markwon.span.SearchSpan;
+import it.niedermann.android.markdown.model.SearchSpan;
-import static it.niedermann.android.markdown.markwon.MarkwonMarkdownUtil.getContentAsSpannable;
+import static it.niedermann.android.markdown.MarkdownUtil.getContentAsSpannable;
public class SearchHighlightPlugin extends AbstractMarkwonPlugin {
@Nullable
private CharSequence searchText = null;
private Integer current;
+ @ColorInt
private int color;
+ @ColorInt
+ private final int highlightColor;
+ private final boolean darkTheme;
public SearchHighlightPlugin(@NonNull Context context) {
- color = ContextCompat.getColor(context, R.color.search_color);
+ this.color = ContextCompat.getColor(context, R.color.search_color);
+ this.highlightColor = ContextCompat.getColor(context, R.color.bg_highlighted);
+ this.darkTheme = MarkwonMarkdownUtil.isDarkThemeActive(context);
}
public static MarkwonPlugin create(@NonNull Context context) {
@@ -35,7 +42,7 @@ public class SearchHighlightPlugin extends AbstractMarkwonPlugin {
public void setSearchText(@Nullable CharSequence searchText, @Nullable Integer current, @NonNull TextView textView) {
this.current = current;
- MarkwonMarkdownUtil.removeSpans(getContentAsSpannable(textView), SearchSpan.class);
+ MarkdownUtil.removeSpans(getContentAsSpannable(textView), SearchSpan.class);
if (TextUtils.isEmpty(searchText)) {
this.searchText = null;
} else {
@@ -54,7 +61,7 @@ public class SearchHighlightPlugin extends AbstractMarkwonPlugin {
super.afterSetText(textView);
if (this.searchText != null) {
final Spannable spannable = getContentAsSpannable(textView);
- MarkwonMarkdownUtil.searchAndColor(spannable, searchText, textView.getContext(), current, color);
+ MarkdownUtil.searchAndColor(spannable, searchText, current, color, highlightColor, darkTheme);
}
}
}
diff --git a/markdown/src/main/java/it/niedermann/android/markdown/markwon/textwatcher/AutoContinuationTextWatcher.java b/markdown/src/main/java/it/niedermann/android/markdown/markwon/textwatcher/AutoContinuationTextWatcher.java
index 44bde738..00369742 100644
--- a/markdown/src/main/java/it/niedermann/android/markdown/markwon/textwatcher/AutoContinuationTextWatcher.java
+++ b/markdown/src/main/java/it/niedermann/android/markdown/markwon/textwatcher/AutoContinuationTextWatcher.java
@@ -6,12 +6,13 @@ import android.text.TextWatcher;
import androidx.annotation.NonNull;
import it.niedermann.android.markdown.markwon.MarkwonMarkdownEditor;
-import it.niedermann.android.markdown.markwon.model.EListType;
+import it.niedermann.android.markdown.model.EListType;
-import static it.niedermann.android.markdown.markwon.MarkwonMarkdownUtil.getListItemIfIsEmpty;
-import static it.niedermann.android.markdown.markwon.MarkwonMarkdownUtil.getOrderedListNumber;
-import static it.niedermann.android.markdown.markwon.MarkwonMarkdownUtil.getStartOfLine;
-import static it.niedermann.android.markdown.markwon.MarkwonMarkdownUtil.lineStartsWithCheckbox;
+import static it.niedermann.android.markdown.MarkdownUtil.getEndOfLine;
+import static it.niedermann.android.markdown.MarkdownUtil.getListItemIfIsEmpty;
+import static it.niedermann.android.markdown.MarkdownUtil.getOrderedListNumber;
+import static it.niedermann.android.markdown.MarkdownUtil.getStartOfLine;
+import static it.niedermann.android.markdown.MarkdownUtil.lineStartsWithCheckbox;
/**
* Automatically continues lists and checkbox lists when pressing enter
@@ -22,6 +23,7 @@ public class AutoContinuationTextWatcher extends InterceptorTextWatcher {
private final MarkwonMarkdownEditor editText;
private CharSequence customText = null;
+ private CharSequence oldText = null;
private boolean isInsert = true;
private int sequenceStart = 0;
@@ -32,9 +34,13 @@ public class AutoContinuationTextWatcher extends InterceptorTextWatcher {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
- if (count == 1 && s.charAt(start) == '\n') {
- handleNewlineInserted(s, start, count);
+ if (count > 0) {
+ CharSequence inserted = getInsertedString(s, start, before, count);
+ if (inserted.length() > 0 && inserted.charAt(inserted.length() - 1) == '\n') {
+ handleNewlineInserted(s, start, count);
+ }
}
+ oldText = s.toString();
originalWatcher.onTextChanged(s, start, before, count);
}
@@ -54,6 +60,15 @@ public class AutoContinuationTextWatcher extends InterceptorTextWatcher {
editText.setMarkdownStringModel(s);
}
+ private CharSequence getInsertedString(CharSequence newText, int start, int before, int count) {
+ if (newText != null && newText.length() > (oldText == null ? 0 : oldText.length())) {
+ // character added
+ int position = start + before;
+ return newText.subSequence(position, position + count - before);
+ }
+ return "";
+ }
+
private void deleteCustomText(Editable s, CharSequence customText) {
s.replace(sequenceStart, sequenceStart + customText.length() + 1, "\n");
editText.setSelection(sequenceStart + 1);
@@ -66,7 +81,7 @@ public class AutoContinuationTextWatcher extends InterceptorTextWatcher {
private void handleNewlineInserted(CharSequence originalSequence, int start, int count) {
final CharSequence s = originalSequence.subSequence(0, originalSequence.length());
final int startOfLine = getStartOfLine(s, start);
- final String line = s.subSequence(startOfLine, start).toString();
+ final String line = s.subSequence(startOfLine, getEndOfLine(s, start)).toString();
final String emptyListString = getListItemIfIsEmpty(line);
if (emptyListString != null) {
diff --git a/markdown/src/main/java/it/niedermann/android/markdown/markwon/textwatcher/SearchHighlightTextWatcher.java b/markdown/src/main/java/it/niedermann/android/markdown/markwon/textwatcher/SearchHighlightTextWatcher.java
index 67b630d9..2e226ff5 100644
--- a/markdown/src/main/java/it/niedermann/android/markdown/markwon/textwatcher/SearchHighlightTextWatcher.java
+++ b/markdown/src/main/java/it/niedermann/android/markdown/markwon/textwatcher/SearchHighlightTextWatcher.java
@@ -1,5 +1,6 @@
package it.niedermann.android.markdown.markwon.textwatcher;
+import android.content.Context;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
@@ -9,10 +10,11 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
+import it.niedermann.android.markdown.MarkdownUtil;
import it.niedermann.android.markdown.R;
import it.niedermann.android.markdown.markwon.MarkwonMarkdownEditor;
import it.niedermann.android.markdown.markwon.MarkwonMarkdownUtil;
-import it.niedermann.android.markdown.markwon.span.SearchSpan;
+import it.niedermann.android.markdown.model.SearchSpan;
public class SearchHighlightTextWatcher extends InterceptorTextWatcher {
@@ -20,19 +22,29 @@ public class SearchHighlightTextWatcher extends InterceptorTextWatcher {
@Nullable
private CharSequence searchText;
private Integer current;
+ @ColorInt
private int color;
+ @ColorInt
+ private final int highlightColor;
+ private final boolean darkTheme;
public SearchHighlightTextWatcher(@NonNull TextWatcher originalWatcher, @NonNull MarkwonMarkdownEditor editText) {
super(originalWatcher);
this.editText = editText;
- this.color = ContextCompat.getColor(editText.getContext(), R.color.search_color);
+ final Context context = editText.getContext();
+ this.color = ContextCompat.getColor(context, R.color.search_color);
+ this.highlightColor = ContextCompat.getColor(context, R.color.bg_highlighted);
+ this.darkTheme = MarkwonMarkdownUtil.isDarkThemeActive(context);
}
public void setSearchText(@Nullable CharSequence searchText, @Nullable Integer current) {
this.current = current;
if (TextUtils.isEmpty(searchText)) {
this.searchText = null;
- MarkwonMarkdownUtil.removeSpans(editText.getText(), SearchSpan.class);
+ final Editable text = editText.getText();
+ if (text != null) {
+ MarkdownUtil.removeSpans(text, SearchSpan.class);
+ }
} else {
this.searchText = searchText;
afterTextChanged(editText.getText());
@@ -48,8 +60,8 @@ public class SearchHighlightTextWatcher extends InterceptorTextWatcher {
public void afterTextChanged(Editable s) {
originalWatcher.afterTextChanged(s);
if (searchText != null) {
- MarkwonMarkdownUtil.removeSpans(s, SearchSpan.class);
- MarkwonMarkdownUtil.searchAndColor(s, searchText, editText.getContext(), current, color);
+ MarkdownUtil.removeSpans(s, SearchSpan.class);
+ MarkdownUtil.searchAndColor(s, searchText, current, color, highlightColor, darkTheme);
}
}
}
diff --git a/markdown/src/main/java/it/niedermann/android/markdown/markwon/model/EListType.java b/markdown/src/main/java/it/niedermann/android/markdown/model/EListType.java
index a03987fd..0bd7d7a9 100644
--- a/markdown/src/main/java/it/niedermann/android/markdown/markwon/model/EListType.java
+++ b/markdown/src/main/java/it/niedermann/android/markdown/model/EListType.java
@@ -1,4 +1,4 @@
-package it.niedermann.android.markdown.markwon.model;
+package it.niedermann.android.markdown.model;
public enum EListType {
STAR('*'),
diff --git a/markdown/src/main/java/it/niedermann/android/markdown/markwon/span/SearchSpan.java b/markdown/src/main/java/it/niedermann/android/markdown/model/SearchSpan.java
index fa740cf6..b6c049c3 100644
--- a/markdown/src/main/java/it/niedermann/android/markdown/markwon/span/SearchSpan.java
+++ b/markdown/src/main/java/it/niedermann/android/markdown/model/SearchSpan.java
@@ -1,7 +1,5 @@
-package it.niedermann.android.markdown.markwon.span;
+package it.niedermann.android.markdown.model;
-import android.content.Context;
-import android.content.res.Configuration;
import android.graphics.Color;
import android.text.TextPaint;
import android.text.style.MetricAffectingSpan;
@@ -9,30 +7,28 @@ import android.text.style.MetricAffectingSpan;
import androidx.annotation.ColorInt;
import androidx.annotation.NonNull;
-import it.niedermann.android.markdown.R;
import it.niedermann.android.util.ColorUtil;
public class SearchSpan extends MetricAffectingSpan {
private final boolean current;
- @NonNull
- Context context;
@ColorInt
private final int mainColor;
@ColorInt
private final int highlightColor;
+ private final boolean darkTheme;
- public SearchSpan(@NonNull Context context, @ColorInt int mainColor, boolean current) {
- this.context = context;
+ public SearchSpan(@ColorInt int mainColor, @ColorInt int highlightColor, boolean current, boolean darkTheme) {
this.mainColor = mainColor;
this.current = current;
- this.highlightColor = context.getResources().getColor(R.color.bg_highlighted);
+ this.highlightColor = highlightColor;
+ this.darkTheme = darkTheme;
}
@Override
public void updateDrawState(TextPaint tp) {
if (current) {
- if (isDarkThemeActive(context)) {
+ if (darkTheme) {
if (ColorUtil.INSTANCE.isColorDark(mainColor)) {
tp.bgColor = Color.WHITE;
tp.setColor(mainColor);
@@ -58,7 +54,7 @@ public class SearchSpan extends MetricAffectingSpan {
if (ColorUtil.INSTANCE.getContrastRatio(mainColor, highlightColor) > 3d) {
tp.setColor(mainColor);
} else {
- if (isDarkThemeActive(context)) {
+ if (darkTheme) {
tp.setColor(Color.WHITE);
} else {
tp.setColor(Color.BLACK);
@@ -72,9 +68,4 @@ public class SearchSpan extends MetricAffectingSpan {
public void updateMeasureState(@NonNull TextPaint tp) {
tp.setFakeBoldText(true);
}
-
- private static boolean isDarkThemeActive(Context context) {
- int uiMode = context.getResources().getConfiguration().uiMode;
- return (uiMode & Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES;
- }
} \ No newline at end of file
diff --git a/markdown/src/main/java/it/niedermann/android/markdown/rxmarkdown/RxMarkdownEditor.java b/markdown/src/main/java/it/niedermann/android/markdown/rxmarkdown/RxMarkdownEditor.java
deleted file mode 100644
index 1d02d989..00000000
--- a/markdown/src/main/java/it/niedermann/android/markdown/rxmarkdown/RxMarkdownEditor.java
+++ /dev/null
@@ -1,72 +0,0 @@
-package it.niedermann.android.markdown.rxmarkdown;
-
-import android.content.Context;
-import android.text.Editable;
-import android.text.TextWatcher;
-import android.util.AttributeSet;
-
-import androidx.lifecycle.LiveData;
-import androidx.lifecycle.MutableLiveData;
-
-import com.yydcdut.markdown.MarkdownEditText;
-import com.yydcdut.markdown.MarkdownProcessor;
-import com.yydcdut.markdown.syntax.edit.EditFactory;
-
-import it.niedermann.android.markdown.MarkdownEditor;
-
-import static androidx.lifecycle.Transformations.distinctUntilChanged;
-
-@Deprecated
-public class RxMarkdownEditor extends MarkdownEditText implements MarkdownEditor {
-
- private final MutableLiveData<CharSequence> unrenderedText$ = new MutableLiveData<>();
- private MarkdownProcessor markdownProcessor;
-
- public RxMarkdownEditor(Context context) {
- super(context);
- init(context);
- }
-
- public RxMarkdownEditor(Context context, AttributeSet attrs) {
- super(context, attrs);
- init(context);
- }
-
- public RxMarkdownEditor(Context context, AttributeSet attrs, int defStyleAttr) {
- super(context, attrs, defStyleAttr);
- init(context);
- }
-
- private void init(Context context) {
- markdownProcessor = new MarkdownProcessor(context);
- markdownProcessor.config(RxMarkdownUtil.getMarkDownConfiguration(context).build());
- markdownProcessor.factory(EditFactory.create());
- markdownProcessor.live(this);
- addTextChangedListener(new TextWatcher() {
- @Override
- public void beforeTextChanged(CharSequence s, int start, int count, int after) {
-
- }
-
- @Override
- public void onTextChanged(CharSequence s, int start, int before, int count) {
- unrenderedText$.setValue(s.toString());
- }
-
- @Override
- public void afterTextChanged(Editable s) {
-
- }
- });
- }
-
- @Override
- public void setMarkdownString(CharSequence text) {
- setText(markdownProcessor.parse(text));
- }
-
- @Override
- public LiveData<CharSequence> getMarkdownString() {
- return distinctUntilChanged(unrenderedText$);
- }
-}
diff --git a/markdown/src/main/java/it/niedermann/android/markdown/rxmarkdown/RxMarkdownUtil.java b/markdown/src/main/java/it/niedermann/android/markdown/rxmarkdown/RxMarkdownUtil.java
deleted file mode 100644
index 16c1652a..00000000
--- a/markdown/src/main/java/it/niedermann/android/markdown/rxmarkdown/RxMarkdownUtil.java
+++ /dev/null
@@ -1,44 +0,0 @@
-package it.niedermann.android.markdown.rxmarkdown;
-
-import android.content.Context;
-
-import androidx.annotation.RestrictTo;
-
-import com.yydcdut.rxmarkdown.RxMDConfiguration.Builder;
-
-/**
- * Created by stefan on 07.12.16.
- */
-@Deprecated
-@RestrictTo(value = RestrictTo.Scope.LIBRARY)
-public class RxMarkdownUtil {
-
- private RxMarkdownUtil() {
- }
-
- /**
- * Ensures every instance of RxMD uses the same configuration
- *
- * @param context Context
- * @return RxMDConfiguration
- */
- public static Builder getMarkDownConfiguration(Context context) {
- return new Builder(context)
- .setHeader2RelativeSize(1.35f)
- .setHeader3RelativeSize(1.25f)
- .setHeader4RelativeSize(1.15f)
- .setHeader5RelativeSize(1.1f)
- .setHeader6RelativeSize(1.05f)
- .setHorizontalRulesHeight(2);
- }
-
- public static Builder getMarkDownConfiguration(Context context, Boolean darkTheme) {
- return new Builder(context)
- .setHeader2RelativeSize(1.35f)
- .setHeader3RelativeSize(1.25f)
- .setHeader4RelativeSize(1.15f)
- .setHeader5RelativeSize(1.1f)
- .setHeader6RelativeSize(1.05f)
- .setHorizontalRulesHeight(2);
- }
-}
diff --git a/markdown/src/main/java/it/niedermann/android/markdown/rxmarkdown/RxMarkdownViewer.java b/markdown/src/main/java/it/niedermann/android/markdown/rxmarkdown/RxMarkdownViewer.java
deleted file mode 100644
index 3c670d33..00000000
--- a/markdown/src/main/java/it/niedermann/android/markdown/rxmarkdown/RxMarkdownViewer.java
+++ /dev/null
@@ -1,68 +0,0 @@
-package it.niedermann.android.markdown.rxmarkdown;
-
-import android.content.Context;
-import android.util.AttributeSet;
-
-import androidx.annotation.NonNull;
-import androidx.lifecycle.LiveData;
-import androidx.lifecycle.MutableLiveData;
-
-import com.nextcloud.android.sso.exceptions.NextcloudFilesAppAccountNotFoundException;
-import com.nextcloud.android.sso.exceptions.NoCurrentAccountSelectedException;
-import com.nextcloud.android.sso.helper.SingleAccountHelper;
-import com.yydcdut.markdown.MarkdownProcessor;
-import com.yydcdut.markdown.MarkdownTextView;
-import com.yydcdut.markdown.syntax.text.TextFactory;
-
-import java.util.Map;
-
-import it.niedermann.android.markdown.MarkdownEditor;
-
-import static it.niedermann.android.markdown.MentionUtil.setupMentions;
-
-@Deprecated
-public class RxMarkdownViewer extends MarkdownTextView implements MarkdownEditor {
-
- private MarkdownProcessor markdownProcessor;
-
- public RxMarkdownViewer(Context context) {
- super(context);
- init(context);
- }
-
- public RxMarkdownViewer(Context context, AttributeSet attrs) {
- super(context, attrs);
- init(context);
- }
-
- public RxMarkdownViewer(Context context, AttributeSet attrs, int defStyleAttr) {
- super(context, attrs, defStyleAttr);
- init(context);
- }
-
- private void init(Context context) {
- markdownProcessor = new MarkdownProcessor(context);
- markdownProcessor.config(RxMarkdownUtil.getMarkDownConfiguration(context).build());
- markdownProcessor.factory(TextFactory.create());
- }
-
- @Override
- public void setMarkdownString(CharSequence text) {
- setText(markdownProcessor.parse(text));
- }
-
- @Override
- public LiveData<CharSequence> getMarkdownString() {
- return new MutableLiveData<>();
- }
-
- @Override
- public void setMarkdownString(CharSequence text, @NonNull Map<String, String> mentions) {
- try {
- setMarkdownString(text);
- setupMentions(SingleAccountHelper.getCurrentSingleSignOnAccount(getContext()), mentions, this);
- } catch (NextcloudFilesAppAccountNotFoundException | NoCurrentAccountSelectedException e) {
- e.printStackTrace();
- }
- }
-}