Add editor documentation page

This commit is contained in:
Dimitry Ivanov 2019-11-07 17:30:20 +03:00
parent bd53c014a1
commit 2488c1047b
3 changed files with 169 additions and 42 deletions

View File

@ -22,7 +22,7 @@ listed in <Link name="commonmark-spec" /> are supported (including support for *
**markdown tables**, **images** and **syntax highlight**).
Since version <Badge text="4.2.0" /> **Markwon** comes with an [editor] to _highlight_ markdown input
as user types for example in **EditText**.
as user types (for example in **EditText**).
[editor]: /docs/v4/editor/

View File

@ -18,8 +18,116 @@ video {
## Getting started with editor
```java
// obtain Markwon instance
final Markwon markwon = Markwon.create(this);
// create editor
final MarkwonEditor editor = MarkwonEditor.create(markwon);
// set edit listener
editText.addTextChangedListener(MarkwonEditorTextWatcher.withProcess(editor));
```
The code above _highlights_ in-place which is OK for relatively small markdown inputs.
If you wish to offload main thread and highlight in background use `withPreRender`
`MarkwonEditorTextWatcher`:
```java
editText.addTextChangedListener(MarkwonEditorTextWatcher.withPreRender(
editor,
Executors.newCachedThreadPool(),
editText));
```
`MarkwonEditorTextWatcher` automatically triggers markdown highlight when text in `EditText` changes.
But you still can invoke `MarkwonEditor` manually:
```java
editor.process(editText.getText());
// please note that MarkwonEditor operates on caller thread,
// if you wish to execute this operation in background - this method
// must be called from background thread
editor.preRender(editText.getText(), new MarkwonEditor.PreRenderResultListener() {
@Override
public void onPreRenderResult(@NonNull MarkwonEditor.PreRenderResult result) {
// it's wise to check if rendered result is for the same input,
// for example by matching raw input
if (editText.getText().toString().equals(result.resultEditable().toString())) {
// if you are in background thread do not forget
// to execute dispatch in main thread
result.dispatchTo(editText.getText());
}
}
});
```
:::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
that is present in raw markdown input but missing from rendered result is considered
to be _punctuation_.
:::
:::danger Tables and LaTeX
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_.
:::
## Custom punctuation span
By default `MarkwonEditor` uses lighter text color of widget to customize punctuation.
If you wish to use a different span you can use `withPunctuationSpan` configuration step:
```java
final MarkwonEditor editor = MarkwonEditor.builder(Markwon.create(this))
.withPunctuationSpan(CustomPunctuationSpan.class, CustomPunctuationSpan::new)
.build();
```
```java
public class CustomPunctuationSpan extends ForegroundColorSpan {
CustomPunctuationSpan() {
super(0xFFFF0000); // RED
}
}
```
## Additional handling
In order to additionally highlight portions of markdown input (for example make text wrapped with `**`
symbols **bold**) `EditSpanHandler` can be used:
```java
final MarkwonEditor editor = MarkwonEditor.builder(Markwon.create(this))
// This is required for edit-span cache
// We could use Markwon `StrongEmphasisSpan` here, but I use a different
// one to indicate that those are completely unrelated spans and must be
// treated differently.
.includeEditSpan(Bold.class, Bold::new)
.withEditSpanHandler(new MarkwonEditor.EditSpanHandler() {
@Override
public void handle(
@NonNull MarkwonEditor.EditSpanStore store,
@NonNull Editable editable,
@NonNull String input,
@NonNull Object span,
int spanStart,
int spanTextLength) {
if (span instanceof StrongEmphasisSpan) {
editable.setSpan(
// `includeEditSpan(Bold.class, Bold::new)` ensured that we have
// a span here to use (either reuse existing or create a new one)
store.get(Bold.class),
spanStart,
// we know that strong emphasis is delimited with 2 characters on both sides
spanStart + spanTextLength + 4,
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
);
}
}
})
.build();
```

View File

@ -64,13 +64,13 @@ public class EditorActivity extends Activity {
private void simple_process() {
// Process highlight in-place (right after text has changed)
// obtain Markwon instance
// obtain Markwon instance
final Markwon markwon = Markwon.create(this);
// create editor
// create editor
final MarkwonEditor editor = MarkwonEditor.create(markwon);
// set edit listener
// set edit listener
editText.addTextChangedListener(MarkwonEditorTextWatcher.withProcess(editor));
}
@ -80,6 +80,25 @@ public class EditorActivity extends Activity {
final Markwon markwon = Markwon.create(this);
final MarkwonEditor editor = MarkwonEditor.create(markwon);
editor.process(editText.getText());
// please note that MarkwonEditor operates on caller thread,
// fi you wish to execute this operation in background - this method
// must be called from background thread
editor.preRender(editText.getText(), new MarkwonEditor.PreRenderResultListener() {
@Override
public void onPreRenderResult(@NonNull MarkwonEditor.PreRenderResult result) {
// it's wise to check if rendered result is for the same input,
// for example by matching raw input
if (editText.getText().toString().equals(result.resultEditable().toString())) {
// if you are in background thread do not forget
// to execute dispatch in main thread
result.dispatchTo(editText.getText());
}
}
});
editText.addTextChangedListener(MarkwonEditorTextWatcher.withPreRender(
editor,
Executors.newCachedThreadPool(),
@ -89,9 +108,9 @@ public class EditorActivity extends Activity {
private void custom_punctuation_span() {
// Use own punctuation span
final MarkwonEditor editor = MarkwonEditor.builder(Markwon.create(this))
.withPunctuationSpan(CustomPunctuationSpan.class, CustomPunctuationSpan::new)
.build();
final MarkwonEditor editor = MarkwonEditor.builder(Markwon.create(this))
.withPunctuationSpan(CustomPunctuationSpan.class, CustomPunctuationSpan::new)
.build();
editText.addTextChangedListener(MarkwonEditorTextWatcher.withProcess(editor));
}
@ -99,35 +118,35 @@ public class EditorActivity extends Activity {
private void additional_edit_span() {
// An additional span is used to highlight strong-emphasis
final MarkwonEditor editor = MarkwonEditor.builder(Markwon.create(this))
// This is required for edit-span cache
// We could use Markwon `StrongEmphasisSpan` here, but I use a different
// one to indicate that those are completely unrelated spans and must be
// treated differently.
.includeEditSpan(Bold.class, Bold::new)
.withEditSpanHandler(new MarkwonEditor.EditSpanHandler() {
@Override
public void handle(
@NonNull MarkwonEditor.EditSpanStore store,
@NonNull Editable editable,
@NonNull String input,
@NonNull Object span,
int spanStart,
int spanTextLength) {
if (span instanceof StrongEmphasisSpan) {
editable.setSpan(
// `includeEditSpan(Bold.class, Bold::new)` ensured that we have
// a span here to use (either reuse existing or create a new one)
store.get(Bold.class),
spanStart,
// we know that strong emphasis is delimited with 2 characters on both sides
spanStart + spanTextLength + 4,
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
);
}
}
})
.build();
final MarkwonEditor editor = MarkwonEditor.builder(Markwon.create(this))
// This is required for edit-span cache
// We could use Markwon `StrongEmphasisSpan` here, but I use a different
// one to indicate that those are completely unrelated spans and must be
// treated differently.
.includeEditSpan(Bold.class, Bold::new)
.withEditSpanHandler(new MarkwonEditor.EditSpanHandler() {
@Override
public void handle(
@NonNull MarkwonEditor.EditSpanStore store,
@NonNull Editable editable,
@NonNull String input,
@NonNull Object span,
int spanStart,
int spanTextLength) {
if (span instanceof StrongEmphasisSpan) {
editable.setSpan(
// `includeEditSpan(Bold.class, Bold::new)` ensured that we have
// a span here to use (either reuse existing or create a new one)
store.get(Bold.class),
spanStart,
// we know that strong emphasis is delimited with 2 characters on both sides
spanStart + spanTextLength + 4,
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
);
}
}
})
.build();
editText.addTextChangedListener(MarkwonEditorTextWatcher.withProcess(editor));
}
@ -316,11 +335,11 @@ public class EditorActivity extends Activity {
}
}
private static class CustomPunctuationSpan extends ForegroundColorSpan {
CustomPunctuationSpan() {
super(0xFFFF0000); // RED
}
private static class CustomPunctuationSpan extends ForegroundColorSpan {
CustomPunctuationSpan() {
super(0xFFFF0000); // RED
}
}
private static class Bold extends MetricAffectingSpan {
public Bold() {