Implicit LinkMovementMethod if not supplied explicitly
This commit is contained in:
		
							parent
							
								
									ba5bb9bfc7
								
							
						
					
					
						commit
						02e7539881
					
				| @ -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
	 Dimitry Ivanov
						Dimitry Ivanov