diff --git a/library/README.md b/library/README.md
index ae394b0e..8c5e1616 100644
--- a/library/README.md
+++ b/library/README.md
@@ -15,6 +15,9 @@ The aim for this library is to render markdown as first class citizen on Android
The most basic example would be:
```java
Markwon.setMarkdown(textView, "**Hello *there*!!**")
+
+// or
+Markwon.setMarkdown(textView, spannableConfiguration, "**There hello~~!~~**")
```
Please note, that this library depends on [commonmark-java][commonmark-java] (and some extensions):
@@ -47,6 +50,92 @@ public Builder htmlParser(SpannableHtmlParser htmlParser);
public SpannableConfiguration build();
```
+## Images
+
+By default this library does not render any of the images. It's done to simplify rendering of text-based markdown. But if images must be supported, then the `AsyncDrawable.Loader` can be specified whilst building a `SpannableConfiguration` instance:
+
+```java
+final AsyncDrawable.Loader loader = new AsyncDrawable.Loader() {
+ @Override
+ public void load(@NonNull String destination, @NonNull final AsyncDrawable drawable) {
+ // `download` method is here for demonstration purposes, it's not included in this interface
+ download(destination, new Callback() {
+ @Override
+ public void onDownloaded(Drawable d) {
+ // additionally we can call `drawable.isAttached()`
+ // to ensure if AsyncDrawable is in layout
+ drawable.setResult(d);
+ }
+ });
+ }
+
+ @Override
+ public void cancel(@NonNull String destination) {
+ // cancel download here
+ }
+};
+
+// `this` here referrs to a Context instance
+final SpannableConfiguration configuration = SpannableConfiguration.builder(this)
+ .asyncDrawableLoader(loader)
+ .build();
+```
+
+There is also standalone artifact that supports image loading *out-of-box* (including support for **SVG** & **GIF**), but provides little to none configuration and could be somewhat not optimal. Please refer to the [README][mil-README] of the module.
+
+
+## Tables
+
+Tables are supported but with some limitations. First of all: table will always take the full width of the TextView Canvas. Second: each column will have the same width (we do not calculate the weight of column) - so, a column width will be: `totalWidth / columnsNumber`.
+
+
+## Syntax highlight
+This library does not provide ready-to-be-used implementation of syntax highlight, but it can be added via `SyntaxHighlight` interface whilst building `SpannableConfiguration`:
+
+```java
+final SyntaxHighlight syntaxHighlight = new SyntaxHighlight() {
+ @NonNull
+ @Override
+ public CharSequence highlight(@Nullable String info, @NonNull String code) {
+ // create Spanned of highlight here
+ return null; // must not return `null` here
+ }
+};
+
+final SpannableConfiguration configuration = SpannableConfiguration.builder(this)
+ .syntaxHighlight(syntaxHighlight)
+ .build();
+```
+
+## Url processing
+If you wish to process urls (links & images) that markdown contains, the `UrlProcessor` can be used:
+```java
+final UrlProcessor urlProcessor = new UrlProcessor() {
+ @NonNull
+ @Override
+ public String process(@NonNull String destination) {
+ // modify the `destination` or return as-is
+ return null;
+ }
+};
+
+final SpannableConfiguration configuration = SpannableConfiguration.builder(this)
+ .urlProcessor(urlProcessor)
+ .build();
+```
+The primary goal of additing this abstraction is to give ability to convert relative urls to absolute ones. If it fits your purpose, then `UrlProcessorRelativeToAbsolute` can be used:
+```java
+final UrlProcessor urlProcessor = new UrlProcessorRelativeToAbsolute("https://this-is-base.org");
+```
+
+## Link resolver
+Link resolver is used to navigate to clicked link. By default `LinkResolverDef` is used and it just constructs an `Intent` and launches activity that can handle it, or silently fails if activity cannot be resolved. The main interface:
+```java
+public interface Resolver {
+ void resolve(View view, @NonNull String link);
+}
+```
+
## Theme
`SpannableTheme` controlls the appearance of rendered markdown. It has pretty reasonable defaults, which are established based on style of a TextView to which it is applied. It has some factory methods:
```java
@@ -153,91 +242,6 @@ public Builder tableBorderWidth(@Dimension int tableBorderWidth);
public Builder tableOddRowBackgroundColor(@ColorInt int tableOddRowBackgroundColor);
```
-## Images
-
-By default this library does not render any of the images. It's done to simplify rendering of text-based markdown. But if images must be supported, then the `AsyncDrawable.Loader` can be specified whilst building a `SpannableConfiguration` instance:
-
-```java
-final AsyncDrawable.Loader loader = new AsyncDrawable.Loader() {
- @Override
- public void load(@NonNull String destination, @NonNull final AsyncDrawable drawable) {
- // `download` method is here for demonstration purposes, it's not included in this interface
- download(destination, new Callback() {
- @Override
- public void onDownloaded(Drawable d) {
- // additionally we can call `drawable.isAttached()`
- // to ensure if AsyncDrawable is in layout
- drawable.setResult(d);
- }
- });
- }
-
- @Override
- public void cancel(@NonNull String destination) {
- // cancel download here
- }
-};
-
-// `this` here referrs to a Context instance
-final SpannableConfiguration configuration = SpannableConfiguration.builder(this)
- .asyncDrawableLoader(loader)
- .build();
-```
-
-There is also standalone artifact that supports image loading *out-of-box* (including support for **SVG** & **GIF**), but provides little to none configuration and could be somewhat not optimal. Please refer to the [README][mil-README] of the module.
-
-
-## Tables
-
-Tables are supported but with some limitations. First of all: table will always take the full width of the TextView Canvas. Second: each column will have the same width (we do not calculate the weight of column) - so, a column width will be: `totalWidth / columnsNumber`.
-
-
-## Syntax highlight
-This library does not provide ready-to-be-used implementation of syntax highlight, but it can be added via `SyntaxHighlight` interface whilst building `SpannableConfiguration`:
-
-```java
-final SyntaxHighlight syntaxHighlight = new SyntaxHighlight() {
- @NonNull
- @Override
- public CharSequence highlight(@Nullable String info, @NonNull String code) {
- // create Spanned of highlight here
- return null; // must not return `null` here
- }
-};
-
-final SpannableConfiguration configuration = SpannableConfiguration.builder(this)
- .syntaxHighlight(syntaxHighlight)
- .build();
-```
-
-## Url processing
-If you wish to process urls (links & images) that markdown contains, the `UrlProcessor` can be used:
-```java
-final UrlProcessor urlProcessor = new UrlProcessor() {
- @NonNull
- @Override
- public String process(@NonNull String destination) {
- // modify the `destination` or return as-is
- return null;
- }
-};
-
-final SpannableConfiguration configuration = SpannableConfiguration.builder(this)
- .urlProcessor(urlProcessor)
- .build();
-```
-The primary goal of additing this abstraction is to give ability to convert relative urls to absolute ones. If it fits your purpose, then `UrlProcessorRelativeToAbsolute` can be used:
-```java
-final UrlProcessor urlProcessor = new UrlProcessorRelativeToAbsolute("https://this-is-base.org");
-```
-
-## Link resolver
-Link resolver is used to navigate to clicked link. By default `LinkResolverDef` is used and it just constructs an `Intent` and launches activity that can handle it, or silently fails if activity cannot be resolved. The main interface:
-```java
-public interface Resolver {
- void resolve(View view, @NonNull String link);
-}
-```
## HTML parser
As markdown supports HTML to be inlined, we need to introduce another entity that does (limited) parsing. Obtain an instance of `SpannableHtmlParser` via one of these factory methods:
@@ -247,5 +251,36 @@ SpannableHtmlParser.create(SpannableTheme, AsyncDrawable.Loader)
SpannableHtmlParser.create(SpannableTheme, AsyncDrawable.Loader, UrlProcessor, LinkSpan.Resolver)
```
+Or, if further tweaking is requered builder methods:
+```java
+// creates empty builder
+SpannableHtmlParser.builder();
+
+// creates builder that is set-up to default values
+SpannableHtmlParser.builderWithDefaults(
+ @NonNull SpannableTheme theme,
+ @Nullable AsyncDrawable.Loader asyncDrawableLoader,
+ @Nullable UrlProcessor urlProcessor,
+ @Nullable LinkSpan.Resolver resolver
+)
+```
+
+Builder with defaults additionally handles these HTML tags:
+* `b`, `strong`
+* `i`, `em`, `cite`, `dfn`
+* `sup`
+* `sub`
+* `u`
+* `del`, `s`, `strike`
+* `a`
+* `img` (only if `AsyncDrawable.Loader` was provided)
+
+You can add own simple tags handling (or override default) via:
+```java
+SpannableHtmlParser.Builder.simpleTag(String, SpanProvider)
+```
+
+Please note, that not all tags are possible to handle via this. These are so called `void` tags ([link](https://www.w3.org/TR/html51/syntax.html#void-elements)) and so-called `html-blocks` ([link](http://spec.commonmark.org/0.18/#html-blocks)). An exception is made only for `img` tag -> it's possible to handle it via `imageProvider` property in `Builder`
+
[commonmark-java]: https://github.com/atlassian/commonmark-java
[mil-README]: https://github.com/noties/Markwon/blob/master/library-image-loader/README.md
diff --git a/library/src/main/java/ru/noties/markwon/renderer/SpannableMarkdownVisitor.java b/library/src/main/java/ru/noties/markwon/renderer/SpannableMarkdownVisitor.java
index 757f735f..022d706b 100644
--- a/library/src/main/java/ru/noties/markwon/renderer/SpannableMarkdownVisitor.java
+++ b/library/src/main/java/ru/noties/markwon/renderer/SpannableMarkdownVisitor.java
@@ -63,6 +63,10 @@ public class SpannableMarkdownVisitor extends AbstractVisitor {
private int blockQuoteIndent;
private int listLevel;
+ private List pendingTableRow;
+ private boolean tableRowIsHeader;
+ private int tableRows;
+
public SpannableMarkdownVisitor(
@NonNull SpannableConfiguration configuration,
@NonNull SpannableStringBuilder builder
@@ -265,10 +269,6 @@ public class SpannableMarkdownVisitor extends AbstractVisitor {
newLine();
}
- private List pendingTableRow;
- private boolean tableRowIsHeader;
- private int tableRows;
-
@Override
public void visit(CustomNode customNode) {