MarkwonSpansFactory append-prepend methods
This commit is contained in:
parent
f7f8f6d1ee
commit
976dfa3162
@ -3,9 +3,11 @@
|
||||
# 4.2.2-SNAPSHOT
|
||||
* Fixed `AsyncDrawable` display when it has placeholder with empty bounds ([#189])
|
||||
* Fixed `syntax-highlight` where code input is empty string ([#192])
|
||||
* Add `appendFactory`/`prependFactory` in `MarkwonSpansFactory.Builder` for more explicit `SpanFactory` ordering ([#193])
|
||||
|
||||
[#189]: https://github.com/noties/Markwon/issues/189
|
||||
[#192]: https://github.com/noties/Markwon/issues/192
|
||||
[#193]: https://github.com/noties/Markwon/issues/193
|
||||
|
||||
# 4.2.1
|
||||
* Fix SpannableBuilder `subSequence` method
|
||||
|
@ -62,7 +62,12 @@ builder.setFactory(Link.class, new SpanFactory() {
|
||||
|
||||
---
|
||||
|
||||
Since <Badge text="3.0.1" /> you can _add_ multiple `SpanFactory` for a single node:
|
||||
:::warning
|
||||
Deprecated in <Badge text="4.2.2" type="error" vertical="middle" />. Use `appendFactory` or `prependFactory` for
|
||||
more explicit factories ordering. `addFactories` behaves like new `prependFactory` method.
|
||||
:::
|
||||
|
||||
Since <Badge text="3.0.1" /><Badge text="4.2.2" type="error" /> you can _add_ multiple `SpanFactory` for a single node:
|
||||
|
||||
```java
|
||||
final Markwon markwon = Markwon.builder(context)
|
||||
@ -81,6 +86,22 @@ final Markwon markwon = Markwon.builder(context)
|
||||
.build();
|
||||
```
|
||||
|
||||
## appendFactory/prependFactory <Badge text="4.2.2" />
|
||||
|
||||
* use `appendFactory` if you wish to add a factory **after** original (can be used to post-process original factory)
|
||||
* use `prependFactory` if you wish to add a factory **before** original (original factory will be applied after this one)
|
||||
|
||||
```java
|
||||
@Override
|
||||
public void configureSpansFactory(@NonNull MarkwonSpansFactory.Builder builder) {
|
||||
// `RemoveUnderlineSpan` will be added AFTER original, thus it will remove underline applied by original
|
||||
builder.appendFactory(Link.class, (configuration, props) -> new RemoveUnderlineSpan());
|
||||
|
||||
// will be added BEFORE origin (origin can override this)
|
||||
builder.prependFactory(Link.class, (configuration, props) -> new AbsoluteSizeSpan(48, true));
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
If you wish to inspect existing factory you can use:
|
||||
|
@ -39,10 +39,34 @@ public interface MarkwonSpansFactory {
|
||||
* {@link SpanFactory} with the specified one.
|
||||
*
|
||||
* @since 3.0.1
|
||||
* @deprecated 4.2.2-SNAPSHOT consider using {@link #appendFactory(Class, SpanFactory)} or
|
||||
* {@link #prependFactory(Class, SpanFactory)} methods for more explicit factory ordering.
|
||||
* `addFactory` behaved like {@link #prependFactory(Class, SpanFactory)}, so
|
||||
* this method call can be replaced with it
|
||||
*/
|
||||
@NonNull
|
||||
@Deprecated
|
||||
<N extends Node> Builder addFactory(@NonNull Class<N> node, @NonNull SpanFactory factory);
|
||||
|
||||
/**
|
||||
* Append a factory to existing one (or make the first one for specified node). Specified factory
|
||||
* will be called <strong>after</strong> original (if present) factory. Can be used to
|
||||
* <em>change</em> behavior or original span factory.
|
||||
*
|
||||
* @since 4.2.2-SNAPSHOT
|
||||
*/
|
||||
@NonNull
|
||||
<N extends Node> Builder appendFactory(@NonNull Class<N> node, @NonNull SpanFactory factory);
|
||||
|
||||
/**
|
||||
* Prepend a factory to existing one (or make the first one for specified node). Specified factory
|
||||
* will be called <string>before</string> original (if present) factory.
|
||||
*
|
||||
* @since 4.2.2-SNAPSHOT
|
||||
*/
|
||||
@NonNull
|
||||
<N extends Node> Builder prependFactory(@NonNull Class<N> node, @NonNull SpanFactory factory);
|
||||
|
||||
/**
|
||||
* Can be useful when <em>enhancing</em> an already defined SpanFactory with another one.
|
||||
*/
|
||||
|
@ -56,7 +56,32 @@ class MarkwonSpansFactoryImpl implements MarkwonSpansFactory {
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
@Deprecated
|
||||
public <N extends Node> Builder addFactory(@NonNull Class<N> node, @NonNull SpanFactory factory) {
|
||||
return prependFactory(node, factory);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public <N extends Node> Builder appendFactory(@NonNull Class<N> node, @NonNull SpanFactory factory) {
|
||||
final SpanFactory existing = factories.get(node);
|
||||
if (existing == null) {
|
||||
factories.put(node, factory);
|
||||
} else {
|
||||
if (existing instanceof CompositeSpanFactory) {
|
||||
((CompositeSpanFactory) existing).factories.add(0, factory);
|
||||
} else {
|
||||
final CompositeSpanFactory compositeSpanFactory =
|
||||
new CompositeSpanFactory(factory, existing);
|
||||
factories.put(node, compositeSpanFactory);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public <N extends Node> Builder prependFactory(@NonNull Class<N> node, @NonNull SpanFactory factory) {
|
||||
// if there is no factory registered for this node -> just add it
|
||||
final SpanFactory existing = factories.get(node);
|
||||
if (existing == null) {
|
||||
|
@ -113,6 +113,7 @@ public class MarkwonSpansFactoryImplTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@Deprecated
|
||||
public void builder_add_factory() {
|
||||
// here is what we should validate:
|
||||
// * if we call addFactory and there is none already -> supplied factory
|
||||
@ -146,4 +147,74 @@ public class MarkwonSpansFactoryImplTest {
|
||||
assertEquals(compositeSpanFactory, builder.getFactory(node));
|
||||
assertEquals(Arrays.asList(first, second, third), compositeSpanFactory.factories);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void builder_prepend_factory() {
|
||||
// here is what we should validate:
|
||||
// * if we call prependFactory and there is none already -> supplied factory
|
||||
// * if there is
|
||||
// * * if not composite -> make composite
|
||||
// * * if composite -> add to it
|
||||
|
||||
final MarkwonSpansFactoryImpl.BuilderImpl builder = new MarkwonSpansFactoryImpl.BuilderImpl();
|
||||
|
||||
final SpanFactory first = mock(SpanFactory.class);
|
||||
final SpanFactory second = mock(SpanFactory.class);
|
||||
final SpanFactory third = mock(SpanFactory.class);
|
||||
|
||||
final Class<Node> node = Node.class;
|
||||
|
||||
// assert none yet
|
||||
assertNull(builder.getFactory(node));
|
||||
|
||||
// add first, none yet -> it should be added without modifications
|
||||
builder.prependFactory(node, first);
|
||||
assertEquals(first, builder.getFactory(node));
|
||||
|
||||
// add second -> composite factory will be created
|
||||
builder.prependFactory(node, second);
|
||||
final MarkwonSpansFactoryImpl.CompositeSpanFactory compositeSpanFactory =
|
||||
(MarkwonSpansFactoryImpl.CompositeSpanFactory) builder.getFactory(node);
|
||||
assertNotNull(compositeSpanFactory);
|
||||
assertEquals(Arrays.asList(first, second), compositeSpanFactory.factories);
|
||||
|
||||
builder.prependFactory(node, third);
|
||||
assertEquals(compositeSpanFactory, builder.getFactory(node));
|
||||
assertEquals(Arrays.asList(first, second, third), compositeSpanFactory.factories);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void builder_append_factory() {
|
||||
// here is what we should validate:
|
||||
// * if we call appendFactory and there is none already -> supplied factory
|
||||
// * if there is
|
||||
// * * if not composite -> make composite
|
||||
// * * if composite -> add to it
|
||||
|
||||
final MarkwonSpansFactoryImpl.BuilderImpl builder = new MarkwonSpansFactoryImpl.BuilderImpl();
|
||||
|
||||
final SpanFactory first = mock(SpanFactory.class);
|
||||
final SpanFactory second = mock(SpanFactory.class);
|
||||
final SpanFactory third = mock(SpanFactory.class);
|
||||
|
||||
final Class<Node> node = Node.class;
|
||||
|
||||
// assert none yet
|
||||
assertNull(builder.getFactory(node));
|
||||
|
||||
// add first, none yet -> it should be added without modifications
|
||||
builder.appendFactory(node, first);
|
||||
assertEquals(first, builder.getFactory(node));
|
||||
|
||||
// add second -> composite factory will be created
|
||||
builder.appendFactory(node, second);
|
||||
final MarkwonSpansFactoryImpl.CompositeSpanFactory compositeSpanFactory =
|
||||
(MarkwonSpansFactoryImpl.CompositeSpanFactory) builder.getFactory(node);
|
||||
assertNotNull(compositeSpanFactory);
|
||||
assertEquals(Arrays.asList(second, first), compositeSpanFactory.factories);
|
||||
|
||||
builder.appendFactory(node, third);
|
||||
assertEquals(compositeSpanFactory, builder.getFactory(node));
|
||||
assertEquals(Arrays.asList(third, second, first), compositeSpanFactory.factories);
|
||||
}
|
||||
}
|
@ -166,6 +166,18 @@ public class CorePluginTest {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public <N extends Node> MarkwonSpansFactory.Builder appendFactory(@NonNull Class<N> node, @NonNull SpanFactory factory) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public <N extends Node> MarkwonSpansFactory.Builder prependFactory(@NonNull Class<N> node, @NonNull SpanFactory factory) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public <N extends Node> SpanFactory getFactory(@NonNull Class<N> node) {
|
||||
|
@ -3,10 +3,12 @@ package io.noties.markwon.sample.recycler;
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.text.TextPaint;
|
||||
import android.text.TextUtils;
|
||||
import android.text.style.CharacterStyle;
|
||||
import android.text.style.UpdateAppearance;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
@ -15,6 +17,7 @@ import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import org.commonmark.ext.gfm.tables.TableBlock;
|
||||
import org.commonmark.node.FencedCodeBlock;
|
||||
import org.commonmark.node.Link;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
@ -26,14 +29,13 @@ import io.noties.debug.Debug;
|
||||
import io.noties.markwon.AbstractMarkwonPlugin;
|
||||
import io.noties.markwon.Markwon;
|
||||
import io.noties.markwon.MarkwonConfiguration;
|
||||
import io.noties.markwon.MarkwonSpansFactory;
|
||||
import io.noties.markwon.MarkwonVisitor;
|
||||
import io.noties.markwon.core.CorePlugin;
|
||||
import io.noties.markwon.html.HtmlPlugin;
|
||||
import io.noties.markwon.image.AsyncDrawable;
|
||||
import io.noties.markwon.image.ImagesPlugin;
|
||||
import io.noties.markwon.image.file.FileSchemeHandler;
|
||||
import io.noties.markwon.image.network.OkHttpNetworkSchemeHandler;
|
||||
import io.noties.markwon.image.picasso.PicassoImagesPlugin;
|
||||
import io.noties.markwon.image.svg.SvgMediaDecoder;
|
||||
import io.noties.markwon.recycler.MarkwonAdapter;
|
||||
import io.noties.markwon.recycler.SimpleEntry;
|
||||
@ -114,10 +116,24 @@ public class RecyclerActivity extends Activity {
|
||||
visitor.builder().append(code);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configureSpansFactory(@NonNull MarkwonSpansFactory.Builder builder) {
|
||||
// `RemoveUnderlineSpan` will be added AFTER original, thus it will remove underline applied by original
|
||||
builder.appendFactory(Link.class, (configuration, props) -> new RemoveUnderlineSpan());
|
||||
}
|
||||
})
|
||||
.build();
|
||||
}
|
||||
|
||||
private static class RemoveUnderlineSpan extends CharacterStyle implements UpdateAppearance {
|
||||
|
||||
@Override
|
||||
public void updateDrawState(TextPaint tp) {
|
||||
tp.setUnderlineText(false);
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private static String loadReadMe(@NonNull Context context) {
|
||||
InputStream stream = null;
|
||||
|
Loading…
x
Reference in New Issue
Block a user