Implicit LinkMovementMethod if not supplied explicitly
This commit is contained in:
parent
ba5bb9bfc7
commit
02e7539881
app/src/main/java/ru/noties/markwon
docs
.vuepress
docs
markwon-core/src/main/java/ru/noties/markwon/core
markwon-ext-latex
sample/src/main/res/layout
@ -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) {
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -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',
|
||||
|
@ -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
|
||||
& 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
|
||||
|
@ -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();
|
||||
```
|
@ -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:
|
||||
|
@ -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
|
||||
|
@ -1,47 +1,3 @@
|
||||
# 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)
|
||||
|
@ -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>
|
Loading…
x
Reference in New Issue
Block a user