load(@NonNull AsyncDrawable drawable) {
+ return Glide.with(context).load(drawable.getDestination());
+ }
+
+ @Override
+ public void cancel(@NonNull Target> target) {
+ Glide.with(context).clear(target);
+ }
+ }))
+ .build();
+```
\ No newline at end of file
diff --git a/docs/docs/v4/image-picasso/README.md b/docs/docs/v4/image-picasso/README.md
index 852ff0e5..22d5f72d 100644
--- a/docs/docs/v4/image-picasso/README.md
+++ b/docs/docs/v4/image-picasso/README.md
@@ -1,3 +1,32 @@
# Image Picasso
-
\ No newline at end of file
+
+
+Image loading based on `Picasso` library
+
+```java
+final Markwon markwon = Markwon.builder(context)
+ // automatically create Picasso instance
+ .usePlugin(PicassoImagesPlugin.create(context))
+ // use provided picasso instance
+ .usePlugin(PicassoImagesPlugin.create(Picasso.get()))
+ // if you need more control
+ .usePlugin(PicassoImagesPlugin.create(new PicassoImagesPlugin.PicassoStore() {
+ @NonNull
+ @Override
+ public RequestCreator load(@NonNull AsyncDrawable drawable) {
+ return Picasso.get()
+ .load(drawable.getDestination())
+ // please note that drawable should be used as tag (not a destination)
+ // otherwise there won't be support for multiple images with the same URL
+ .tag(drawable);
+ }
+
+ @Override
+ public void cancel(@NonNull AsyncDrawable drawable) {
+ Picasso.get()
+ .cancelTag(drawable);
+ }
+ }))
+ .build();
+```
\ No newline at end of file
diff --git a/docs/docs/v4/image/README.md b/docs/docs/v4/image/README.md
index bee67c00..62cb8e77 100644
--- a/docs/docs/v4/image/README.md
+++ b/docs/docs/v4/image/README.md
@@ -194,15 +194,153 @@ introduce any unexpected behavior.
### GifMediaDecoder
+Adds support for GIF media in markdown. If `pl.droidsonroids.gif:android-gif-drawable:*` dependency
+is found in the classpath, then registration will happen automatically.
+
+```java
+final Markwon markwon = Markwon.builder(context)
+ .usePlugin(ImagesPlugin.create(new ImagesPlugin.ImagesConfigure() {
+ @Override
+ public void configureImages(@NonNull ImagesPlugin plugin) {
+ // autoplayGif controls if GIF should be automatically started
+ plugin.addMediaDecoder(GifMediaDecoder.create(/*autoplayGif*/false));
+ }
+ }))
+ .build();
+```
+
### SvgMediaDecoder
+Adds support for SVG media in markdown. If `com.caverock:androidsvg:*` dependency is found
+in the classpath, then registration will happen automatically.
+
+```java
+final Markwon markwon = Markwon.builder(context)
+ .usePlugin(ImagesPlugin.create(new ImagesPlugin.ImagesConfigure() {
+ @Override
+ public void configureImages(@NonNull ImagesPlugin plugin) {
+
+ // uses supplied Resources
+ plugin.addMediaDecoder(SvgMediaDecoder.create(context.getResources()));
+
+ // uses Resources.getSystem()
+ plugin.addMediaDecoder(SvgMediaDecoder.create());
+ }
+ }))
+ .build();
+```
+
### DefaultMediaDecoder
+`DefaultMediaDecoder` _tries_ to decode supplied InputStream
+as Bitmap (via `BitmapFactory.decodeStream(inputStream)`). This decoder is registered automatically.
+
+```java
+final Markwon markwon = Markwon.builder(context)
+ .usePlugin(ImagesPlugin.create(new ImagesPlugin.ImagesConfigure() {
+ @Override
+ public void configureImages(@NonNull ImagesPlugin plugin) {
+
+ // uses supplied Resources
+ plugin.defaultMediaDecoder(DefaultMediaDecoder.create(context.getResources()));
+
+ // uses Resources.getSystem()
+ plugin.defaultMediaDecoder(DefaultMediaDecoder.create());
+ }
+ }))
+ .build();
+```
+
## AsyncDrawableScheduler
+`AsyncDrawableScheduler` is used in order to give `AsyncDrawable` a way to invalidate `TextView`
+that is holding it. A plugin that is dealing with `AsyncDrawable` should always call these methods:
+
+```java
+final Markwon markwon = Markwon.builder(context)
+ .usePlugin(new AbstractMarkwonPlugin() {
+ @Override
+ public void beforeSetText(@NonNull TextView textView, @NonNull Spanned markdown) {
+ AsyncDrawableScheduler.unschedule(textView);
+ }
+
+ @Override
+ public void afterSetText(@NonNull TextView textView) {
+ AsyncDrawableScheduler.schedule(textView);
+ }
+ })
+ .build();
+```
+
+:::tip
+Starting with multiple plugins can call `AsyncDrawableScheduler#schedule`
+method without the penalty to process `AsyncDrawable` callbacks multiple times (internally caches
+state which ensures that a `TextView` is processed only once the text has changed).
+:::
+
## ErrorHandler
-## Placeholder
+An `ErrorHandler` can be used to receive an error that has happened during image loading
+and (optionally) return an error drawable to be displayed instead
+
+```java
+final Markwon markwon = Markwon.builder(context)
+ .usePlugin(ImagesPlugin.create(new ImagesPlugin.ImagesConfigure() {
+ @Override
+ public void configureImages(@NonNull ImagesPlugin plugin) {
+ plugin.errorHandler(new ImagesPlugin.ErrorHandler() {
+ @Nullable
+ @Override
+ public Drawable handleError(@NonNull String url, @NonNull Throwable throwable) {
+ return null;
+ }
+ });
+ }
+ }))
+ .build();
+```
+
+## PlaceholderProvider
+
+To display a placeholder during image loading `PlaceholderProvider` can be used:
+
+```java
+final Markwon markwon = Markwon.builder(context)
+ .usePlugin(ImagesPlugin.create(new ImagesPlugin.ImagesConfigure() {
+ @Override
+ public void configureImages(@NonNull ImagesPlugin plugin) {
+ plugin.placeholderProvider(new ImagesPlugin.PlaceholderProvider() {
+ @Nullable
+ @Override
+ public Drawable providePlaceholder(@NonNull AsyncDrawable drawable) {
+ return null;
+ }
+ });
+ }
+ }))
+ .build();
+```
+
+:::tip
+If your placeholder drawable has _specific_ size which is not the same an image that is being loaded,
+you can manually assign bounds to the placeholder:
+
+```java
+plugin.placeholderProvider(new ImagesPlugin.PlaceholderProvider() {
+ @Override
+ public Drawable providePlaceholder(@NonNull AsyncDrawable drawable) {
+ final ColorDrawable placeholder = new ColorDrawable(Color.BLUE);
+ // these bounds will be used to display a placeholder,
+ // so even if loading image has size `width=100%`, placeholder
+ // bounds won't be affected by it
+ placeholder.setBounds(0, 0, 48, 48);
+ return placeholder;
+ }
+});
+```
+:::
+
+---
:::tip
If you are using [html](/docs/v4/html/) you do not have to additionally setup
diff --git a/docs/docs/v4/linkify/README.md b/docs/docs/v4/linkify/README.md
index 10a96b98..6140e4bc 100644
--- a/docs/docs/v4/linkify/README.md
+++ b/docs/docs/v4/linkify/README.md
@@ -1,3 +1,31 @@
# Linkify
-
\ No newline at end of file
+
+
+A plugin to automatically add links to your markdown. Currently autolinking works for:
+* email (`me@web.com`)
+* phone numbers (`+10000000`)
+* web URLS
+
+:::warning
+`Linkify` plugin is based on `android.text.util.Linkify` which can lead to significant performance
+drop due to its implementation based on regex.
+:::
+
+:::danger
+Do not use `autolink` XML attribute on your `TextView` as it will remove
+all links except autolinked ones ¯\\\_(ツ)_/¯
+:::
+
+```java
+final Markwon markwon = Markwon.builder(context)
+ // will autolink all supported types
+ .usePlugin(LinkifyPlugin.create())
+ // the same as above
+ .usePlugin(LinkifyPlugin.create(
+ Linkify.EMAIL_ADDRESSES | Linkify.PHONE_NUMBERS | Linkify.WEB_URLS
+ ))
+ // only emails
+ .usePlugin(LinkifyPlugin.create(Linkify.EMAIL_ADDRESSES))
+ .build();
+```
\ No newline at end of file
diff --git a/docs/docs/v4/migration-3-4.md b/docs/docs/v4/migration-3-4.md
index f36cf75a..8dd6bc5d 100644
--- a/docs/docs/v4/migration-3-4.md
+++ b/docs/docs/v4/migration-3-4.md
@@ -2,5 +2,6 @@
* maven group-id is changed: `io.noties.markwon` (was `ru.noties.markwon`)
* root package-name is changed: `io.noties.markwon` (was `ru.noties.markwon`)
+* `androidx` packages
todo
\ No newline at end of file
diff --git a/docs/docs/v4/simple-ext/README.md b/docs/docs/v4/simple-ext/README.md
index c16fc085..ded84bb6 100644
--- a/docs/docs/v4/simple-ext/README.md
+++ b/docs/docs/v4/simple-ext/README.md
@@ -60,3 +60,11 @@ This extension will be applied to a text like this:
```md
@@we are inside different delimiter characters$$
```
+
+:::warning
+Space character cannot be used as a delimiter (from either side). So,
+```java
+plugin.addExtension(1, '@', ' ', /*spanFactory*/);
+```
+won't work for `@some-text ` text
+:::
diff --git a/markwon-core/src/main/java/io/noties/markwon/LinkResolver.java b/markwon-core/src/main/java/io/noties/markwon/LinkResolver.java
index 1a6c9010..f468f872 100644
--- a/markwon-core/src/main/java/io/noties/markwon/LinkResolver.java
+++ b/markwon-core/src/main/java/io/noties/markwon/LinkResolver.java
@@ -7,7 +7,7 @@ import androidx.annotation.NonNull;
/**
* @see LinkResolverDef
* @see MarkwonConfiguration.Builder#linkResolver(LinkResolver)
- * @since 4.0.0-SNAPSHOT
+ * @since 4.0.0
*/
public interface LinkResolver {
void resolve(@NonNull View view, @NonNull String link);
diff --git a/markwon-core/src/main/java/io/noties/markwon/Markwon.java b/markwon-core/src/main/java/io/noties/markwon/Markwon.java
index 1f3896ce..ac702599 100644
--- a/markwon-core/src/main/java/io/noties/markwon/Markwon.java
+++ b/markwon-core/src/main/java/io/noties/markwon/Markwon.java
@@ -47,14 +47,14 @@ public abstract class Markwon {
@NonNull
public static Builder builder(@NonNull Context context) {
return new MarkwonBuilderImpl(context)
- // @since 4.0.0-SNAPSHOT add CorePlugin
+ // @since 4.0.0 add CorePlugin
.usePlugin(CorePlugin.create());
}
/**
* Factory method to obtain an instance of {@link Builder} without {@link CorePlugin}.
*
- * @since 4.0.0-SNAPSHOT
+ * @since 4.0.0
*/
@NonNull
public static Builder builderNoCore(@NonNull Context context) {
diff --git a/markwon-core/src/main/java/io/noties/markwon/MarkwonConfiguration.java b/markwon-core/src/main/java/io/noties/markwon/MarkwonConfiguration.java
index b911e945..5b22623f 100644
--- a/markwon-core/src/main/java/io/noties/markwon/MarkwonConfiguration.java
+++ b/markwon-core/src/main/java/io/noties/markwon/MarkwonConfiguration.java
@@ -95,7 +95,7 @@ public class MarkwonConfiguration {
}
/**
- * @since 4.0.0-SNAPSHOT
+ * @since 4.0.0
*/
@NonNull
public Builder asyncDrawableLoader(@NonNull AsyncDrawableLoader asyncDrawableLoader) {
@@ -138,7 +138,7 @@ public class MarkwonConfiguration {
this.theme = theme;
this.spansFactory = spansFactory;
- // @since 4.0.0-SNAPSHOT
+ // @since 4.0.0
if (asyncDrawableLoader == null) {
asyncDrawableLoader = AsyncDrawableLoader.noOp();
}
diff --git a/markwon-core/src/main/java/io/noties/markwon/MarkwonPlugin.java b/markwon-core/src/main/java/io/noties/markwon/MarkwonPlugin.java
index a916540a..33527a9b 100644
--- a/markwon-core/src/main/java/io/noties/markwon/MarkwonPlugin.java
+++ b/markwon-core/src/main/java/io/noties/markwon/MarkwonPlugin.java
@@ -26,7 +26,7 @@ public interface MarkwonPlugin {
/**
* @see Registry#require(Class, Action)
- * @since 4.0.0-SNAPSHOT
+ * @since 4.0.0
*/
interface Action {
void apply(@NonNull P p);
@@ -34,7 +34,7 @@ public interface MarkwonPlugin {
/**
* @see #configure(Registry)
- * @since 4.0.0-SNAPSHOT
+ * @since 4.0.0
*/
interface Registry {
@@ -49,7 +49,7 @@ public interface MarkwonPlugin {
/**
* This method will be called before any other during {@link Markwon} instance construction.
*
- * @since 4.0.0-SNAPSHOT
+ * @since 4.0.0
*/
void configure(@NonNull Registry registry);
@@ -91,14 +91,6 @@ public interface MarkwonPlugin {
*/
void configureSpansFactory(@NonNull MarkwonSpansFactory.Builder builder);
-// /**
-// * Configure {@link MarkwonHtmlRenderer} to add or remove HTML {@link TagHandler}s
-// *
-// * @see MarkwonHtmlRenderer
-// * @see MarkwonHtmlRenderer.Builder
-// */
-// void configureHtmlRenderer(@NonNull MarkwonHtmlRenderer.Builder builder);
-
/**
* Process input markdown and return new string to be used in parsing stage further.
* Can be described as pre-processing
of markdown String.
diff --git a/markwon-core/src/main/java/io/noties/markwon/RegistryImpl.java b/markwon-core/src/main/java/io/noties/markwon/RegistryImpl.java
index 76805be8..d1d0acdb 100644
--- a/markwon-core/src/main/java/io/noties/markwon/RegistryImpl.java
+++ b/markwon-core/src/main/java/io/noties/markwon/RegistryImpl.java
@@ -10,7 +10,7 @@ import java.util.Set;
import io.noties.markwon.core.CorePlugin;
-// @since 4.0.0-SNAPSHOT
+// @since 4.0.0
class RegistryImpl implements MarkwonPlugin.Registry {
private final List origin;
diff --git a/markwon-core/src/main/java/io/noties/markwon/core/CorePlugin.java b/markwon-core/src/main/java/io/noties/markwon/core/CorePlugin.java
index 084fb0d2..194882e3 100644
--- a/markwon-core/src/main/java/io/noties/markwon/core/CorePlugin.java
+++ b/markwon-core/src/main/java/io/noties/markwon/core/CorePlugin.java
@@ -58,7 +58,7 @@ public class CorePlugin extends AbstractMarkwonPlugin {
/**
* @see #addOnTextAddedListener(OnTextAddedListener)
- * @since 4.0.0-SNAPSHOT
+ * @since 4.0.0
*/
public interface OnTextAddedListener {
@@ -88,7 +88,7 @@ public class CorePlugin extends AbstractMarkwonPlugin {
return new CorePlugin();
}
- // @since 4.0.0-SNAPSHOT
+ // @since 4.0.0
private final List onTextAddedListeners = new ArrayList<>(0);
protected CorePlugin() {
@@ -98,7 +98,7 @@ public class CorePlugin extends AbstractMarkwonPlugin {
* Can be useful to post-process text added. For example for auto-linking capabilities.
*
* @see OnTextAddedListener
- * @since 4.0.0-SNAPSHOT
+ * @since 4.0.0
*/
@SuppressWarnings("UnusedReturnValue")
@NonNull
@@ -171,7 +171,7 @@ public class CorePlugin extends AbstractMarkwonPlugin {
visitor.builder().append(literal);
- // @since 4.0.0-SNAPSHOT
+ // @since 4.0.0
if (!onTextAddedListeners.isEmpty()) {
// calculate the start position
final int length = visitor.length() - literal.length();
@@ -262,7 +262,7 @@ public class CorePlugin extends AbstractMarkwonPlugin {
});
}
- // @since 4.0.0-SNAPSHOT
+ // @since 4.0.0
// his method is moved from ImagesPlugin. Alternative implementations must set SpanFactory
// for Image node in order for this visitor to function
private static void image(MarkwonVisitor.Builder builder) {
diff --git a/markwon-core/src/main/java/io/noties/markwon/core/spans/LastLineSpacingSpan.java b/markwon-core/src/main/java/io/noties/markwon/core/spans/LastLineSpacingSpan.java
index 560e3026..6ef71dea 100644
--- a/markwon-core/src/main/java/io/noties/markwon/core/spans/LastLineSpacingSpan.java
+++ b/markwon-core/src/main/java/io/noties/markwon/core/spans/LastLineSpacingSpan.java
@@ -8,7 +8,7 @@ import androidx.annotation.NonNull;
import androidx.annotation.Px;
/**
- * @since 4.0.0-SNAPSHOT
+ * @since 4.0.0
*/
public class LastLineSpacingSpan implements LineHeightSpan {
diff --git a/markwon-core/src/main/java/io/noties/markwon/image/AsyncDrawable.java b/markwon-core/src/main/java/io/noties/markwon/image/AsyncDrawable.java
index 7eb4b38d..62ea138a 100644
--- a/markwon-core/src/main/java/io/noties/markwon/image/AsyncDrawable.java
+++ b/markwon-core/src/main/java/io/noties/markwon/image/AsyncDrawable.java
@@ -53,7 +53,7 @@ public class AsyncDrawable extends Drawable {
}
/**
- * @since 4.0.0-SNAPSHOT
+ * @since 4.0.0
*/
@Nullable
public ImageSize getImageSize() {
@@ -61,7 +61,7 @@ public class AsyncDrawable extends Drawable {
}
/**
- * @since 4.0.0-SNAPSHOT
+ * @since 4.0.0
*/
@NonNull
public ImageSizeResolver getImageSizeResolver() {
@@ -69,7 +69,7 @@ public class AsyncDrawable extends Drawable {
}
/**
- * @since 4.0.0-SNAPSHOT
+ * @since 4.0.0
*/
public boolean hasKnownDimentions() {
return canvasWidth > 0;
@@ -77,7 +77,7 @@ public class AsyncDrawable extends Drawable {
/**
* @see #hasKnownDimentions()
- * @since 4.0.0-SNAPSHOT
+ * @since 4.0.0
*/
public int getLastKnownCanvasWidth() {
return canvasWidth;
@@ -85,7 +85,7 @@ public class AsyncDrawable extends Drawable {
/**
* @see #hasKnownDimentions()
- * @since 4.0.0-SNAPSHOT
+ * @since 4.0.0
*/
public float getLastKnowTextSize() {
return textSize;
@@ -262,7 +262,7 @@ public class AsyncDrawable extends Drawable {
if (hasResult()) {
out = result.getIntrinsicWidth();
} else {
- // @since 4.0.0-SNAPSHOT, must not be zero in order to receive canvas dimensions
+ // @since 4.0.0, must not be zero in order to receive canvas dimensions
out = 1;
}
return out;
@@ -274,7 +274,7 @@ public class AsyncDrawable extends Drawable {
if (hasResult()) {
out = result.getIntrinsicHeight();
} else {
- // @since 4.0.0-SNAPSHOT, must not be zero in order to receive canvas dimensions
+ // @since 4.0.0, must not be zero in order to receive canvas dimensions
out = 1;
}
return out;
diff --git a/markwon-core/src/main/java/io/noties/markwon/image/AsyncDrawableLoader.java b/markwon-core/src/main/java/io/noties/markwon/image/AsyncDrawableLoader.java
index 75c99384..9907202f 100644
--- a/markwon-core/src/main/java/io/noties/markwon/image/AsyncDrawableLoader.java
+++ b/markwon-core/src/main/java/io/noties/markwon/image/AsyncDrawableLoader.java
@@ -16,12 +16,12 @@ public abstract class AsyncDrawableLoader {
}
/**
- * @since 3.1.0-SNAPSHOT
+ * @since 4.0.0
*/
public abstract void load(@NonNull AsyncDrawable drawable);
/**
- * @since 3.1.0-SNAPSHOT
+ * @since 4.0.0
*/
public abstract void cancel(@NonNull AsyncDrawable drawable);
diff --git a/markwon-core/src/main/java/io/noties/markwon/image/AsyncDrawableScheduler.java b/markwon-core/src/main/java/io/noties/markwon/image/AsyncDrawableScheduler.java
index 63ad3f68..a7d664e3 100644
--- a/markwon-core/src/main/java/io/noties/markwon/image/AsyncDrawableScheduler.java
+++ b/markwon-core/src/main/java/io/noties/markwon/image/AsyncDrawableScheduler.java
@@ -24,7 +24,7 @@ public abstract class AsyncDrawableScheduler {
// hm... we need the same thing for unschedule then... we can check if last hash is !null,
// if it's not -> unschedule, else ignore
- // @since 4.0.0-SNAPSHOT
+ // @since 4.0.0
final Integer lastTextHashCode =
(Integer) textView.getTag(R.id.markwon_drawables_scheduler_last_text_hashcode);
final int textHashCode = textView.getText().hashCode();
@@ -69,7 +69,7 @@ public abstract class AsyncDrawableScheduler {
// must be called when text manually changed in TextView
public static void unschedule(@NonNull TextView view) {
- // @since 4.0.0-SNAPSHOT
+ // @since 4.0.0
if (view.getTag(R.id.markwon_drawables_scheduler_last_text_hashcode) == null) {
return;
}
@@ -99,7 +99,7 @@ public abstract class AsyncDrawableScheduler {
}
// we also could've tried the `nextSpanTransition`, but strangely it leads to worse performance
- // then direct getSpans
+ // than direct getSpans
return ((Spanned) cs).getSpans(0, length, AsyncDrawableSpan.class);
}
diff --git a/markwon-core/src/main/java/io/noties/markwon/image/ImageSizeResolver.java b/markwon-core/src/main/java/io/noties/markwon/image/ImageSizeResolver.java
index ecd7bbcb..cc7e7060 100644
--- a/markwon-core/src/main/java/io/noties/markwon/image/ImageSizeResolver.java
+++ b/markwon-core/src/main/java/io/noties/markwon/image/ImageSizeResolver.java
@@ -12,7 +12,7 @@ import androidx.annotation.NonNull;
public abstract class ImageSizeResolver {
/**
- * @since 4.0.0-SNAPSHOT
+ * @since 4.0.0
*/
@NonNull
public abstract Rect resolveImageSize(@NonNull AsyncDrawable drawable);
diff --git a/markwon-core/src/test/java/io/noties/markwon/image/ImageSizeResolverDefTest.java b/markwon-core/src/test/java/io/noties/markwon/image/ImageSizeResolverDefTest.java
index 5030986c..455ccb74 100644
--- a/markwon-core/src/test/java/io/noties/markwon/image/ImageSizeResolverDefTest.java
+++ b/markwon-core/src/test/java/io/noties/markwon/image/ImageSizeResolverDefTest.java
@@ -31,7 +31,7 @@ public class ImageSizeResolverDefTest {
@Test
public void correct_redirect() {
- // @since 4.0.0-SNAPSHOT the main method is changed to accept AsyncDrawable
+ // @since 4.0.0 the main method is changed to accept AsyncDrawable
final ImageSizeResolverDef def = mock(ImageSizeResolverDef.class, Mockito.CALLS_REAL_METHODS);
final AsyncDrawable drawable = mock(AsyncDrawable.class);
diff --git a/markwon-ext-latex/src/main/java/io/noties/markwon/ext/latex/JLatexMathPlugin.java b/markwon-ext-latex/src/main/java/io/noties/markwon/ext/latex/JLatexMathPlugin.java
index 8b7bce3e..6e3ea341 100644
--- a/markwon-ext-latex/src/main/java/io/noties/markwon/ext/latex/JLatexMathPlugin.java
+++ b/markwon-ext-latex/src/main/java/io/noties/markwon/ext/latex/JLatexMathPlugin.java
@@ -36,7 +36,7 @@ import ru.noties.jlatexmath.JLatexMathDrawable;
public class JLatexMathPlugin extends AbstractMarkwonPlugin {
/**
- * @since 4.0.0-SNAPSHOT
+ * @since 4.0.0
*/
public interface BackgroundProvider {
@NonNull
@@ -73,7 +73,7 @@ public class JLatexMathPlugin extends AbstractMarkwonPlugin {
private final float textSize;
- // @since 4.0.0-SNAPSHOT
+ // @since 4.0.0
private final BackgroundProvider backgroundProvider;
@JLatexMathDrawable.Align
@@ -81,13 +81,13 @@ public class JLatexMathPlugin extends AbstractMarkwonPlugin {
private final boolean fitCanvas;
- // @since 4.0.0-SNAPSHOT
+ // @since 4.0.0
private final int paddingHorizontal;
- // @since 4.0.0-SNAPSHOT
+ // @since 4.0.0
private final int paddingVertical;
- // @since 4.0.0-SNAPSHOT
+ // @since 4.0.0
private final ExecutorService executorService;
Config(@NonNull Builder builder) {
@@ -98,7 +98,7 @@ public class JLatexMathPlugin extends AbstractMarkwonPlugin {
this.paddingHorizontal = builder.paddingHorizontal;
this.paddingVertical = builder.paddingVertical;
- // @since 4.0.0-SNAPSHOT
+ // @since 4.0.0
ExecutorService executorService = builder.executorService;
if (executorService == null) {
executorService = Executors.newCachedThreadPool();
@@ -164,7 +164,7 @@ public class JLatexMathPlugin extends AbstractMarkwonPlugin {
private final float textSize;
- // @since 4.0.0-SNAPSHOT
+ // @since 4.0.0
private BackgroundProvider backgroundProvider;
@JLatexMathDrawable.Align
@@ -172,13 +172,13 @@ public class JLatexMathPlugin extends AbstractMarkwonPlugin {
private boolean fitCanvas = true;
- // @since 4.0.0-SNAPSHOT
+ // @since 4.0.0
private int paddingHorizontal;
- // @since 4.0.0-SNAPSHOT
+ // @since 4.0.0
private int paddingVertical;
- // @since 4.0.0-SNAPSHOT
+ // @since 4.0.0
private ExecutorService executorService;
Builder(float textSize) {
@@ -211,7 +211,7 @@ public class JLatexMathPlugin extends AbstractMarkwonPlugin {
}
/**
- * @since 4.0.0-SNAPSHOT
+ * @since 4.0.0
*/
@NonNull
public Builder builder(@Px int paddingHorizontal, @Px int paddingVertical) {
@@ -221,7 +221,7 @@ public class JLatexMathPlugin extends AbstractMarkwonPlugin {
}
/**
- * @since 4.0.0-SNAPSHOT
+ * @since 4.0.0
*/
@NonNull
public Builder executorService(@NonNull ExecutorService executorService) {
@@ -235,7 +235,7 @@ public class JLatexMathPlugin extends AbstractMarkwonPlugin {
}
}
- // @since 4.0.0-SNAPSHOT
+ // @since 4.0.0
private static class JLatextAsyncDrawableLoader extends AsyncDrawableLoader {
private final Config config;
@@ -317,7 +317,7 @@ public class JLatexMathPlugin extends AbstractMarkwonPlugin {
}
// we must make drawable fit canvas (if specified), but do not keep the ratio whilst scaling up
- // @since 4.0.0-SNAPSHOT
+ // @since 4.0.0
private static class JLatexImageSizeResolver extends ImageSizeResolver {
private final boolean fitCanvas;
diff --git a/markwon-html/src/main/java/io/noties/markwon/html/HtmlPlugin.java b/markwon-html/src/main/java/io/noties/markwon/html/HtmlPlugin.java
index c4462c99..c2c13c12 100644
--- a/markwon-html/src/main/java/io/noties/markwon/html/HtmlPlugin.java
+++ b/markwon-html/src/main/java/io/noties/markwon/html/HtmlPlugin.java
@@ -29,7 +29,7 @@ public class HtmlPlugin extends AbstractMarkwonPlugin {
/**
* @see #create(HtmlConfigure)
- * @since 4.0.0-SNAPSHOT
+ * @since 4.0.0
*/
public interface HtmlConfigure {
void configureHtml(@NonNull HtmlPlugin plugin);
@@ -41,7 +41,7 @@ public class HtmlPlugin extends AbstractMarkwonPlugin {
}
/**
- * @since 4.0.0-SNAPSHOT
+ * @since 4.0.0
*/
@NonNull
public static HtmlPlugin create(@NonNull HtmlConfigure configure) {
@@ -65,7 +65,7 @@ public class HtmlPlugin extends AbstractMarkwonPlugin {
/**
* @param allowNonClosedTags whether or not non-closed tags should be closed
* at the document end. By default `false`
- * @since 4.0.0-SNAPSHOT
+ * @since 4.0.0
*/
@NonNull
public HtmlPlugin allowNonClosedTags(boolean allowNonClosedTags) {
@@ -74,7 +74,7 @@ public class HtmlPlugin extends AbstractMarkwonPlugin {
}
/**
- * @since 4.0.0-SNAPSHOT
+ * @since 4.0.0
*/
@NonNull
public HtmlPlugin addHandler(@NonNull TagHandler tagHandler) {
@@ -83,7 +83,7 @@ public class HtmlPlugin extends AbstractMarkwonPlugin {
}
/**
- * @since 4.0.0-SNAPSHOT
+ * @since 4.0.0
*/
@Nullable
public TagHandler getHandler(@NonNull String tagName) {
@@ -96,7 +96,7 @@ public class HtmlPlugin extends AbstractMarkwonPlugin {
* {@link TagHandlerNoOp} to no-op certain default tags.
*
* @see TagHandlerNoOp
- * @since 4.0.0-SNAPSHOT
+ * @since 4.0.0
*/
@NonNull
public HtmlPlugin excludeDefaults(boolean excludeDefaults) {
@@ -107,7 +107,7 @@ public class HtmlPlugin extends AbstractMarkwonPlugin {
@Override
public void configureConfiguration(@NonNull MarkwonConfiguration.Builder configurationBuilder) {
- // @since 4.0.0-SNAPSHOT we init internal html-renderer here (marks the end of configuration)
+ // @since 4.0.0 we init internal html-renderer here (marks the end of configuration)
final MarkwonHtmlRendererImpl.Builder builder = this.builder;
diff --git a/markwon-html/src/main/java/io/noties/markwon/html/TagHandler.java b/markwon-html/src/main/java/io/noties/markwon/html/TagHandler.java
index 66a30e06..29693a07 100644
--- a/markwon-html/src/main/java/io/noties/markwon/html/TagHandler.java
+++ b/markwon-html/src/main/java/io/noties/markwon/html/TagHandler.java
@@ -15,7 +15,7 @@ public abstract class TagHandler {
);
/**
- * @since 4.0.0-SNAPSHOT
+ * @since 4.0.0
*/
@NonNull
public abstract Collection supportedTags();
diff --git a/markwon-html/src/main/java/io/noties/markwon/html/TagHandlerNoOp.java b/markwon-html/src/main/java/io/noties/markwon/html/TagHandlerNoOp.java
index 79ba8dea..dcc31bed 100644
--- a/markwon-html/src/main/java/io/noties/markwon/html/TagHandlerNoOp.java
+++ b/markwon-html/src/main/java/io/noties/markwon/html/TagHandlerNoOp.java
@@ -9,7 +9,7 @@ import java.util.Collections;
import io.noties.markwon.MarkwonVisitor;
/**
- * @since 4.0.0-SNAPSHOT
+ * @since 4.0.0
*/
public class TagHandlerNoOp extends TagHandler {
diff --git a/markwon-image-glide/src/main/java/io/noties/markwon/image/glide/GlideImagesPlugin.java b/markwon-image-glide/src/main/java/io/noties/markwon/image/glide/GlideImagesPlugin.java
index ae15afa4..e690c014 100644
--- a/markwon-image-glide/src/main/java/io/noties/markwon/image/glide/GlideImagesPlugin.java
+++ b/markwon-image-glide/src/main/java/io/noties/markwon/image/glide/GlideImagesPlugin.java
@@ -30,7 +30,7 @@ import io.noties.markwon.image.DrawableUtils;
import io.noties.markwon.image.ImageSpanFactory;
/**
- * @since 4.0.0-SNAPSHOT
+ * @since 4.0.0
*/
public class GlideImagesPlugin extends AbstractMarkwonPlugin {
diff --git a/markwon-image-picasso/src/main/java/io/noties/markwon/image/picasso/PicassoImagesPlugin.java b/markwon-image-picasso/src/main/java/io/noties/markwon/image/picasso/PicassoImagesPlugin.java
index 4e92fced..ea751030 100644
--- a/markwon-image-picasso/src/main/java/io/noties/markwon/image/picasso/PicassoImagesPlugin.java
+++ b/markwon-image-picasso/src/main/java/io/noties/markwon/image/picasso/PicassoImagesPlugin.java
@@ -30,7 +30,7 @@ import io.noties.markwon.image.DrawableUtils;
import io.noties.markwon.image.ImageSpanFactory;
/**
- * @since 4.0.0-SNAPSHOT
+ * @since 4.0.0
*/
public class PicassoImagesPlugin extends AbstractMarkwonPlugin {
diff --git a/markwon-image/src/main/java/io/noties/markwon/image/AsyncDrawableLoaderBuilder.java b/markwon-image/src/main/java/io/noties/markwon/image/AsyncDrawableLoaderBuilder.java
index 24ce355a..25daf016 100644
--- a/markwon-image/src/main/java/io/noties/markwon/image/AsyncDrawableLoaderBuilder.java
+++ b/markwon-image/src/main/java/io/noties/markwon/image/AsyncDrawableLoaderBuilder.java
@@ -28,7 +28,7 @@ class AsyncDrawableLoaderBuilder {
AsyncDrawableLoaderBuilder() {
- // @since 4.0.0-SNAPSHOT
+ // @since 4.0.0
// okay, let's add supported schemes at the start, this would be : data-uri and default network
// we should not use file-scheme as it's a bit complicated to assume file usage (lack of permissions)
addSchemeHandler(DataUriSchemeHandler.create());
diff --git a/markwon-image/src/main/java/io/noties/markwon/image/AsyncDrawableLoaderImpl.java b/markwon-image/src/main/java/io/noties/markwon/image/AsyncDrawableLoaderImpl.java
index e1b92d55..e227cc6d 100644
--- a/markwon-image/src/main/java/io/noties/markwon/image/AsyncDrawableLoaderImpl.java
+++ b/markwon-image/src/main/java/io/noties/markwon/image/AsyncDrawableLoaderImpl.java
@@ -28,7 +28,7 @@ class AsyncDrawableLoaderImpl extends AsyncDrawableLoader {
private final Handler handler;
- // @since 4.0.0-SNAPSHOT use a hash-map with a AsyncDrawable as key for multiple requests
+ // @since 4.0.0 use a hash-map with a AsyncDrawable as key for multiple requests
// for the same destination
private final Map> requests = new HashMap<>(2);
@@ -36,7 +36,7 @@ class AsyncDrawableLoaderImpl extends AsyncDrawableLoader {
this(builder, new Handler(Looper.getMainLooper()));
}
- // @since 4.0.0-SNAPSHOT
+ // @since 4.0.0
@VisibleForTesting
AsyncDrawableLoaderImpl(@NonNull AsyncDrawableLoaderBuilder builder, @NonNull Handler handler) {
this.executorService = builder.executorService;
@@ -144,7 +144,7 @@ class AsyncDrawableLoaderImpl extends AsyncDrawableLoader {
final Drawable out = drawable;
- // @since 4.0.0-SNAPSHOT apply intrinsic bounds (but only if they are empty)
+ // @since 4.0.0 apply intrinsic bounds (but only if they are empty)
if (out != null) {
final Rect bounds = out.getBounds();
//noinspection ConstantConditions
diff --git a/markwon-image/src/main/java/io/noties/markwon/image/ImageItem.java b/markwon-image/src/main/java/io/noties/markwon/image/ImageItem.java
index 191e3e10..e44587ea 100644
--- a/markwon-image/src/main/java/io/noties/markwon/image/ImageItem.java
+++ b/markwon-image/src/main/java/io/noties/markwon/image/ImageItem.java
@@ -17,7 +17,7 @@ public abstract class ImageItem {
*
* @see #withDecodingNeeded(String, InputStream)
* @see WithResult
- * @since 4.0.0-SNAPSHOT
+ * @since 4.0.0
*/
@NonNull
public static ImageItem withResult(@NonNull Drawable drawable) {
@@ -29,7 +29,7 @@ public abstract class ImageItem {
*
* @see #withResult(Drawable)
* @see WithDecodingNeeded
- * @since 4.0.0-SNAPSHOT
+ * @since 4.0.0
*/
@NonNull
public static ImageItem withDecodingNeeded(
@@ -43,31 +43,31 @@ public abstract class ImageItem {
}
/**
- * @since 4.0.0-SNAPSHOT
+ * @since 4.0.0
*/
public abstract boolean hasResult();
/**
- * @since 4.0.0-SNAPSHOT
+ * @since 4.0.0
*/
public abstract boolean hasDecodingNeeded();
/**
* @see #hasResult()
- * @since 4.0.0-SNAPSHOT
+ * @since 4.0.0
*/
@NonNull
public abstract WithResult getAsWithResult();
/**
* @see #hasDecodingNeeded()
- * @since 4.0.0-SNAPSHOT
+ * @since 4.0.0
*/
@NonNull
public abstract WithDecodingNeeded getAsWithDecodingNeeded();
/**
- * @since 4.0.0-SNAPSHOT
+ * @since 4.0.0
*/
public static class WithResult extends ImageItem {
@@ -106,7 +106,7 @@ public abstract class ImageItem {
}
/**
- * @since 4.0.0-SNAPSHOT
+ * @since 4.0.0
*/
public static class WithDecodingNeeded extends ImageItem {
diff --git a/markwon-image/src/main/java/io/noties/markwon/image/ImagesPlugin.java b/markwon-image/src/main/java/io/noties/markwon/image/ImagesPlugin.java
index d93ca23d..bd653369 100644
--- a/markwon-image/src/main/java/io/noties/markwon/image/ImagesPlugin.java
+++ b/markwon-image/src/main/java/io/noties/markwon/image/ImagesPlugin.java
@@ -27,14 +27,14 @@ import io.noties.markwon.image.svg.SvgMediaDecoder;
public class ImagesPlugin extends AbstractMarkwonPlugin {
/**
- * @since 4.0.0-SNAPSHOT
+ * @since 4.0.0
*/
public interface ImagesConfigure {
void configureImages(@NonNull ImagesPlugin plugin);
}
/**
- * @since 4.0.0-SNAPSHOT
+ * @since 4.0.0
*/
public interface PlaceholderProvider {
@Nullable
@@ -42,7 +42,7 @@ public class ImagesPlugin extends AbstractMarkwonPlugin {
}
/**
- * @since 4.0.0-SNAPSHOT
+ * @since 4.0.0
*/
public interface ErrorHandler {
@@ -74,12 +74,12 @@ public class ImagesPlugin extends AbstractMarkwonPlugin {
private final AsyncDrawableLoaderBuilder builder;
- // @since 4.0.0-SNAPSHOT
+ // @since 4.0.0
ImagesPlugin() {
this(new AsyncDrawableLoaderBuilder());
}
- // @since 4.0.0-SNAPSHOT
+ // @since 4.0.0
@VisibleForTesting
ImagesPlugin(@NonNull AsyncDrawableLoaderBuilder builder) {
this.builder = builder;
@@ -88,7 +88,7 @@ public class ImagesPlugin extends AbstractMarkwonPlugin {
/**
* Optional (by default new cached thread executor will be used)
*
- * @since 4.0.0-SNAPSHOT
+ * @since 4.0.0
*/
@NonNull
public ImagesPlugin executorService(@NonNull ExecutorService executorService) {
@@ -102,7 +102,7 @@ public class ImagesPlugin extends AbstractMarkwonPlugin {
* @see FileSchemeHandler
* @see NetworkSchemeHandler
* @see OkHttpNetworkSchemeHandler
- * @since 4.0.0-SNAPSHOT
+ * @since 4.0.0
*/
@NonNull
public ImagesPlugin addSchemeHandler(@NonNull SchemeHandler schemeHandler) {
@@ -114,7 +114,7 @@ public class ImagesPlugin extends AbstractMarkwonPlugin {
* @see DefaultMediaDecoder
* @see SvgMediaDecoder
* @see GifMediaDecoder
- * @since 4.0.0-SNAPSHOT
+ * @since 4.0.0
*/
@NonNull
public ImagesPlugin addMediaDecoder(@NonNull MediaDecoder mediaDecoder) {
@@ -127,7 +127,7 @@ public class ImagesPlugin extends AbstractMarkwonPlugin {
* if you need to disable default-image-media-decoder specify here own no-op implementation or null.
*
* @see DefaultMediaDecoder
- * @since 4.0.0-SNAPSHOT
+ * @since 4.0.0
*/
@NonNull
public ImagesPlugin defaultMediaDecoder(@Nullable MediaDecoder mediaDecoder) {
@@ -136,7 +136,7 @@ public class ImagesPlugin extends AbstractMarkwonPlugin {
}
/**
- * @since 4.0.0-SNAPSHOT
+ * @since 4.0.0
*/
@NonNull
public ImagesPlugin removeSchemeHandler(@NonNull String scheme) {
@@ -145,7 +145,7 @@ public class ImagesPlugin extends AbstractMarkwonPlugin {
}
/**
- * @since 4.0.0-SNAPSHOT
+ * @since 4.0.0
*/
@NonNull
public ImagesPlugin removeMediaDecoder(@NonNull String contentType) {
@@ -154,7 +154,7 @@ public class ImagesPlugin extends AbstractMarkwonPlugin {
}
/**
- * @since 4.0.0-SNAPSHOT
+ * @since 4.0.0
*/
@NonNull
public ImagesPlugin placeholderProvider(@NonNull PlaceholderProvider placeholderProvider) {
@@ -164,7 +164,7 @@ public class ImagesPlugin extends AbstractMarkwonPlugin {
/**
* @see ErrorHandler
- * @since 4.0.0-SNAPSHOT
+ * @since 4.0.0
*/
@NonNull
public ImagesPlugin errorHandler(@NonNull ErrorHandler errorHandler) {
diff --git a/markwon-image/src/main/java/io/noties/markwon/image/MediaDecoder.java b/markwon-image/src/main/java/io/noties/markwon/image/MediaDecoder.java
index 6b69ba03..f5f115e0 100644
--- a/markwon-image/src/main/java/io/noties/markwon/image/MediaDecoder.java
+++ b/markwon-image/src/main/java/io/noties/markwon/image/MediaDecoder.java
@@ -27,7 +27,7 @@ public abstract class MediaDecoder {
);
/**
- * @since 4.0.0-SNAPSHOT
+ * @since 4.0.0
*/
@NonNull
public abstract Collection supportedTypes();
diff --git a/markwon-image/src/main/java/io/noties/markwon/image/SchemeHandler.java b/markwon-image/src/main/java/io/noties/markwon/image/SchemeHandler.java
index 6a8ccbf1..89bd4877 100644
--- a/markwon-image/src/main/java/io/noties/markwon/image/SchemeHandler.java
+++ b/markwon-image/src/main/java/io/noties/markwon/image/SchemeHandler.java
@@ -24,7 +24,7 @@ public abstract class SchemeHandler {
public abstract ImageItem handle(@NonNull String raw, @NonNull Uri uri);
/**
- * @since 4.0.0-SNAPSHOT
+ * @since 4.0.0
*/
@NonNull
public abstract Collection supportedSchemes();
diff --git a/markwon-image/src/main/java/io/noties/markwon/image/file/FileSchemeHandler.java b/markwon-image/src/main/java/io/noties/markwon/image/file/FileSchemeHandler.java
index 43a969f5..d7da6dc5 100644
--- a/markwon-image/src/main/java/io/noties/markwon/image/file/FileSchemeHandler.java
+++ b/markwon-image/src/main/java/io/noties/markwon/image/file/FileSchemeHandler.java
@@ -40,7 +40,7 @@ public class FileSchemeHandler extends SchemeHandler {
/**
* @see #createWithAssets(AssetManager)
* @see UrlProcessorAndroidAssets
- * @since 4.0.0-SNAPSHOT
+ * @since 4.0.0
*/
@NonNull
public static FileSchemeHandler createWithAssets(@NonNull Context context) {
diff --git a/markwon-image/src/main/java/io/noties/markwon/image/gif/GifMediaDecoder.java b/markwon-image/src/main/java/io/noties/markwon/image/gif/GifMediaDecoder.java
index 479815f4..e8ac616e 100644
--- a/markwon-image/src/main/java/io/noties/markwon/image/gif/GifMediaDecoder.java
+++ b/markwon-image/src/main/java/io/noties/markwon/image/gif/GifMediaDecoder.java
@@ -26,7 +26,7 @@ public class GifMediaDecoder extends MediaDecoder {
/**
* Creates a {@link GifMediaDecoder} with {@code autoPlayGif = true}
*
- * @since 4.0.0-SNAPSHOT
+ * @since 4.0.0
*/
@NonNull
public static GifMediaDecoder create() {
@@ -43,7 +43,7 @@ public class GifMediaDecoder extends MediaDecoder {
protected GifMediaDecoder(boolean autoPlayGif) {
this.autoPlayGif = autoPlayGif;
- // @since 4.0.0-SNAPSHOT
+ // @since 4.0.0
validate();
}
diff --git a/markwon-image/src/main/java/io/noties/markwon/image/gif/GifSupport.java b/markwon-image/src/main/java/io/noties/markwon/image/gif/GifSupport.java
index 3e996d45..47624d40 100644
--- a/markwon-image/src/main/java/io/noties/markwon/image/gif/GifSupport.java
+++ b/markwon-image/src/main/java/io/noties/markwon/image/gif/GifSupport.java
@@ -1,7 +1,7 @@
package io.noties.markwon.image.gif;
/**
- * @since 4.0.0-SNAPSHOT
+ * @since 4.0.0
*/
public abstract class GifSupport {
diff --git a/markwon-image/src/main/java/io/noties/markwon/image/network/OkHttpNetworkSchemeHandler.java b/markwon-image/src/main/java/io/noties/markwon/image/network/OkHttpNetworkSchemeHandler.java
index 3d7bea00..84becb16 100644
--- a/markwon-image/src/main/java/io/noties/markwon/image/network/OkHttpNetworkSchemeHandler.java
+++ b/markwon-image/src/main/java/io/noties/markwon/image/network/OkHttpNetworkSchemeHandler.java
@@ -16,7 +16,7 @@ import okhttp3.Response;
import okhttp3.ResponseBody;
/**
- * @since 4.0.0-SNAPSHOT
+ * @since 4.0.0
*/
public class OkHttpNetworkSchemeHandler extends SchemeHandler {
@@ -35,7 +35,7 @@ public class OkHttpNetworkSchemeHandler extends SchemeHandler {
}
/**
- * @since 4.0.0-SNAPSHOT
+ * @since 4.0.0
*/
@NonNull
public static OkHttpNetworkSchemeHandler create(@NonNull Call.Factory factory) {
@@ -44,7 +44,7 @@ public class OkHttpNetworkSchemeHandler extends SchemeHandler {
private static final String HEADER_CONTENT_TYPE = "Content-Type";
- // @since 4.0.0-SNAPSHOT, previously just OkHttpClient
+ // @since 4.0.0, previously just OkHttpClient
private final Call.Factory factory;
@SuppressWarnings("WeakerAccess")
diff --git a/markwon-image/src/main/java/io/noties/markwon/image/svg/SvgMediaDecoder.java b/markwon-image/src/main/java/io/noties/markwon/image/svg/SvgMediaDecoder.java
index 848cc82e..b307a105 100644
--- a/markwon-image/src/main/java/io/noties/markwon/image/svg/SvgMediaDecoder.java
+++ b/markwon-image/src/main/java/io/noties/markwon/image/svg/SvgMediaDecoder.java
@@ -27,7 +27,7 @@ public class SvgMediaDecoder extends MediaDecoder {
/**
* @see #create(Resources)
- * @since 4.0.0-SNAPSHOT
+ * @since 4.0.0
*/
@NonNull
public static SvgMediaDecoder create() {
@@ -45,7 +45,7 @@ public class SvgMediaDecoder extends MediaDecoder {
SvgMediaDecoder(Resources resources) {
this.resources = resources;
- // @since 4.0.0-SNAPSHOT
+ // @since 4.0.0
validate();
}
diff --git a/markwon-image/src/main/java/io/noties/markwon/image/svg/SvgSupport.java b/markwon-image/src/main/java/io/noties/markwon/image/svg/SvgSupport.java
index 7ed0ce46..70293570 100644
--- a/markwon-image/src/main/java/io/noties/markwon/image/svg/SvgSupport.java
+++ b/markwon-image/src/main/java/io/noties/markwon/image/svg/SvgSupport.java
@@ -1,7 +1,7 @@
package io.noties.markwon.image.svg;
/**
- * @since 4.0.0-SNAPSHOT
+ * @since 4.0.0
*/
public abstract class SvgSupport {
diff --git a/markwon-linkify/README.md b/markwon-linkify/README.md
index e57f87ca..437ce4e4 100644
--- a/markwon-linkify/README.md
+++ b/markwon-linkify/README.md
@@ -1,9 +1,2 @@
# Linkify
-Use this module (or take a hint from it) if you would need _linkify_ capabilities. Do not
-use `TextView.setAutolinkMask` (or specify `autolink` in XML) because it will remove all
-existing links and keep only the ones it creates.
-
-Please note that usage of this plugin introduces significant performance drop due to not
-optimal implementation of underlying `android.text.util.Linkify`. If you have any ideas of how
-to improve this - PRs are welcome!
\ No newline at end of file
diff --git a/markwon-simple-ext/src/main/java/io/noties/markwon/simple/ext/SimpleExtBuilder.java b/markwon-simple-ext/src/main/java/io/noties/markwon/simple/ext/SimpleExtBuilder.java
index 10d0ed95..927ba3f0 100644
--- a/markwon-simple-ext/src/main/java/io/noties/markwon/simple/ext/SimpleExtBuilder.java
+++ b/markwon-simple-ext/src/main/java/io/noties/markwon/simple/ext/SimpleExtBuilder.java
@@ -9,7 +9,7 @@ import java.util.List;
import io.noties.markwon.SpanFactory;
-// @since 4.0.0-SNAPSHOT
+// @since 4.0.0
class SimpleExtBuilder {
private final List extensions = new ArrayList<>(2);
diff --git a/markwon-simple-ext/src/main/java/io/noties/markwon/simple/ext/SimpleExtDelimiterProcessor.java b/markwon-simple-ext/src/main/java/io/noties/markwon/simple/ext/SimpleExtDelimiterProcessor.java
index 5cde82fe..924525b0 100644
--- a/markwon-simple-ext/src/main/java/io/noties/markwon/simple/ext/SimpleExtDelimiterProcessor.java
+++ b/markwon-simple-ext/src/main/java/io/noties/markwon/simple/ext/SimpleExtDelimiterProcessor.java
@@ -9,7 +9,7 @@ import org.commonmark.parser.delimiter.DelimiterRun;
import io.noties.markwon.SpanFactory;
-// @since 4.0.0-SNAPSHOT
+// @since 4.0.0
class SimpleExtDelimiterProcessor implements DelimiterProcessor {
private final char open;
diff --git a/markwon-simple-ext/src/main/java/io/noties/markwon/simple/ext/SimpleExtNode.java b/markwon-simple-ext/src/main/java/io/noties/markwon/simple/ext/SimpleExtNode.java
index d43855e2..8d1173c3 100644
--- a/markwon-simple-ext/src/main/java/io/noties/markwon/simple/ext/SimpleExtNode.java
+++ b/markwon-simple-ext/src/main/java/io/noties/markwon/simple/ext/SimpleExtNode.java
@@ -7,7 +7,7 @@ import org.commonmark.node.Visitor;
import io.noties.markwon.SpanFactory;
-// @since 4.0.0-SNAPSHOT
+// @since 4.0.0
class SimpleExtNode extends CustomNode {
private final SpanFactory spanFactory;
diff --git a/markwon-simple-ext/src/main/java/io/noties/markwon/simple/ext/SimpleExtPlugin.java b/markwon-simple-ext/src/main/java/io/noties/markwon/simple/ext/SimpleExtPlugin.java
index 48e90359..a5d2cf8c 100644
--- a/markwon-simple-ext/src/main/java/io/noties/markwon/simple/ext/SimpleExtPlugin.java
+++ b/markwon-simple-ext/src/main/java/io/noties/markwon/simple/ext/SimpleExtPlugin.java
@@ -11,7 +11,7 @@ import io.noties.markwon.SpanFactory;
import io.noties.markwon.SpannableBuilder;
/**
- * @since 4.0.0-SNAPSHOT
+ * @since 4.0.0
*/
public class SimpleExtPlugin extends AbstractMarkwonPlugin {
diff --git a/sample/src/main/AndroidManifest.xml b/sample/src/main/AndroidManifest.xml
index 7018e3fc..5434d3f5 100644
--- a/sample/src/main/AndroidManifest.xml
+++ b/sample/src/main/AndroidManifest.xml
@@ -26,6 +26,7 @@
+
diff --git a/sample/src/main/java/io/noties/markwon/sample/MainActivity.java b/sample/src/main/java/io/noties/markwon/sample/MainActivity.java
index a27d37a9..2614b239 100644
--- a/sample/src/main/java/io/noties/markwon/sample/MainActivity.java
+++ b/sample/src/main/java/io/noties/markwon/sample/MainActivity.java
@@ -21,6 +21,7 @@ import io.noties.markwon.Markwon;
import io.noties.markwon.sample.basicplugins.BasicPluginsActivity;
import io.noties.markwon.sample.core.CoreActivity;
import io.noties.markwon.sample.customextension.CustomExtensionActivity;
+import io.noties.markwon.sample.customextension2.CustomExtensionActivity2;
import io.noties.markwon.sample.html.HtmlActivity;
import io.noties.markwon.sample.latex.LatexActivity;
import io.noties.markwon.sample.recycler.RecyclerActivity;
@@ -107,6 +108,10 @@ public class MainActivity extends Activity {
activity = SimpleExtActivity.class;
break;
+ case CUSTOM_EXTENSION_2:
+ activity = CustomExtensionActivity2.class;
+ break;
+
default:
throw new IllegalStateException("No Activity is associated with sample-item: " + item);
}
diff --git a/sample/src/main/java/io/noties/markwon/sample/Sample.java b/sample/src/main/java/io/noties/markwon/sample/Sample.java
index dbe9bc8a..e892a5ce 100644
--- a/sample/src/main/java/io/noties/markwon/sample/Sample.java
+++ b/sample/src/main/java/io/noties/markwon/sample/Sample.java
@@ -17,7 +17,9 @@ public enum Sample {
HTML(R.string.sample_html),
- SIMPLE_EXT(R.string.sample_simple_ext);
+ SIMPLE_EXT(R.string.sample_simple_ext),
+
+ CUSTOM_EXTENSION_2(R.string.sample_custom_extension_2);
private final int textResId;
diff --git a/sample/src/main/java/io/noties/markwon/sample/customextension/IconPlugin.java b/sample/src/main/java/io/noties/markwon/sample/customextension/IconPlugin.java
index e8459dd3..53c94571 100644
--- a/sample/src/main/java/io/noties/markwon/sample/customextension/IconPlugin.java
+++ b/sample/src/main/java/io/noties/markwon/sample/customextension/IconPlugin.java
@@ -22,13 +22,6 @@ public class IconPlugin extends AbstractMarkwonPlugin {
this.iconSpanProvider = iconSpanProvider;
}
-// @NonNull
-// @Override
-// public Priority priority() {
-// // define images dependency
-// return Priority.after(ImagesPlugin.class);
-// }
-
@Override
public void configureParser(@NonNull Parser.Builder builder) {
builder.customDelimiterProcessor(IconProcessor.create());
diff --git a/sample/src/main/java/io/noties/markwon/sample/customextension2/CustomExtensionActivity2.java b/sample/src/main/java/io/noties/markwon/sample/customextension2/CustomExtensionActivity2.java
new file mode 100644
index 00000000..735d6c0c
--- /dev/null
+++ b/sample/src/main/java/io/noties/markwon/sample/customextension2/CustomExtensionActivity2.java
@@ -0,0 +1,123 @@
+package io.noties.markwon.sample.customextension2;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import org.commonmark.node.Link;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import io.noties.markwon.AbstractMarkwonPlugin;
+import io.noties.markwon.Markwon;
+import io.noties.markwon.MarkwonConfiguration;
+import io.noties.markwon.MarkwonVisitor;
+import io.noties.markwon.RenderProps;
+import io.noties.markwon.SpannableBuilder;
+import io.noties.markwon.core.CorePlugin;
+import io.noties.markwon.core.CoreProps;
+import io.noties.markwon.sample.R;
+
+public class CustomExtensionActivity2 extends Activity {
+
+ @Override
+ public void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_text_view);
+
+ final TextView textView = findViewById(R.id.text_view);
+
+ // let's look for github special links:
+ // * `#1` - an issue or a pull request
+ // * `@user` link to a user
+
+ final Markwon markwon = Markwon.builder(this)
+ .usePlugin(new AbstractMarkwonPlugin() {
+ @Override
+ public void configure(@NonNull Registry registry) {
+ registry.require(CorePlugin.class, corePlugin ->
+ corePlugin.addOnTextAddedListener(new GithubLinkifyRegexTextAddedListener()));
+ }
+ })
+ .build();
+
+ final String md = "# Custom Extension 2\n" +
+ "\n" +
+ "This is an issue #1\n" +
+ "Done by @noties";
+
+ markwon.setMarkdown(textView, md);
+ }
+
+ private static class GithubLinkifyRegexTextAddedListener implements CorePlugin.OnTextAddedListener {
+
+ private static final Pattern PATTERN = Pattern.compile("((#\\d+)|(@\\w+))", Pattern.MULTILINE);
+
+ @Override
+ public void onTextAdded(@NonNull MarkwonVisitor visitor, @NonNull String text, int start) {
+
+ final Matcher matcher = PATTERN.matcher(text);
+
+ String value;
+ String url;
+ int index;
+
+ while (matcher.find()) {
+
+ value = matcher.group(1);
+
+ // detect which one it is
+ if ('#' == value.charAt(0)) {
+ url = createIssueOrPullRequestLink(value.substring(1));
+ } else {
+ url = createUserLink(value.substring(1));
+ }
+
+ // it's important to use `start` value (represents start-index of `text` in the visitor)
+ index = start + matcher.start();
+
+ setLink(visitor, url, index, index + value.length());
+ }
+ }
+
+ @NonNull
+ private String createIssueOrPullRequestLink(@NonNull String number) {
+ // issues and pull-requests on github follow the same pattern and we
+ // cannot know for sure which one it is, but if we use issues for all types,
+ // github will automatically redirect to pull-request if it's the one which is opened
+ return "https://github.com/noties/Markwon/issues/" + number;
+ }
+
+ @NonNull
+ private String createUserLink(@NonNull String user) {
+ return "https://github.com/" + user;
+ }
+
+ private void setLink(@NonNull MarkwonVisitor visitor, @NonNull String destination, int start, int end) {
+
+ // might a simpler one, but it doesn't respect possible changes to links
+// visitor.builder().setSpan(
+// new LinkSpan(visitor.configuration().theme(), destination, visitor.configuration().linkResolver()),
+// start,
+// end
+// );
+
+ // use default handlers for links
+ final MarkwonConfiguration configuration = visitor.configuration();
+ final RenderProps renderProps = visitor.renderProps();
+
+ CoreProps.LINK_DESTINATION.set(renderProps, destination);
+
+ SpannableBuilder.setSpans(
+ visitor.builder(),
+ configuration.spansFactory().require(Link.class).getSpans(configuration, renderProps),
+ start,
+ end
+ );
+ }
+ }
+}
diff --git a/sample/src/main/res/values/strings-samples.xml b/sample/src/main/res/values/strings-samples.xml
index a624f921..c1206e4b 100644
--- a/sample/src/main/res/values/strings-samples.xml
+++ b/sample/src/main/res/values/strings-samples.xml
@@ -20,4 +20,7 @@
# \# SimpleExt\n\nShows how to use SimpleExtPlugin module
to create own delimited parser extensions
+ # \# Custom extension 2\n\nAutomatically
+ convert `#1` and `@user` to Github links
+
\ No newline at end of file