diff --git a/CHANGELOG.md b/CHANGELOG.md index 5f805716..1f267a59 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,9 +1,40 @@ # Changelog -# 3.0.2 +# 4.0.0 +* maven group-id change to `io.noties.markwon` (was `ru.noties.markwon`) +* package name change to `io.notier.markwon.*` (was `ru.noties.markwon.*`) +* androidx artifacts (#76) +* `Markwon#builder` does not require explicit `CorePlugin` (added automatically), +use `Markwon#builderNoCore()` to obtain a builder without `CorePlugin` +* Removed `Priority` abstraction and `MarkwonPlugin#priority` (use `MarkwonPlugin.Registry`) +* Removed `MarkwonPlugin#configureHtmlRenderer` (for configuration use `HtmlPlugin` directly) +* Removed `MarkwonPlugin#configureImages` (for configuration use `ImagesPlugin` directly) +* Added `MarkwonPlugin.Registry` and `MarkwonPlugin#configure(Registry)` method +* `CorePlugin#addOnTextAddedListener` (process raw text added) +* `ImageSizeResolver` signature change (accept `AsyncDrawable`) +* `LinkResolver` is now an independent entity (previously part of `LinkSpan`) +* `AsyncDrawableScheduler` can now be called multiple times without performance penalty +* `AsyncDrawable` now exposes its destination, image-size, last known dimensions (canvas, text-size) +* `AsyncDrawableLoader` signature change (accept `AsyncDrawable`) +* Add `LastLineSpacingSpan` +* Add `MarkwonConfiguration.Builder#asyncDrawableLoader` method +* `ImagesPlugin` removed from `core` artifact +(also removed `images-gif`, `images-okhttp` and `images-svg` artifacts and their plugins) +* `ImagesPlugin` exposes configuration (adding scheme-handler, media-decoder, etc) +* `ImagesPlugin` allows multiple images with the same source (URL) +* Add `PlaceholderProvider` and `ErrorHandler` to `ImagesPlugin` +* `GIF` and `SVG` media-decoders are automatically added to `ImagesPlugin` if required libraries are found in the classpath +* `ImageItem` is now abstract, has 2 implementations: `withResult`, `withDecodingNeeded` +* Add `images-glide`, `images-picasso`, `linkify`, `simple-ext` modules +* `JLatexMathPlugin` is now independent of `ImagesPlugin` +* Fix wrong `JLatexMathPlugin` formulas sizes (#138) +* `JLatexMathPlugin` has `backgroundProvider`, `executorService` configuration +* `HtmlPlugin` is self-contained (all configuration is moved in the plugin itself) + +## 3.0.2 * Fix `latex` plugin (#136) * Add `#create(Call.Factory)` factory method to `OkHttpImagesPlugin` (#129) - thanks to @ZacSweers +
Thanks to @ZacSweers ## 3.0.1 * Add `AsyncDrawableLoader.Builder#implementation` method (#109) @@ -64,7 +95,7 @@ to get the full picture of latest changes. * Add SpannableBuilder#getSpans method * Fix DataUri scheme handler in image-loader (#74) * Introduced a "copy" builder for SpannableThem - Thanks @c-b-h +
Thanks @c-b-h ## 2.0.0 * Add `html-parser-api` and `html-parser-impl` modules @@ -90,7 +121,7 @@ to get the full picture of latest changes. * Fix OrderedListItemSpan text position (baseline) (#55) * Add softBreakAddsNewLine option for SpannableConfiguration (#54) * Paragraph text can now explicitly be spanned (#58) - Thanks to @c-b-h +
Thanks to @c-b-h * Fix table border color if odd background is specified (#56) * Add table customizations (even and header rows) @@ -98,10 +129,10 @@ to get the full picture of latest changes. * Update commonmark to 0.11.0 and android-gif to 1.2.14 * Add syntax highlight functionality (`library-syntax` module and `markwon-syntax` artifact) * Add headingTypeface, headingTextSizes to SpannableTheme - Thanks to @edenman +
Thanks to @edenman * Introduce `MediaDecoder` abstraction to `image-loader` module * Introduce `SpannableFactory` - Thanks for idea to @c-b-h +
Thanks for idea to @c-b-h * Update sample application to use syntax-highlight * Update sample application to use clickable placeholder for GIF media @@ -116,12 +147,12 @@ to `ru.noties.markwon.renderer` package (one level up, previously `ru.noties.mar * Change LinkSpan to extend URLSpan. Allow default linkColor (if not set explicitly) * Fit an image without dimensions to canvas width (and keep ratio) * Add support for separate color for code blocks (#37) - Thanks to @Arcnor +
Thanks to @Arcnor ## v1.0.4 * Fixes #28 (tables are not rendered when at the end of the markdown) * Adds support for `indented code blocks` - Thanks to @dlew +
Thanks to @dlew ## v1.0.3 * Fixed ordered lists (when number width is greater than block margin) diff --git a/README.md b/README.md index ddfd65dd..999f7e8c 100644 --- a/README.md +++ b/README.md @@ -35,13 +35,14 @@ features listed in [commonmark-spec] are supported implementation "io.noties.markwon:core:${markwonVersion}" ``` -Full list of available artifacts is present in the [install section](https://noties.github.io/Markwon/docs/v3/install.html) +Full list of available artifacts is present in the [install section](https://noties.github.io/Markwon/docs/v4/install.html) of the [documentation] web-site. Please visit [documentation] web-site for further reference. -> You can find previous version of Markwon in [2.x.x](https://github.com/noties/Markwon/tree/2.x.x) branch +> You can find previous version of Markwon in [2.x.x](https://github.com/noties/Markwon/tree/2.x.x) +and [3.x.x](https://github.com/noties/Markwon/tree/3.x.x) branches ## Supported markdown features: diff --git a/_CHANGES.md b/_CHANGES.md deleted file mode 100644 index 3cd3b21a..00000000 --- a/_CHANGES.md +++ /dev/null @@ -1,16 +0,0 @@ -* `Markwon.builder` won't require CorePlugin registration (it is done automatically) - to create a builder without CorePlugin - use `Markwon#builderNoCore` -* `JLatex` plugin now is not dependent on ImagesPlugin - also accepts a ExecutorService (optional, by default cachedThreadPool is used) -* AsyncDrawableScheduler now can be called by multiple plugins without penalty - internally caches latest state and skips scheduling if drawables are already processed -* configure with registry -* removed priority -* images-plugin moved to standalone again -* removed MarkwonPlugin#configureHtmlRenderer -> now part of HtmlPlugin -* TagHandler now has `supportedTags()` method -* html is moved completely to html-plugin -* OnTextAddedListener (CorePlugin) -* ImageSizeResolver signature change (accept AsyncDrawable) -* JLatexMathPlugin builder has vertical & horizontal padding -* LinkResolver is now an independent entity (previously part of LinkSpan) \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index c17e0fa6..33d7c8cd 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -34,7 +34,6 @@ dependencies { implementation project(':markwon-ext-tasklist') implementation project(':markwon-html') implementation project(':markwon-image') - implementation project(':markwon-linkify') implementation project(':markwon-syntax-highlight') deps.with { diff --git a/docs/docs/v4/image-glide/README.md b/docs/docs/v4/image-glide/README.md index 5d733b87..d8b361c6 100644 --- a/docs/docs/v4/image-glide/README.md +++ b/docs/docs/v4/image-glide/README.md @@ -1,3 +1,27 @@ # Image Glide - \ No newline at end of file + + +Image loading based on `Glide` library + +```java +final Markwon markwon = Markwon.builder(context) + // automatically create Glide instance + .usePlugin(GlideImagesPlugin.create(context)) + // use supplied Glide instance + .usePlugin(GlideImagesPlugin.create(Glide.with(context))) + // if you need more control + .usePlugin(GlideImagesPlugin.create(new GlideImagesPlugin.GlideStore() { + @NonNull + @Override + public RequestBuilder 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