diff --git a/.github/workflows/develop.yml b/.github/workflows/develop.yml
index 968f2a92..dfb474a6 100644
--- a/.github/workflows/develop.yml
+++ b/.github/workflows/develop.yml
@@ -15,7 +15,7 @@ jobs:
with:
java-version: 1.8
- name: Build with Gradle
- run: ./gradlew build
+ run: ./gradlew build -Prelease
deploy:
needs: build
diff --git a/docs/.vuepress/.artifacts.js b/docs/.vuepress/.artifacts.js
index 62c52ab8..50625f79 100644
--- a/docs/.vuepress/.artifacts.js
+++ b/docs/.vuepress/.artifacts.js
@@ -1,4 +1,4 @@
// this is a generated file, do not modify. To update it run 'collectArtifacts.js' script
-const artifacts = [{"id":"core","name":"Core","group":"io.noties.markwon","description":"Core Markwon artifact that includes basic markdown parsing and rendering"},{"id":"ext-latex","name":"LaTeX","group":"io.noties.markwon","description":"Extension to add LaTeX formulas to Markwon markdown"},{"id":"ext-strikethrough","name":"Strikethrough","group":"io.noties.markwon","description":"Extension to add strikethrough markup to Markwon markdown"},{"id":"ext-tables","name":"Tables","group":"io.noties.markwon","description":"Extension to add tables markup (GFM) to Markwon markdown"},{"id":"ext-tasklist","name":"Task List","group":"io.noties.markwon","description":"Extension to add task lists (GFM) to Markwon markdown"},{"id":"html","name":"HTML","group":"io.noties.markwon","description":"Provides HTML parsing functionality"},{"id":"image","name":"Image","group":"io.noties.markwon","description":"Markwon image loading module (with optional GIF and SVG support)"},{"id":"image-glide","name":"Image Glide","group":"io.noties.markwon","description":"Markwon image loading module (based on Glide library)"},{"id":"image-picasso","name":"Image Picasso","group":"io.noties.markwon","description":"Markwon image loading module (based on Picasso library)"},{"id":"linkify","name":"Linkify","group":"io.noties.markwon","description":"Markwon plugin to linkify text (based on Android Linkify)"},{"id":"recycler","name":"Recycler","group":"io.noties.markwon","description":"Provides RecyclerView.Adapter to display Markwon markdown"},{"id":"recycler-table","name":"Recycler Table","group":"io.noties.markwon","description":"Provides MarkwonAdapter.Entry to render TableBlocks inside Android-native TableLayout widget"},{"id":"simple-ext","name":"Simple Extension","group":"io.noties.markwon","description":"Custom extension based on simple delimiter usage"},{"id":"syntax-highlight","name":"Syntax Highlight","group":"io.noties.markwon","description":"Add syntax highlight to Markwon markdown via Prism4j library"}];
+const artifacts = [{"id":"core","name":"Core","group":"io.noties.markwon","description":"Core Markwon artifact that includes basic markdown parsing and rendering"},{"id":"editor","name":"Editor","group":"io.noties.markwon","description":"Markdown editor based on Markwon"},{"id":"ext-latex","name":"LaTeX","group":"io.noties.markwon","description":"Extension to add LaTeX formulas to Markwon markdown"},{"id":"ext-strikethrough","name":"Strikethrough","group":"io.noties.markwon","description":"Extension to add strikethrough markup to Markwon markdown"},{"id":"ext-tables","name":"Tables","group":"io.noties.markwon","description":"Extension to add tables markup (GFM) to Markwon markdown"},{"id":"ext-tasklist","name":"Task List","group":"io.noties.markwon","description":"Extension to add task lists (GFM) to Markwon markdown"},{"id":"html","name":"HTML","group":"io.noties.markwon","description":"Provides HTML parsing functionality"},{"id":"image","name":"Image","group":"io.noties.markwon","description":"Markwon image loading module (with optional GIF and SVG support)"},{"id":"image-glide","name":"Image Glide","group":"io.noties.markwon","description":"Markwon image loading module (based on Glide library)"},{"id":"image-picasso","name":"Image Picasso","group":"io.noties.markwon","description":"Markwon image loading module (based on Picasso library)"},{"id":"linkify","name":"Linkify","group":"io.noties.markwon","description":"Markwon plugin to linkify text (based on Android Linkify)"},{"id":"recycler","name":"Recycler","group":"io.noties.markwon","description":"Provides RecyclerView.Adapter to display Markwon markdown"},{"id":"recycler-table","name":"Recycler Table","group":"io.noties.markwon","description":"Provides MarkwonAdapter.Entry to render TableBlocks inside Android-native TableLayout widget"},{"id":"simple-ext","name":"Simple Extension","group":"io.noties.markwon","description":"Custom extension based on simple delimiter usage"},{"id":"syntax-highlight","name":"Syntax Highlight","group":"io.noties.markwon","description":"Add syntax highlight to Markwon markdown via Prism4j library"}];
export { artifacts };
diff --git a/docs/.vuepress/config.js b/docs/.vuepress/config.js
index cd58b64c..f8db7ba5 100644
--- a/docs/.vuepress/config.js
+++ b/docs/.vuepress/config.js
@@ -95,6 +95,7 @@ module.exports = {
'/docs/v4/core/text-setter.md'
]
},
+ '/docs/v4/editor/',
'/docs/v4/ext-latex/',
'/docs/v4/ext-strikethrough/',
'/docs/v4/ext-tables/',
diff --git a/docs/.vuepress/public/assets/markwon-editor-preview.jpg b/docs/.vuepress/public/assets/markwon-editor-preview.jpg
new file mode 100644
index 00000000..e5b29e05
Binary files /dev/null and b/docs/.vuepress/public/assets/markwon-editor-preview.jpg differ
diff --git a/docs/.vuepress/public/assets/markwon-editor.mp4 b/docs/.vuepress/public/assets/markwon-editor.mp4
new file mode 100644
index 00000000..8ce65a68
Binary files /dev/null and b/docs/.vuepress/public/assets/markwon-editor.mp4 differ
diff --git a/docs/README.md b/docs/README.md
index abab2311..300075e8 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -21,6 +21,11 @@ but also gives all the means to tweak the appearance if desired. All markdown fe
listed in are supported (including support for **inlined/block HTML code**,
**markdown tables**, **images** and **syntax highlight**).
+Since version **Markwon** comes with an [editor] to _highlight_ markdown input
+as user types for example in **EditText**.
+
+[editor]: /docs/v4/editor/
+
## Supported markdown features
* Emphasis (`*`, `_`)
diff --git a/docs/docs/v4/editor/README.md b/docs/docs/v4/editor/README.md
new file mode 100644
index 00000000..9af9bf6c
--- /dev/null
+++ b/docs/docs/v4/editor/README.md
@@ -0,0 +1,25 @@
+# Editor
+
+
+
+Markdown editing highlight for Android based on **Markwon**.
+
+
+
+
+
+## Getting started with editor
+
+:::warning Implementation Detail
+It must be mentioned that highlight is implemented via text diff. Everything
+that is present in raw markdown input and missing from rendered result is considered
+to be _punctuation_.
+:::
\ No newline at end of file
diff --git a/markwon-editor/README.md b/markwon-editor/README.md
index 896a8723..f191ee4f 100644
--- a/markwon-editor/README.md
+++ b/markwon-editor/README.md
@@ -3,4 +3,11 @@
Markdown editor for Android based on `Markwon`.
Main principle: _difference_ between input text and rendered markdown is considered to be
-_punctuation_.
\ No newline at end of file
+_punctuation_.
+
+
+## Limitations
+
+Tables and LaTeX nodes won't be rendered correctly. They will be treated as _punctuation_
+as whole. This comes from their implementation - they are _mocked_ and do not present
+in final result as text and thus cannot be _diffed_.
\ No newline at end of file
diff --git a/markwon-editor/src/main/java/io/noties/markwon/editor/EditSpanHandlerBuilder.java b/markwon-editor/src/main/java/io/noties/markwon/editor/EditSpanHandlerBuilder.java
index 09c1706e..96c47424 100644
--- a/markwon-editor/src/main/java/io/noties/markwon/editor/EditSpanHandlerBuilder.java
+++ b/markwon-editor/src/main/java/io/noties/markwon/editor/EditSpanHandlerBuilder.java
@@ -31,7 +31,7 @@ public class EditSpanHandlerBuilder {
private final Map, EditSpanHandlerTyped> map = new HashMap<>(3);
@NonNull
- public EditSpanHandlerBuilder include(
+ public EditSpanHandlerBuilder handleMarkdownSpan(
@NonNull Class type,
@NonNull EditSpanHandlerTyped handler) {
map.put(type, handler);
diff --git a/markwon-editor/src/main/java/io/noties/markwon/editor/MarkwonEditor.java b/markwon-editor/src/main/java/io/noties/markwon/editor/MarkwonEditor.java
index 2427b3e0..e6e0b185 100644
--- a/markwon-editor/src/main/java/io/noties/markwon/editor/MarkwonEditor.java
+++ b/markwon-editor/src/main/java/io/noties/markwon/editor/MarkwonEditor.java
@@ -10,11 +10,6 @@ import java.util.Map;
import io.noties.markwon.Markwon;
-// todo: how to reuse existing spanFactories? to obtain a value they require render-props....
-// maybe.. mock them? plus, spanFactory can return multiple spans
-
-// todo: as we do text-diff, then images, latex and tables won't be handled... they will be treated as punctuation as-whole..
-
/**
* @see #builder(Markwon)
* @see #create(Markwon)
@@ -24,6 +19,9 @@ import io.noties.markwon.Markwon;
*/
public abstract class MarkwonEditor {
+ /**
+ * Represents cache of spans that are used during highlight
+ */
public interface EditSpanStore {
/**
diff --git a/markwon-editor/src/test/java/io/noties/markwon/editor/MarkwonEditorImplTest.java b/markwon-editor/src/test/java/io/noties/markwon/editor/MarkwonEditorImplTest.java
new file mode 100644
index 00000000..9bbfc829
--- /dev/null
+++ b/markwon-editor/src/test/java/io/noties/markwon/editor/MarkwonEditorImplTest.java
@@ -0,0 +1,166 @@
+package io.noties.markwon.editor;
+
+import android.text.SpannableStringBuilder;
+import android.text.Spanned;
+
+import androidx.annotation.NonNull;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import io.noties.markwon.Markwon;
+import io.noties.markwon.editor.MarkwonEditorImpl.EditSpanStoreImpl;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+@RunWith(RobolectricTestRunner.class)
+@Config(manifest = Config.NONE)
+public class MarkwonEditorImplTest {
+
+ @Test
+ public void extract_spans() {
+
+ final class One {
+ }
+ final class Two {
+ }
+ final class Three {
+ }
+
+ final SpannableStringBuilder builder = new SpannableStringBuilder();
+ append(builder, "one", new One());
+ append(builder, "two", new Two(), new Two());
+ append(builder, "three", new Three(), new Three(), new Three());
+
+ final Map, List