Implicit LinkMovementMethod if not supplied explicitly

This commit is contained in:
Dimitry Ivanov 2019-01-13 16:57:16 +03:00
parent ba5bb9bfc7
commit 02e7539881
9 changed files with 112 additions and 131 deletions

View File

@ -7,7 +7,6 @@ import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.text.Spanned;
import android.text.method.LinkMovementMethod;
import android.view.View;
import android.widget.TextView;
@ -59,8 +58,6 @@ public class MainActivity extends Activity {
appBarRenderer.render(appBarState());
textView.setMovementMethod(LinkMovementMethod.getInstance());
markdownLoader.load(uri(), new MarkdownLoader.OnMarkdownTextLoaded() {
@Override
public void apply(final String text) {

View File

@ -1,5 +1,8 @@
<template>
<a :href="linkHref()" target="_blank" rel="noopener noreferrer">{{linkText()}}<OutboundLink/></a>
<a :href="linkHref()" target="_blank" rel="noopener noreferrer">
{{linkText()}}
<OutboundLink/>
</a>
</template>
<script>
@ -9,34 +12,36 @@ var map = {
href: "https://spec.commonmark.org/0.28/"
},
"commonmark-spec#inline": {
href: "https://spec.commonmark.org/0.28/#raw-html"
href: "https://spec.commonmark.org/0.28/#raw-html"
},
"commonmark-spec#block": {
href: "https://spec.commonmark.org/0.28/#html-blocks"
href: "https://spec.commonmark.org/0.28/#html-blocks"
},
"commonmark-spec#soft-break": {
href: "https://spec.commonmark.org/0.28/#soft-line-breaks"
href: "https://spec.commonmark.org/0.28/#soft-line-breaks"
},
"commonmark-dingus": {
displayName: "commonmark dingus",
href: "https://spec.commonmark.org/dingus/"
displayName: "commonmark dingus",
href: "https://spec.commonmark.org/dingus/"
},
"html-inlines": {
href: "https://developer.mozilla.org/en-US/docs/Web/HTML/Inline_elements"
href: "https://developer.mozilla.org/en-US/docs/Web/HTML/Inline_elements"
},
"html-blocks": {
href: "https://developer.mozilla.org/en-US/docs/Web/HTML/Block-level_elements"
href:
"https://developer.mozilla.org/en-US/docs/Web/HTML/Block-level_elements"
},
"jsoup": {
displayName: "Jsoup",
href: "https://github.com/jhy/jsoup/"
jsoup: {
displayName: "Jsoup",
href: "https://github.com/jhy/jsoup/"
},
"markwon-jsoup": {
href: "https://github.com/noties/Markwon/tree/master/markwon-html-parser-impl/src/main/java/ru/noties/markwon/html/impl/jsoup"
href:
"https://github.com/noties/Markwon/tree/master/markwon-html-parser-impl/src/main/java/ru/noties/markwon/html/impl/jsoup"
},
"commonmark-java": {
href: "https://github.com/atlassian/commonmark-java/",
displayName: "commonmark-java"
href: "https://github.com/atlassian/commonmark-java/",
displayName: "commonmark-java"
}
};
@ -48,7 +53,7 @@ export default {
return this.href || map[this.name].href;
},
linkText: function() {
return this.displayName || map[this.name].displayName;
return this.displayName || map[this.name].displayName;
}
}
};

View File

@ -37,7 +37,7 @@ module.exports = {
'/docs/core/theme.md'
]
},
'/docs/ext-latex/latex.md',
'/docs/ext-latex/',
'/docs/ext-strikethrough/strikethrough.md',
'/docs/ext-tables/tables.md',
'/docs/ext-tasklist/tasklist.md',

View File

@ -10,20 +10,27 @@ to learn how to add `Markwon` to your project
This is the most simple way to set markdown to a `TextView` or any of its siblings:
```java
Markwon.setMarkdown(textView, "**Hello there!**");
// obtain an instance of Markwon
final Markwon markwon = Markwon.create(context);
// set markdown
markwon.setMarkdown(textView, "**Hello there!**");
```
The most simple way to obtain markdown to be applied _somewhere_ else:
```java
// parsed and styled markdown
final CharSequence markdown = Markwon.markdown(context, "**Hello there!**");
// obtain an instance of Markwon
final Markwon markwon = Markwon.create(context);
// parse markdown and create styled text
final Spanned markdown = markwon.toMarkdown("**Hello there!**");
// use it
Toast.makeText(context, markdown, Toast.LENGTH_LONG).show();
```
:::warning v3 migration
:::warning 3.x.x migration
Starting with <Badge text="3.0.0" /> version Markwon no longer relies on static
utility methods. To learn more about migrating existing applications
refer to [migration](/docs/migration-2-3.md) section.
@ -31,69 +38,78 @@ refer to [migration](/docs/migration-2-3.md) section.
## Longer one
When you need to customize markdown parsing/rendering you can use [SpannableConfiguration](/docs/configure.md):
With explicit `parse` and `render` methods:
```java
final SpannableConfiguration configuration = SpannableConfiguration.builder(context)
.asyncDrawableLoader(AsyncDrawableLoader.create())
.build();
// obtain an instance of Markwon
final Markwon markwon = Markwon.create(context);
Markwon.setMarkdown(textView, configuration, "Are **you** still there?");
// parse markdown to commonmark-java Node
final Node node = markwon.parse("Are **you** still there?");
final CharSequence markdown = Markwon.markdown(configuration, "Are **you** still there?");
// create styled text from parsed Node
final Spanned markdown = markwon.render(node);
// use it on a TextView
markwon.setParsedMarkdown(textView, markdown);
// or a Toast
Toast.makeText(context, markdown, Toast.LENGTH_LONG).show();
```
## No magic one
In order to understand how previous examples work, let's break them down:
* construct a `Parser` (see: <Link name="commonmark-java" />) and parse markdown
* construct a `SpannableConfiguration` (if it's not provided)
* *render* parsed markdown to Spannable (via `SpannableRenderer`)
* prepares TextView to display images, tables and links
* sets text
This flow answers the most simple usage of displaying markdown: one shot parsing
&amp; configuration of relatively small markdown chunks. If your markdown contains
a lot of text or you plan to display multiple UI widgets with markdown you might
consider *stepping in* and taking control of this flow.
The candidate requirements to *step in*:
* parsing and processing of parsed markdown in a background thread
* reusing `Parser` and/or `SpannableConfiguration` between multiple calls
* ignore images or tables specific logic (you know that markdown won't contain them)
So, if we expand `Markwon.setMarkdown(textView, markdown)` method we will see the following:
So, what happens _internally_ when there is a `markwon#setMarkdown(TextView,String)` call?
Please note that this is mere representaion of what happens underneath and a caller
would likely never has to deal with these method calls directly. It still valuable
to understand how things are working:
```java
// create a Parser instance (can be done manually)
// internally creates default Parser instance & registers `strike-through` & `tables` extension
final Parser parser = Markwon.createParser();
// `Markwon#create` implicitly uses CorePlugin
final Markwon markwon = Markwon.builder(context)
.usePlugin(CorePlugin.create())
.build();
// core class to display markdown, can be obtained via this method,
// which creates default instance (no images handling though),
// or via `builder` method, which lets you to configure this instance
final SpannableConfiguration configuration = SpannableConfiguration.create(context);
// each plugin will configure resulting Markwon instance
// we will cover it in plugins section of documentation
final SpannableRenderer renderer = new SpannableRenderer();
// warning: pseudo-code
final Node node = parser.parse(markdown);
final CharSequence text = renderer.render(configuration, node);
// 0. each plugin will be called to _pre-process_ raw input markdown
rawInput = plugins.reduce(rawInput, (input, plugin) -> plugin.processMarkdown(input));
// for links in markdown to be clickable
textView.setMovementMethod(LinkMovementMethod.getInstance());
// 1. after input is processed it's being parsed to a Node
node = parser.parse(rawInput);
// we need these due to the limited nature of Spannables to invalidate TextView
Markwon.unscheduleDrawables(textView);
Markwon.unscheduleTableRows(textView);
// 2. each plugin will configure RenderProps
plugins.forEach(plugin -> plugin.configureRenderProps(renderProps));
textView.setText(text);
// 3. each plugin will be able to inspect or manipulate resulting Node
// before rendering
plugins.forEach(plugin -> plugin.beforeRender(node));
Markwon.scheduleDrawables(textView);
Markwon.scheduleTableRows(textView);
// 4. node is being visited by a visitor
node.accept(visitor);
// 5. each plugin will be called after node is being visited (aka rendered)
plugins.forEach(plugin -> plugin.afterRender(node, visitor));
// 6. styled markdown ready at this point
final Spanned markdown = visitor.markdown();
// 7. each plugin will be called before styled markdown is applied to a TextView
plugins.forEach(plugin -> plugin.beforeSetText(textView, markdown));
// 8. markdown is applied to a TextView
textView.setText(markdown);
// 9. each plugin will be called after markdown is applied to a TextView
plugins.forEach(plugin -> plugin.afterSetText(textView));
```
As you can see a `plugin` is what lifts the most weight. We will cover
plugins next.
:::tip Note
If you are having trouble with `LinkMovementMethod` you can use
`Markwon.setText(textView, markdown, movementMethod)` method <Badge text="1.0.6" /> to specify _no_ movement

View File

@ -19,7 +19,7 @@ $$\\text{A long division \\longdiv{12345}{13}$$
```java
Markwon.builder(context)
.use(ImagesPlugin.create(context))
.use(JLatexMathPlugin.create(new Config(textSize))
.use(JLatexMathPlugin.create(textSize))
.build();
```
@ -30,17 +30,17 @@ final result
## Config
```java
public static class Config {
protected final float textSize;
protected Drawable background;
@JLatexMathDrawable.Align
protected int align = JLatexMathDrawable.ALIGN_CENTER;
protected boolean fitCanvas = true;
protected int padding;
}
final Markwon markwon = Markwon.builder(context)
.usePlugin(ImagesPlugin.create(context))
.usePlugin(JLatexMathPlugin.create(textSize, new BuilderConfigure() {
@Override
public void configureBuilder(@NonNull Builder builder) {
builder
.background(backgroundDrawable)
.align(JLatexMathDrawable.ALIGN_CENTER)
.fitCanvas(true)
.padding(paddingPx);
}
}))
.build();
```

View File

@ -2,11 +2,6 @@
# Getting started
:::tip Installation
Please follow [installation](/docs/install.md) instructions
to learn how to add `Markwon` to your project
:::
## Quick one
This is the most simple way to set markdown to a `TextView` or any of its siblings:

View File

@ -4,6 +4,7 @@ import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.VisibleForTesting;
import android.text.Spanned;
import android.text.method.LinkMovementMethod;
import android.widget.TextView;
import org.commonmark.node.BlockQuote;
@ -113,6 +114,16 @@ public class CorePlugin extends AbstractMarkwonPlugin {
OrderedListItemSpan.measure(textView, markdown);
}
@Override
public void afterSetText(@NonNull TextView textView) {
// let's ensure that there is a movement method applied
// we do it `afterSetText` so any user-defined movement method won't be
// replaced (it should be done in `beforeSetText` or manually on a TextView)
if (textView.getMovementMethod() == null) {
textView.setMovementMethod(LinkMovementMethod.getInstance());
}
}
private static void text(@NonNull MarkwonVisitor.Builder builder) {
builder.on(Text.class, new MarkwonVisitor.NodeVisitor<Text>() {
@Override

View File

@ -1,47 +1,3 @@
# LaTeX
[![ext-latex](https://img.shields.io/maven-central/v/ru.noties.markwon/ext-latex.svg?label=ext-latex)](http://search.maven.org/#search|ga|1|g%3A%22ru.noties.markwon%22%20AND%20a%3A%22ext-latex%22)
This is an extension that will help you display LaTeX formulas in your markdown.
Syntax is pretty simple: pre-fix and post-fix your latex with `$$` (double dollar sign).
`$$` should be the first characters in a line.
```markdown
$$
\\text{A long division \\longdiv{12345}{13}
$$
```
```markdown
$$\\text{A long division \\longdiv{12345}{13}$$
```
```java
Markwon.builder(context)
.use(ImagesPlugin.create(context))
.use(JLatexMathPlugin.create(new Config(textSize))
.build();
```
This extension uses [jlatexmath-android](https://github.com/noties/jlatexmath-android) artifact to create LaTeX drawable. Then it
registers special `latex` image scheme handler and uses `AsyncDrawableLoader` to display
final result
## Config
```java
public static class Config {
protected final float textSize;
protected Drawable background;
@JLatexMathDrawable.Align
protected int align = JLatexMathDrawable.ALIGN_CENTER;
protected boolean fitCanvas = true;
protected int padding;
}
```
[Documentation](https://noties.github.io/Markwon/docs/ext-latex)

View File

@ -9,7 +9,8 @@
android:layout_height="wrap_content"
android:padding="8dip"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textSize="15sp"
android:textColor="#000"
android:textSize="16sp"
tools:text="whatever" />
</ScrollView>