V1.0.6 (#46)
* Fix bullet list item size (depend on text size and not top-bottom arguments) * Add SNAPSHOT publishing * Add ability to specify MovementMethod when applying markdown to a TextView * Add information about new method signature to README (Markwon.setText) * Fix README links reference * Add new section to README (applications using markwon) * Markdown images size is also resolved via ImageSizeResolver
This commit is contained in:
parent
ddb8989669
commit
cb66618d3a
39
README.md
39
README.md
@ -12,11 +12,34 @@
|
|||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
```groovy
|
```groovy
|
||||||
compile 'ru.noties:markwon:1.0.5'
|
compile 'ru.noties:markwon:1.0.6'
|
||||||
compile 'ru.noties:markwon-image-loader:1.0.5' // optional
|
compile 'ru.noties:markwon-image-loader:1.0.6' // optional
|
||||||
compile 'ru.noties:markwon-view:1.0.5' // optional
|
compile 'ru.noties:markwon-view:1.0.6' // optional
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Snapshot
|
||||||
|

|
||||||
|
|
||||||
|
In order to use latest `SNAPSHOT` version add snapshot repository to your root project's `build.gradle` file:
|
||||||
|
|
||||||
|
```groovy
|
||||||
|
allprojects {
|
||||||
|
repositories {
|
||||||
|
jcenter()
|
||||||
|
google()
|
||||||
|
maven { url 'https://oss.sonatype.org/content/repositories/snapshots/' }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
and then in your module `build.gradle`:
|
||||||
|
|
||||||
|
```groovy
|
||||||
|
implementation 'ru.noties:markwon:1.0.6-SNAPSHOT'
|
||||||
|
```
|
||||||
|
|
||||||
|
Please note that `markwon-image-loader` and `markwon-view` are also present in `SNAPSHOT` repository and share the same version as main `markwon` artifact.
|
||||||
|
|
||||||
## Supported markdown features:
|
## Supported markdown features:
|
||||||
* Emphasis (`*`, `_`)
|
* Emphasis (`*`, `_`)
|
||||||
* Strong emphasis (`**`, `__`)
|
* Strong emphasis (`**`, `__`)
|
||||||
@ -111,6 +134,11 @@ Markwon.scheduleDrawables(textView);
|
|||||||
Markwon.scheduleTableRows(textView);
|
Markwon.scheduleTableRows(textView);
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Please note that if you are having trouble with `LinkMovementMethod` you can use
|
||||||
|
`Markwon.setText(textView, markdown, movementMethod)` method (`@since 1.0.6`) to specify _no_ movement
|
||||||
|
method (aka `null`) or own implementation. As an alternative to the system `LinkMovementMethod`
|
||||||
|
you can use [Better-Link-Movement-Method][better-link-movement-method].
|
||||||
|
|
||||||
Please refer to [SpannableConfiguration] document for more info
|
Please refer to [SpannableConfiguration] document for more info
|
||||||
|
|
||||||
---
|
---
|
||||||
@ -269,6 +297,10 @@ Underscores (`_`)
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## Applications using Markwon
|
||||||
|
|
||||||
|
* [FairNote Notepad](https://play.google.com/store/apps/details?id=com.rgiskard.fairnote)
|
||||||
|
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
@ -292,6 +324,7 @@ Underscores (`_`)
|
|||||||
[commonmark-java]: https://github.com/atlassian/commonmark-java/blob/master/README.md
|
[commonmark-java]: https://github.com/atlassian/commonmark-java/blob/master/README.md
|
||||||
[cheatsheet]: https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet
|
[cheatsheet]: https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet
|
||||||
[SpannableConfiguration]: ./docs/SpannableConfiguration.md
|
[SpannableConfiguration]: ./docs/SpannableConfiguration.md
|
||||||
|
[better-link-movement-method]: https://github.com/saket/Better-Link-Movement-Method
|
||||||
|
|
||||||
[arbitrary case-insensitive reference text]: https://www.mozilla.org
|
[arbitrary case-insensitive reference text]: https://www.mozilla.org
|
||||||
[1]: http://slashdot.org
|
[1]: http://slashdot.org
|
||||||
|
@ -31,6 +31,7 @@ dependencies {
|
|||||||
implementation project(':library-image-loader')
|
implementation project(':library-image-loader')
|
||||||
|
|
||||||
implementation 'ru.noties:debug:3.0.0@jar'
|
implementation 'ru.noties:debug:3.0.0@jar'
|
||||||
|
implementation 'me.saket:better-link-movement-method:2.2.0'
|
||||||
|
|
||||||
implementation OK_HTTP
|
implementation OK_HTTP
|
||||||
|
|
||||||
|
@ -4,11 +4,14 @@ import android.app.Activity;
|
|||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import me.saket.bettermovementmethod.BetterLinkMovementMethod;
|
||||||
import ru.noties.debug.Debug;
|
import ru.noties.debug.Debug;
|
||||||
|
|
||||||
public class MainActivity extends Activity {
|
public class MainActivity extends Activity {
|
||||||
@ -64,7 +67,7 @@ public class MainActivity extends Activity {
|
|||||||
markdownRenderer.render(MainActivity.this, uri(), text, new MarkdownRenderer.MarkdownReadyListener() {
|
markdownRenderer.render(MainActivity.this, uri(), text, new MarkdownRenderer.MarkdownReadyListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onMarkdownReady(CharSequence markdown) {
|
public void onMarkdownReady(CharSequence markdown) {
|
||||||
Markwon.setText(textView, markdown);
|
Markwon.setText(textView, markdown, BetterLinkMovementMethod.getInstance());
|
||||||
Views.setVisible(progress, false);
|
Views.setVisible(progress, false);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -72,6 +75,7 @@ public class MainActivity extends Activity {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
private AppBarItem.State appBarState() {
|
private AppBarItem.State appBarState() {
|
||||||
|
|
||||||
final String title;
|
final String title;
|
||||||
@ -100,6 +104,7 @@ public class MainActivity extends Activity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
private Uri uri() {
|
private Uri uri() {
|
||||||
final Intent intent = getIntent();
|
final Intent intent = getIntent();
|
||||||
return intent != null
|
return intent != null
|
||||||
|
@ -6,7 +6,7 @@ org.gradle.configureondemand=true
|
|||||||
android.enableBuildCache=true
|
android.enableBuildCache=true
|
||||||
android.buildCacheDir=build/pre-dex-cache
|
android.buildCacheDir=build/pre-dex-cache
|
||||||
|
|
||||||
VERSION_NAME=1.0.5
|
VERSION_NAME=1.0.6
|
||||||
|
|
||||||
GROUP=ru.noties
|
GROUP=ru.noties
|
||||||
POM_DESCRIPTION=Markwon
|
POM_DESCRIPTION=Markwon
|
||||||
|
@ -2,7 +2,9 @@ package ru.noties.markwon;
|
|||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
import android.text.method.LinkMovementMethod;
|
import android.text.method.LinkMovementMethod;
|
||||||
|
import android.text.method.MovementMethod;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import org.commonmark.ext.gfm.strikethrough.StrikethroughExtension;
|
import org.commonmark.ext.gfm.strikethrough.StrikethroughExtension;
|
||||||
@ -67,20 +69,39 @@ public abstract class Markwon {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper method to apply parsed markdown.
|
* Helper method to apply parsed markdown.
|
||||||
|
* <p>
|
||||||
|
* Since 1.0.6 redirects it\'s call to {@link #setText(TextView, CharSequence, MovementMethod)}
|
||||||
|
* with LinkMovementMethod as an argument to preserve current API.
|
||||||
*
|
*
|
||||||
* @param view {@link TextView} to set markdown into
|
* @param view {@link TextView} to set markdown into
|
||||||
* @param text parsed markdown
|
* @param text parsed markdown
|
||||||
* @see #scheduleDrawables(TextView)
|
* @see #setText(TextView, CharSequence, MovementMethod)
|
||||||
* @see #scheduleTableRows(TextView)
|
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
public static void setText(@NonNull TextView view, CharSequence text) {
|
public static void setText(@NonNull TextView view, CharSequence text) {
|
||||||
|
setText(view, text, LinkMovementMethod.getInstance());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper method to apply parsed markdown with additional argument of a MovementMethod. Used
|
||||||
|
* to workaround problems that occur when using system LinkMovementMethod (for example:
|
||||||
|
* https://issuetracker.google.com/issues/37068143). As a better alternative to it consider
|
||||||
|
* using: https://github.com/saket/Better-Link-Movement-Method
|
||||||
|
*
|
||||||
|
* @param view TextView to set markdown into
|
||||||
|
* @param text parsed markdown
|
||||||
|
* @param movementMethod an implementation if MovementMethod or null
|
||||||
|
* @see #scheduleDrawables(TextView)
|
||||||
|
* @see #scheduleTableRows(TextView)
|
||||||
|
* @since 1.0.6
|
||||||
|
*/
|
||||||
|
public static void setText(@NonNull TextView view, CharSequence text, @Nullable MovementMethod movementMethod) {
|
||||||
|
|
||||||
unscheduleDrawables(view);
|
unscheduleDrawables(view);
|
||||||
unscheduleTableRows(view);
|
unscheduleTableRows(view);
|
||||||
|
|
||||||
// update movement method (for links to be clickable)
|
// update movement method (for links to be clickable)
|
||||||
view.setMovementMethod(LinkMovementMethod.getInstance());
|
view.setMovementMethod(movementMethod);
|
||||||
view.setText(text);
|
view.setText(text);
|
||||||
|
|
||||||
// schedule drawables (dynamic drawables that can change bounds/animate will be correctly updated)
|
// schedule drawables (dynamic drawables that can change bounds/animate will be correctly updated)
|
||||||
|
@ -3,8 +3,8 @@ package ru.noties.markwon;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
|
|
||||||
import ru.noties.markwon.renderer.html.ImageSizeResolver;
|
import ru.noties.markwon.renderer.ImageSizeResolver;
|
||||||
import ru.noties.markwon.renderer.html.ImageSizeResolverDef;
|
import ru.noties.markwon.renderer.ImageSizeResolverDef;
|
||||||
import ru.noties.markwon.renderer.html.SpannableHtmlParser;
|
import ru.noties.markwon.renderer.html.SpannableHtmlParser;
|
||||||
import ru.noties.markwon.spans.AsyncDrawable;
|
import ru.noties.markwon.spans.AsyncDrawable;
|
||||||
import ru.noties.markwon.spans.LinkSpan;
|
import ru.noties.markwon.spans.LinkSpan;
|
||||||
@ -30,6 +30,7 @@ public class SpannableConfiguration {
|
|||||||
private final LinkSpan.Resolver linkResolver;
|
private final LinkSpan.Resolver linkResolver;
|
||||||
private final UrlProcessor urlProcessor;
|
private final UrlProcessor urlProcessor;
|
||||||
private final SpannableHtmlParser htmlParser;
|
private final SpannableHtmlParser htmlParser;
|
||||||
|
private final ImageSizeResolver imageSizeResolver;
|
||||||
|
|
||||||
private SpannableConfiguration(@NonNull Builder builder) {
|
private SpannableConfiguration(@NonNull Builder builder) {
|
||||||
this.theme = builder.theme;
|
this.theme = builder.theme;
|
||||||
@ -38,6 +39,7 @@ public class SpannableConfiguration {
|
|||||||
this.linkResolver = builder.linkResolver;
|
this.linkResolver = builder.linkResolver;
|
||||||
this.urlProcessor = builder.urlProcessor;
|
this.urlProcessor = builder.urlProcessor;
|
||||||
this.htmlParser = builder.htmlParser;
|
this.htmlParser = builder.htmlParser;
|
||||||
|
this.imageSizeResolver = builder.imageSizeResolver;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
@ -70,6 +72,11 @@ public class SpannableConfiguration {
|
|||||||
return htmlParser;
|
return htmlParser;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
public ImageSizeResolver imageSizeResolver() {
|
||||||
|
return imageSizeResolver;
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public static class Builder {
|
public static class Builder {
|
||||||
|
|
||||||
@ -154,12 +161,11 @@ public class SpannableConfiguration {
|
|||||||
urlProcessor = new UrlProcessorNoOp();
|
urlProcessor = new UrlProcessorNoOp();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (imageSizeResolver == null) {
|
||||||
|
imageSizeResolver = new ImageSizeResolverDef();
|
||||||
|
}
|
||||||
|
|
||||||
if (htmlParser == null) {
|
if (htmlParser == null) {
|
||||||
|
|
||||||
if (imageSizeResolver == null) {
|
|
||||||
imageSizeResolver = new ImageSizeResolverDef();
|
|
||||||
}
|
|
||||||
|
|
||||||
htmlParser = SpannableHtmlParser.create(theme, asyncDrawableLoader, urlProcessor, linkResolver, imageSizeResolver);
|
htmlParser = SpannableHtmlParser.create(theme, asyncDrawableLoader, urlProcessor, linkResolver, imageSizeResolver);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package ru.noties.markwon.renderer.html;
|
package ru.noties.markwon.renderer;
|
||||||
|
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
|
|
||||||
@ -34,4 +34,12 @@ public class ImageSize {
|
|||||||
this.width = width;
|
this.width = width;
|
||||||
this.height = height;
|
this.height = height;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "ImageSize{" +
|
||||||
|
"width=" + width +
|
||||||
|
", height=" + height +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package ru.noties.markwon.renderer.html;
|
package ru.noties.markwon.renderer;
|
||||||
|
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
@ -1,4 +1,4 @@
|
|||||||
package ru.noties.markwon.renderer.html;
|
package ru.noties.markwon.renderer;
|
||||||
|
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
@ -438,7 +438,9 @@ public class SpannableMarkdownVisitor extends AbstractVisitor {
|
|||||||
configuration.theme(),
|
configuration.theme(),
|
||||||
new AsyncDrawable(
|
new AsyncDrawable(
|
||||||
destination,
|
destination,
|
||||||
configuration.asyncDrawableLoader()
|
configuration.asyncDrawableLoader(),
|
||||||
|
configuration.imageSizeResolver(),
|
||||||
|
null
|
||||||
),
|
),
|
||||||
AsyncDrawableSpan.ALIGN_BOTTOM,
|
AsyncDrawableSpan.ALIGN_BOTTOM,
|
||||||
link
|
link
|
||||||
|
@ -11,6 +11,8 @@ import java.util.HashMap;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import ru.noties.markwon.UrlProcessor;
|
import ru.noties.markwon.UrlProcessor;
|
||||||
|
import ru.noties.markwon.renderer.ImageSize;
|
||||||
|
import ru.noties.markwon.renderer.ImageSizeResolver;
|
||||||
import ru.noties.markwon.spans.AsyncDrawable;
|
import ru.noties.markwon.spans.AsyncDrawable;
|
||||||
import ru.noties.markwon.spans.AsyncDrawableSpan;
|
import ru.noties.markwon.spans.AsyncDrawableSpan;
|
||||||
import ru.noties.markwon.spans.SpannableTheme;
|
import ru.noties.markwon.spans.SpannableTheme;
|
||||||
|
@ -13,6 +13,8 @@ import java.util.Map;
|
|||||||
import ru.noties.markwon.LinkResolverDef;
|
import ru.noties.markwon.LinkResolverDef;
|
||||||
import ru.noties.markwon.UrlProcessor;
|
import ru.noties.markwon.UrlProcessor;
|
||||||
import ru.noties.markwon.UrlProcessorNoOp;
|
import ru.noties.markwon.UrlProcessorNoOp;
|
||||||
|
import ru.noties.markwon.renderer.ImageSizeResolver;
|
||||||
|
import ru.noties.markwon.renderer.ImageSizeResolverDef;
|
||||||
import ru.noties.markwon.spans.AsyncDrawable;
|
import ru.noties.markwon.spans.AsyncDrawable;
|
||||||
import ru.noties.markwon.spans.LinkSpan;
|
import ru.noties.markwon.spans.LinkSpan;
|
||||||
import ru.noties.markwon.spans.SpannableTheme;
|
import ru.noties.markwon.spans.SpannableTheme;
|
||||||
|
@ -10,8 +10,8 @@ import android.support.annotation.IntRange;
|
|||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
|
|
||||||
import ru.noties.markwon.renderer.html.ImageSize;
|
import ru.noties.markwon.renderer.ImageSize;
|
||||||
import ru.noties.markwon.renderer.html.ImageSizeResolver;
|
import ru.noties.markwon.renderer.ImageSizeResolver;
|
||||||
|
|
||||||
public class AsyncDrawable extends Drawable {
|
public class AsyncDrawable extends Drawable {
|
||||||
|
|
||||||
@ -33,6 +33,10 @@ public class AsyncDrawable extends Drawable {
|
|||||||
private int canvasWidth;
|
private int canvasWidth;
|
||||||
private float textSize;
|
private float textSize;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated 1.0.6 markdown images are also processed with {@link ImageSizeResolver}
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
public AsyncDrawable(@NonNull String destination, @NonNull Loader loader) {
|
public AsyncDrawable(@NonNull String destination, @NonNull Loader loader) {
|
||||||
this(destination, loader, null, null);
|
this(destination, loader, null, null);
|
||||||
}
|
}
|
||||||
@ -176,8 +180,7 @@ public class AsyncDrawable extends Drawable {
|
|||||||
|
|
||||||
final Rect rect;
|
final Rect rect;
|
||||||
|
|
||||||
if (imageSizeResolver == null
|
if (imageSizeResolver == null) {
|
||||||
|| imageSize == null) {
|
|
||||||
|
|
||||||
// @since 1.0.5
|
// @since 1.0.5
|
||||||
final Rect bounds = result.getBounds();
|
final Rect bounds = result.getBounds();
|
||||||
|
@ -48,12 +48,15 @@ public class BulletListItemSpan implements LeadingMarginSpan {
|
|||||||
try {
|
try {
|
||||||
|
|
||||||
final int width = theme.getBlockMargin();
|
final int width = theme.getBlockMargin();
|
||||||
final int height = bottom - top;
|
|
||||||
|
|
||||||
final int side = theme.getBulletWidth(bottom - top);
|
// @since 1.0.6 we no longer rely on (bottom-top) calculation in order to detect line height
|
||||||
|
// it lead to bad rendering as first & last lines received different results even
|
||||||
|
// if text size is the same (first line received greater amount and bottom line -> less)
|
||||||
|
final int textLineHeight = (int) (paint.descent() - paint.ascent() + .5F);
|
||||||
|
|
||||||
|
final int side = theme.getBulletWidth(textLineHeight);
|
||||||
|
|
||||||
final int marginLeft = (width - side) / 2;
|
final int marginLeft = (width - side) / 2;
|
||||||
final int marginTop = (height - side) / 2;
|
|
||||||
|
|
||||||
// in order to support RTL
|
// in order to support RTL
|
||||||
final int l;
|
final int l;
|
||||||
@ -64,7 +67,8 @@ public class BulletListItemSpan implements LeadingMarginSpan {
|
|||||||
l = Math.min(left, right);
|
l = Math.min(left, right);
|
||||||
r = Math.max(left, right);
|
r = Math.max(left, right);
|
||||||
}
|
}
|
||||||
final int t = top + marginTop;
|
|
||||||
|
final int t = baseline + (int) ((paint.descent() + paint.ascent()) / 2.F + .5F) - (side / 2);
|
||||||
final int b = t + side;
|
final int b = t + side;
|
||||||
|
|
||||||
if (level == 0
|
if (level == 0
|
||||||
|
Loading…
x
Reference in New Issue
Block a user