Skip to content

Commit

Permalink
Merge pull request #175 from noties/v4.2.0
Browse files Browse the repository at this point in the history
V4.2.0
  • Loading branch information
noties authored Nov 15, 2019
2 parents ba22ca8 + 3917705 commit b844f4d
Show file tree
Hide file tree
Showing 84 changed files with 7,329 additions and 59 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/develop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
with:
java-version: 1.8
- name: Build with Gradle
run: ./gradlew build
run: ./gradlew build -Prelease

deploy:
needs: build
Expand Down
19 changes: 19 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,24 @@
# Changelog

# 4.2.0
* `MarkwonEditor` to highlight markdown input whilst editing (new module: `markwon-editor`)
* `CoilImagesPlugin` image loader based on [Coil] library (new module: `markwon-image-coil`) ([#166], [#174])
<br>Thanks to [@tylerbwong]
* `MarkwonInlineParser` to customize inline parsing (new module: `markwon-inline-parser`)
* Update commonmark-java to `0.13.0` (and commonmark spec `0.29`)
* `Markwon#configuration` method to expose `MarkwonConfiguration` via public API
* `HeadingSpan#getLevel` getter
* Add `SvgPictureMediaDecoder` in `image` module to deal with SVG without dimensions ([#165])
* `LinkSpan#getLink` method
* `LinkifyPlugin` applies link span that is configured by `Markwon` (obtain via span factory)
* `LinkifyPlugin` is thread-safe

[@tylerbwong]: https://github.com/tylerbwong
[Coil]: https://github.com/coil-kt/coil
[#165]: https://github.com/noties/Markwon/issues/165
[#166]: https://github.com/noties/Markwon/issues/166
[#174]: https://github.com/noties/Markwon/pull/174

# 4.1.2
* Do not re-use RenderProps when creating a new visitor (fixes [#171])

Expand Down
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ features listed in [commonmark-spec] are supported
(including support for **inlined/block HTML code**, **markdown tables**,
**images** and **syntax highlight**).

Since version **4.2.0** **Markwon** comes with an [editor](./markwon-editor/) to _highlight_ markdown input
as user types (for example in **EditText**).

[commonmark-spec]: https://spec.commonmark.org/0.28/
[commonmark-java]: https://github.com/atlassian/commonmark-java/blob/master/README.md

Expand Down
7 changes: 0 additions & 7 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,6 @@ android {
lintOptions {
abortOnError false
}

buildTypes {
debug {
minifyEnabled false
proguardFile 'proguard.pro'
}
}
}

dependencies {
Expand Down
19 changes: 10 additions & 9 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ buildscript {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.5.1'
classpath 'com.android.tools.build:gradle:3.5.2'
classpath 'com.github.ben-manes:gradle-versions-plugin:0.21.0'
}
}
Expand Down Expand Up @@ -44,7 +44,6 @@ if (hasProperty('local')) {

ext {

// NB, updating build-tools or compile-sdk will require updating Travis config (.travis.yml)
config = [
'build-tools' : '28.0.3',
'compile-sdk' : 28,
Expand All @@ -53,7 +52,7 @@ ext {
'push-aar-gradle': 'https://raw.githubusercontent.com/noties/gradle-mvn-push/master/gradle-mvn-push-aar.gradle'
]

final def commonMarkVersion = '0.12.1'
final def commonMarkVersion = '0.13.0'
final def daggerVersion = '2.10'

deps = [
Expand All @@ -72,7 +71,8 @@ ext {
'adapt' : 'io.noties:adapt:2.0.0',
'dagger' : "com.google.dagger:dagger:$daggerVersion",
'picasso' : 'com.squareup.picasso:picasso:2.71828',
'glide' : 'com.github.bumptech.glide:glide:4.9.0'
'glide' : 'com.github.bumptech.glide:glide:4.9.0',
'coil' : 'io.coil-kt:coil:0.8.0'
]

deps['annotationProcessor'] = [
Expand All @@ -81,11 +81,12 @@ ext {
]

deps['test'] = [
'junit' : 'junit:junit:4.12',
'robolectric': 'org.robolectric:robolectric:3.8',
'ix-java' : 'com.github.akarnokd:ixjava:1.0.0',
'commons-io' : 'commons-io:commons-io:2.6',
'mockito' : 'org.mockito:mockito-core:2.21.0'
'junit' : 'junit:junit:4.12',
'robolectric' : 'org.robolectric:robolectric:3.8',
'ix-java' : 'com.github.akarnokd:ixjava:1.0.0',
'commons-io' : 'commons-io:commons-io:2.6',
'mockito' : 'org.mockito:mockito-core:2.21.0',
'commonmark-test-util': "com.atlassian.commonmark:commonmark-test-util:$commonMarkVersion",
]

registerArtifact = this.&registerArtifact
Expand Down
2 changes: 1 addition & 1 deletion docs/.vuepress/.artifacts.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions docs/.vuepress/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,14 +95,17 @@ module.exports = {
'/docs/v4/core/text-setter.md'
]
},
'/docs/v4/editor/',
'/docs/v4/ext-latex/',
'/docs/v4/ext-strikethrough/',
'/docs/v4/ext-tables/',
'/docs/v4/ext-tasklist/',
'/docs/v4/html/',
'/docs/v4/image/',
'/docs/v4/image-coil/',
'/docs/v4/image-glide/',
'/docs/v4/image-picasso/',
'/docs/v4/inline-parser/',
'/docs/v4/linkify/',
'/docs/v4/recycler/',
'/docs/v4/recycler-table/',
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/.vuepress/public/assets/markwon-editor.mp4
Binary file not shown.
5 changes: 5 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ but also gives all the means to tweak the appearance if desired. All markdown fe
listed in <Link name="commonmark-spec" /> are supported (including support for **inlined/block HTML code**,
**markdown tables**, **images** and **syntax highlight**).

Since version <Badge text="4.2.0" /> **Markwon** comes with an [editor] to _highlight_ markdown input
as user types (for example in **EditText**).

[editor]: /docs/v4/editor/

## Supported markdown features

* Emphasis (`*`, `_`)
Expand Down
150 changes: 150 additions & 0 deletions docs/docs/v4/editor/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
# Editor <Badge text="4.2.0" />

<MavenBadge4 :artifact="'editor'" />

Markdown editing highlight for Android based on **Markwon**.

<style>
video {
max-height: 82vh;
}
</style>

<video controls="true" loop="" :poster="$withBase('/assets/markwon-editor-preview.jpg')">
<source :src="$withBase('/assets/markwon-editor.mp4')" type="video/mp4">
You browser does not support mp4 playback, try downloading video file
<a :href="$withBase('/assets/markwon-editor.mp4')">directly</a>
</video>

## Getting started with editor

```java
// obtain Markwon instance
final Markwon markwon = Markwon.create(this);

// create editor
final MarkwonEditor editor = MarkwonEditor.create(markwon);

// set edit listener
editText.addTextChangedListener(MarkwonEditorTextWatcher.withProcess(editor));
```

The code above _highlights_ in-place which is OK for relatively small markdown inputs.
If you wish to offload main thread and highlight in background use `withPreRender`
`MarkwonEditorTextWatcher`:

```java
editText.addTextChangedListener(MarkwonEditorTextWatcher.withPreRender(
editor,
Executors.newCachedThreadPool(),
editText));
```

`MarkwonEditorTextWatcher` automatically triggers markdown highlight when text in `EditText` changes.
But you still can invoke `MarkwonEditor` manually:

```java
editor.process(editText.getText());

// please note that MarkwonEditor operates on caller thread,
// if you wish to execute this operation in background - this method
// must be called from background thread
editor.preRender(editText.getText(), new MarkwonEditor.PreRenderResultListener() {
@Override
public void onPreRenderResult(@NonNull MarkwonEditor.PreRenderResult result) {
// it's wise to check if rendered result is for the same input,
// for example by matching raw input
if (editText.getText().toString().equals(result.resultEditable().toString())) {

// if you are in background thread do not forget
// to execute dispatch in main thread
result.dispatchTo(editText.getText());
}
}
});
```

:::warning Implementation Detail
It must be mentioned that highlight is implemented via text diff. Everything
that is present in raw markdown input but missing from rendered result is considered
to be _punctuation_.
:::

:::danger Tables and LaTeX
Tables and LaTeX nodes won't be rendered correctly. They will be treated as _punctuation_
as whole. This comes from their implementation - they are _mocked_ and do not present
in final result as text and thus cannot be _diffed_.
:::

## Custom punctuation span

By default `MarkwonEditor` uses lighter text color of widget to customize punctuation.
If you wish to use a different span you can use `punctuationSpan` configuration step:

```java
final MarkwonEditor editor = MarkwonEditor.builder(Markwon.create(this))
.punctuationSpan(CustomPunctuationSpan.class, CustomPunctuationSpan::new)
.build();
```

```java
public class CustomPunctuationSpan extends ForegroundColorSpan {
CustomPunctuationSpan() {
super(0xFFFF0000); // RED
}
}
```

## Additional handling

In order to additionally highlight portions of markdown input (for example make text wrapped with `**`
symbols **bold**) `EditHandler` can be used:

```java
final MarkwonEditor editor = MarkwonEditor.builder(Markwon.create(this))
.useEditHandler(new AbstractEditHandler<StrongEmphasisSpan>() {
@Override
public void configurePersistedSpans(@NonNull PersistedSpans.Builder builder) {
// Here we define which span is _persisted_ in EditText, it is not removed
// from EditText between text changes, but instead - reused (by changing
// position). Consider it as a cache for spans. We could use `StrongEmphasisSpan`
// here also, but I chose Bold to indicate that this span is not the same
// as in off-screen rendered markdown
builder.persistSpan(Bold.class, Bold::new);
}

@Override
public void handleMarkdownSpan(
@NonNull PersistedSpans persistedSpans,
@NonNull Editable editable,
@NonNull String input,
@NonNull StrongEmphasisSpan span,
int spanStart,
int spanTextLength) {
// Unfortunately we cannot hardcode delimiters length here (aka spanTextLength + 4)
// because multiple inline markdown nodes can refer to the same text.
// For example, `**_~~hey~~_**` - we will receive `**_~~` in this method,
// and thus will have to manually find actual position in raw user input
final MarkwonEditorUtils.Match match =
MarkwonEditorUtils.findDelimited(input, spanStart, "**", "__");
if (match != null) {
editable.setSpan(
// we handle StrongEmphasisSpan and represent it with Bold in EditText
// we still could use StrongEmphasisSpan, but it must be accessed
// via persistedSpans
persistedSpans.get(Bold.class),
match.start(),
match.end(),
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
);
}
}

@NonNull
@Override
public Class<StrongEmphasisSpan> markdownSpanType() {
return StrongEmphasisSpan.class;
}
})
.build();
```
35 changes: 35 additions & 0 deletions docs/docs/v4/image-coil/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Image Coil

<MavenBadge4 :artifact="'image-coil'" />

Image loading based on `Coil` library

```kotlin
val markwon = Markwon.builder(context)
// automatically create Coil instance
.usePlugin(CoilImagesPlugin.create(context))
// use supplied ImageLoader instance
.usePlugin(CoilImagesPlugin.create(
context,
ImageLoader(context) {
availableMemoryPercentage(0.5)
bitmapPoolPercentage(0.5)
crossfade(true)
}
))
// if you need more control
.usePlugin(CoilImagesPlugin.create(object : CoilImagesPlugin.CoilStore {
override fun load(drawable: AsyncDrawable): LoadRequest {
return LoadRequest(context, customImageLoader.defaults) {
data(drawable.destination)
crossfade(true)
transformations(CircleCropTransformation())
}
}

override cancel(disposable: RequestDisposable) {
disposable.dispose()
}
}, customImageLoader))
.build()
```
Loading

0 comments on commit b844f4d

Please sign in to comment.