Merge 56944dfd3450bf7d9d51a4c2a675ede0a6cae8ff into 6f8b8e71f57ffd9b25cc02f99a301b4f06550f77
This commit is contained in:
commit
cbe4aabf14
@ -5,7 +5,7 @@ import java.util.concurrent.Executors;
|
|||||||
import io.noties.markwon.Markwon;
|
import io.noties.markwon.Markwon;
|
||||||
import io.noties.markwon.app.sample.Tags;
|
import io.noties.markwon.app.sample.Tags;
|
||||||
import io.noties.markwon.app.samples.editor.shared.MarkwonEditTextSample;
|
import io.noties.markwon.app.samples.editor.shared.MarkwonEditTextSample;
|
||||||
import io.noties.markwon.app.samples.editor.shared.HeadingEditHandler;
|
import io.noties.markwon.editor.handler.HeadingEditHandler;
|
||||||
import io.noties.markwon.editor.MarkwonEditor;
|
import io.noties.markwon.editor.MarkwonEditor;
|
||||||
import io.noties.markwon.editor.MarkwonEditorTextWatcher;
|
import io.noties.markwon.editor.MarkwonEditorTextWatcher;
|
||||||
import io.noties.markwon.sample.annotations.MarkwonArtifact;
|
import io.noties.markwon.sample.annotations.MarkwonArtifact;
|
||||||
|
@ -22,6 +22,7 @@ import io.noties.markwon.editor.MarkwonEditor;
|
|||||||
import io.noties.markwon.editor.MarkwonEditorTextWatcher;
|
import io.noties.markwon.editor.MarkwonEditorTextWatcher;
|
||||||
import io.noties.markwon.editor.handler.EmphasisEditHandler;
|
import io.noties.markwon.editor.handler.EmphasisEditHandler;
|
||||||
import io.noties.markwon.editor.handler.StrongEmphasisEditHandler;
|
import io.noties.markwon.editor.handler.StrongEmphasisEditHandler;
|
||||||
|
import io.noties.markwon.editor.handler.CodeBlockEditHandler;
|
||||||
import io.noties.markwon.ext.strikethrough.StrikethroughPlugin;
|
import io.noties.markwon.ext.strikethrough.StrikethroughPlugin;
|
||||||
import io.noties.markwon.inlineparser.BangInlineProcessor;
|
import io.noties.markwon.inlineparser.BangInlineProcessor;
|
||||||
import io.noties.markwon.inlineparser.EntityInlineProcessor;
|
import io.noties.markwon.inlineparser.EntityInlineProcessor;
|
||||||
@ -76,6 +77,7 @@ public class EditorMultipleEditSpansSample extends MarkwonEditTextSample {
|
|||||||
.useEditHandler(new EmphasisEditHandler())
|
.useEditHandler(new EmphasisEditHandler())
|
||||||
.useEditHandler(new StrongEmphasisEditHandler())
|
.useEditHandler(new StrongEmphasisEditHandler())
|
||||||
.useEditHandler(new StrikethroughEditHandler())
|
.useEditHandler(new StrikethroughEditHandler())
|
||||||
|
.useEditHandler(new CodeBlockEditHandler())
|
||||||
.useEditHandler(new CodeEditHandler())
|
.useEditHandler(new CodeEditHandler())
|
||||||
.useEditHandler(new BlockQuoteEditHandler())
|
.useEditHandler(new BlockQuoteEditHandler())
|
||||||
.useEditHandler(new LinkEditHandler(onClick))
|
.useEditHandler(new LinkEditHandler(onClick))
|
||||||
|
@ -15,7 +15,6 @@ import io.noties.markwon.SoftBreakAddsNewLinePlugin;
|
|||||||
import io.noties.markwon.app.sample.Tags;
|
import io.noties.markwon.app.sample.Tags;
|
||||||
import io.noties.markwon.app.samples.editor.shared.BlockQuoteEditHandler;
|
import io.noties.markwon.app.samples.editor.shared.BlockQuoteEditHandler;
|
||||||
import io.noties.markwon.app.samples.editor.shared.CodeEditHandler;
|
import io.noties.markwon.app.samples.editor.shared.CodeEditHandler;
|
||||||
import io.noties.markwon.app.samples.editor.shared.HeadingEditHandler;
|
|
||||||
import io.noties.markwon.app.samples.editor.shared.LinkEditHandler;
|
import io.noties.markwon.app.samples.editor.shared.LinkEditHandler;
|
||||||
import io.noties.markwon.app.samples.editor.shared.MarkwonEditTextSample;
|
import io.noties.markwon.app.samples.editor.shared.MarkwonEditTextSample;
|
||||||
import io.noties.markwon.app.samples.editor.shared.StrikethroughEditHandler;
|
import io.noties.markwon.app.samples.editor.shared.StrikethroughEditHandler;
|
||||||
@ -23,6 +22,7 @@ import io.noties.markwon.editor.MarkwonEditor;
|
|||||||
import io.noties.markwon.editor.MarkwonEditorTextWatcher;
|
import io.noties.markwon.editor.MarkwonEditorTextWatcher;
|
||||||
import io.noties.markwon.editor.PersistedSpans;
|
import io.noties.markwon.editor.PersistedSpans;
|
||||||
import io.noties.markwon.editor.handler.EmphasisEditHandler;
|
import io.noties.markwon.editor.handler.EmphasisEditHandler;
|
||||||
|
import io.noties.markwon.editor.handler.HeadingEditHandler;
|
||||||
import io.noties.markwon.editor.handler.StrongEmphasisEditHandler;
|
import io.noties.markwon.editor.handler.StrongEmphasisEditHandler;
|
||||||
import io.noties.markwon.sample.annotations.MarkwonArtifact;
|
import io.noties.markwon.sample.annotations.MarkwonArtifact;
|
||||||
import io.noties.markwon.sample.annotations.MarkwonSampleInfo;
|
import io.noties.markwon.sample.annotations.MarkwonSampleInfo;
|
||||||
|
@ -1,82 +0,0 @@
|
|||||||
package io.noties.markwon.app.samples.editor.shared;
|
|
||||||
|
|
||||||
import android.text.Editable;
|
|
||||||
import android.text.Spanned;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
|
|
||||||
import io.noties.markwon.Markwon;
|
|
||||||
import io.noties.markwon.core.MarkwonTheme;
|
|
||||||
import io.noties.markwon.core.spans.HeadingSpan;
|
|
||||||
import io.noties.markwon.editor.EditHandler;
|
|
||||||
import io.noties.markwon.editor.PersistedSpans;
|
|
||||||
|
|
||||||
public class HeadingEditHandler implements EditHandler<HeadingSpan> {
|
|
||||||
|
|
||||||
private MarkwonTheme theme;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void init(@NonNull Markwon markwon) {
|
|
||||||
this.theme = markwon.configuration().theme();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void configurePersistedSpans(@NonNull PersistedSpans.Builder builder) {
|
|
||||||
builder
|
|
||||||
.persistSpan(Head1.class, () -> new Head1(theme))
|
|
||||||
.persistSpan(Head2.class, () -> new Head2(theme));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handleMarkdownSpan(
|
|
||||||
@NonNull PersistedSpans persistedSpans,
|
|
||||||
@NonNull Editable editable,
|
|
||||||
@NonNull String input,
|
|
||||||
@NonNull HeadingSpan span,
|
|
||||||
int spanStart,
|
|
||||||
int spanTextLength
|
|
||||||
) {
|
|
||||||
final Class<?> type;
|
|
||||||
switch (span.getLevel()) {
|
|
||||||
case 1:
|
|
||||||
type = Head1.class;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
type = Head2.class;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
type = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type != null) {
|
|
||||||
final int index = input.indexOf('\n', spanStart + spanTextLength);
|
|
||||||
final int end = index < 0
|
|
||||||
? input.length()
|
|
||||||
: index;
|
|
||||||
editable.setSpan(
|
|
||||||
persistedSpans.get(type),
|
|
||||||
spanStart,
|
|
||||||
end,
|
|
||||||
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@NonNull
|
|
||||||
@Override
|
|
||||||
public Class<HeadingSpan> markdownSpanType() {
|
|
||||||
return HeadingSpan.class;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class Head1 extends HeadingSpan {
|
|
||||||
Head1(@NonNull MarkwonTheme theme) {
|
|
||||||
super(theme, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class Head2 extends HeadingSpan {
|
|
||||||
Head2(@NonNull MarkwonTheme theme) {
|
|
||||||
super(theme, 2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -11,6 +11,11 @@ android {
|
|||||||
versionCode 1
|
versionCode 1
|
||||||
versionName version
|
versionName version
|
||||||
}
|
}
|
||||||
|
|
||||||
|
compileOptions {
|
||||||
|
targetCompatibility JavaVersion.VERSION_1_8
|
||||||
|
sourceCompatibility JavaVersion.VERSION_1_8
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
@ -0,0 +1,47 @@
|
|||||||
|
package io.noties.markwon.editor.handler;
|
||||||
|
|
||||||
|
import android.text.Editable;
|
||||||
|
import android.text.Spanned;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
|
import io.noties.markwon.Markwon;
|
||||||
|
import io.noties.markwon.core.MarkwonTheme;
|
||||||
|
import io.noties.markwon.core.spans.CodeBlockSpan;
|
||||||
|
import io.noties.markwon.editor.EditHandler;
|
||||||
|
import io.noties.markwon.editor.MarkwonEditorUtils;
|
||||||
|
import io.noties.markwon.editor.PersistedSpans;
|
||||||
|
|
||||||
|
public class CodeBlockEditHandler implements EditHandler<CodeBlockSpan> {
|
||||||
|
private MarkwonTheme theme;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(@NonNull Markwon markwon) {
|
||||||
|
theme = markwon.configuration().theme();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void configurePersistedSpans(@NonNull PersistedSpans.Builder builder) {
|
||||||
|
builder.persistSpan(CodeBlockSpan.class, () -> new CodeBlockSpan(theme));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleMarkdownSpan(@NonNull PersistedSpans persistedSpans, @NonNull Editable editable, @NonNull String input, @NonNull CodeBlockSpan span, int spanStart, int spanTextLength) {
|
||||||
|
MarkwonEditorUtils.Match delimited = MarkwonEditorUtils.findDelimited(input, spanStart, "```");
|
||||||
|
if (delimited != null) {
|
||||||
|
editable.setSpan(
|
||||||
|
persistedSpans.get(markdownSpanType()),
|
||||||
|
delimited.start(),
|
||||||
|
delimited.end(),
|
||||||
|
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
|
||||||
|
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public Class<CodeBlockSpan> markdownSpanType() {
|
||||||
|
return CodeBlockSpan.class;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,142 @@
|
|||||||
|
package io.noties.markwon.editor.handler;
|
||||||
|
|
||||||
|
import android.text.Editable;
|
||||||
|
import android.text.Spanned;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
|
import io.noties.markwon.Markwon;
|
||||||
|
import io.noties.markwon.core.MarkwonTheme;
|
||||||
|
import io.noties.markwon.core.spans.HeadingSpan;
|
||||||
|
import io.noties.markwon.editor.EditHandler;
|
||||||
|
import io.noties.markwon.editor.PersistedSpans;
|
||||||
|
|
||||||
|
public class HeadingEditHandler implements EditHandler<HeadingSpan> {
|
||||||
|
|
||||||
|
private MarkwonTheme theme;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(@NonNull Markwon markwon) {
|
||||||
|
this.theme = markwon.configuration().theme();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void configurePersistedSpans(@NonNull PersistedSpans.Builder builder) {
|
||||||
|
builder.persistSpan(Heading1Span.class, () -> new Heading1Span(theme));
|
||||||
|
builder.persistSpan(Heading2Span.class, () -> new Heading2Span(theme));
|
||||||
|
builder.persistSpan(Heading3Span.class, () -> new Heading3Span(theme));
|
||||||
|
builder.persistSpan(Heading4Span.class, () -> new Heading4Span(theme));
|
||||||
|
builder.persistSpan(Heading5Span.class, () -> new Heading5Span(theme));
|
||||||
|
builder.persistSpan(Heading6Span.class, () -> new Heading6Span(theme));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleMarkdownSpan(
|
||||||
|
@NonNull PersistedSpans persistedSpans,
|
||||||
|
@NonNull Editable editable,
|
||||||
|
@NonNull String input,
|
||||||
|
@NonNull HeadingSpan span,
|
||||||
|
int spanStart,
|
||||||
|
int spanTextLength) {
|
||||||
|
final HeadingSpan newSpan;
|
||||||
|
|
||||||
|
switch (span.getLevel()) {
|
||||||
|
case 1:
|
||||||
|
newSpan = persistedSpans.get(Heading1Span.class);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
newSpan = persistedSpans.get(Heading2Span.class);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
newSpan = persistedSpans.get(Heading3Span.class);
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
newSpan = persistedSpans.get(Heading4Span.class);
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
newSpan = persistedSpans.get(Heading5Span.class);
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
newSpan = persistedSpans.get(Heading6Span.class);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
|
||||||
|
}
|
||||||
|
final int newStart = getNewSpanStart(input, spanStart);
|
||||||
|
final int newEnd = findEnd(input, newStart, newSpan.getLevel());
|
||||||
|
|
||||||
|
editable.setSpan(
|
||||||
|
newSpan,
|
||||||
|
newStart,
|
||||||
|
newEnd,
|
||||||
|
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int findEnd(String input, int searchFrom, int spanLevel) {
|
||||||
|
int end = searchFrom + spanLevel;
|
||||||
|
final int strLength = input.length();
|
||||||
|
while (end < strLength - 1) {
|
||||||
|
end++;
|
||||||
|
if (input.charAt(end) == '\n') {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return end + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getNewSpanStart(String input, int spanStart) {
|
||||||
|
int start = spanStart;
|
||||||
|
|
||||||
|
while (start >= 0 && input.charAt(start) != '\n') {
|
||||||
|
start--;
|
||||||
|
}
|
||||||
|
start += 1;
|
||||||
|
|
||||||
|
return start;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public Class<HeadingSpan> markdownSpanType() {
|
||||||
|
return HeadingSpan.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class Heading1Span extends HeadingSpan {
|
||||||
|
public Heading1Span(@NonNull MarkwonTheme theme) {
|
||||||
|
super(theme, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class Heading2Span extends HeadingSpan {
|
||||||
|
public Heading2Span(@NonNull MarkwonTheme theme) {
|
||||||
|
super(theme, 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class Heading3Span extends HeadingSpan {
|
||||||
|
public Heading3Span(@NonNull MarkwonTheme theme) {
|
||||||
|
super(theme, 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class Heading4Span extends HeadingSpan {
|
||||||
|
public Heading4Span(@NonNull MarkwonTheme theme) {
|
||||||
|
super(theme, 4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class Heading5Span extends HeadingSpan {
|
||||||
|
public Heading5Span(@NonNull MarkwonTheme theme) {
|
||||||
|
super(theme, 5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class Heading6Span extends HeadingSpan {
|
||||||
|
public Heading6Span(@NonNull MarkwonTheme theme) {
|
||||||
|
super(theme, 6);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user