Working with readmes

This commit is contained in:
Dimitry Ivanov 2017-05-26 17:42:17 +03:00
parent 0f1b6c4cf7
commit 261f289329
5 changed files with 208 additions and 48 deletions

View File

@ -13,6 +13,10 @@ compile 'ru.noties:markwon-image-loader:1.0.0' // optional
---
**Please note, that this file is created for demonstration purposes. Please refer to `library` module [README][library] instead**
---
## Supported markdown features:
* Emphasis (`*`, `_`)
* Strong emphasis (`**`, `__`)
@ -167,4 +171,6 @@ long long long skjfs fgjsdfhj sf `dfk df` | sdsd,fklsdfklsdfklsdfkl sdfkl dsfjks
[1]: https://github.com
[github]: https://github.com
[commonmark-java]: https://github.com/atlassian/commonmark-java
[commonmark-java]: https://github.com/atlassian/commonmark-java/blob/master/README.md
[library]: https://github.com/noties/Markwon/blob/master/README.md

View File

@ -17,6 +17,142 @@ The most basic example would be:
Markwon.setMarkdown(textView, "**Hello *there*!!**")
```
Please note, that this library depends on [commonmark-java][commonmark-java] (and some extensions):
```groovy
compile 'com.atlassian.commonmark:commonmark:0.9.0'
compile 'com.atlassian.commonmark:commonmark-ext-gfm-strikethrough:0.9.0'
compile 'com.atlassian.commonmark:commonmark-ext-gfm-tables:0.9.0'
```
## Configuration
In order to render correctly markdown, this library need a `SpannableConfiguration` instance. It has 2 factory methods:
```java
// creates default instance
SpannableConfiguration.create(Context);
// returns configurable Builder
SpannableConfiguration.builder(Context);
```
`SpannableConfiguration.Builder` class has these configurable properties (which are described in more detail further):
```java
public Builder theme(SpannableTheme theme);
public Builder asyncDrawableLoader(AsyncDrawable.Loader asyncDrawableLoader);
public Builder syntaxHighlight(SyntaxHighlight syntaxHighlight);
public Builder linkResolver(LinkSpan.Resolver linkResolver);
public Builder urlProcessor(UrlProcessor urlProcessor);
public Builder htmlParser(SpannableHtmlParser htmlParser);
// and obviously:
public SpannableConfiguration build();
```
## 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
// creates ready-to-use SpannableThemeObject
SpannableTheme.create(Context);
// can be used to tweak default appearance
SpannableTheme.builderWithDefaults(Context);
// returns empty builder (no default values are set)
SpannableTheme.builder();
// returns a builder that is instantiated with all values from specified SpannableTheme
SpannableTheme.builder(SpannableTheme copyFrom);
```
`SpannableTheme.Builder` have these configurations:
#### Link
```java
public Builder linkColor(@ColorInt int linkColor);
```
#### Block
```java
// left margin for: lists & quotes (text is shifted)
public Builder blockMargin(@Dimension int blockMargin);
```
#### Quote
```java
// width of quote indication (the `|`)
public Builder blockQuoteWidth(@Dimension int blockQuoteWidth);
// color of `|` quote indication
public Builder blockQuoteColor(@ColorInt int blockQuoteColor);
```
#### Lists
```java
// color of list item bullets(●, ○, ■)/numbers
public Builder listItemColor(@ColorInt int listItemColor);
// stroke width for list bullet (2nd level - `○`)
public Builder bulletListItemStrokeWidth(@Dimension int bulletListItemStrokeWidth);
// width of list bullet (●, ○, ■)
public Builder bulletWidth(@Dimension int bulletWidth);
```
#### Code
```java
// text color for `code` blocks
public Builder codeTextColor(@ColorInt int codeTextColor);
// background color for `code` blocks
public Builder codeBackgroundColor(@ColorInt int codeBackgroundColor);
// left margin for multiline `code` blocks
public Builder codeMultilineMargin(@Dimension int codeMultilineMargin);
// typeface of `code` block
public Builder codeTypeface(@NonNull Typeface codeTypeface);
// text size for `code` block
public Builder codeTextSize(@Dimension int codeTextSize);
```
#### Headings
```java
// height of the `break` line under h1 & h2
public Builder headingBreakHeight(@Dimension int headingBreakHeight);
// color of the `break` line under h1 & h2
public Builder headingBreakColor(@ColorInt int headingBreakColor);
```
#### SuperScript & SupScript
```java
// ratio for <sup> & <sub> text size (calculated based on TextView text size)
public Builder scriptTextSizeRatio(@FloatRange(from = .0F, to = Float.MAX_VALUE) float scriptTextSizeRatio);
```
#### Thematic break
```java
// the `---` thematic break color
public Builder thematicBreakColor(@ColorInt int thematicBreakColor);
// the `---` thematic break height
public Builder thematicBreakHeight(@Dimension int thematicBreakHeight);
```
#### Tables
```java
// padding inside a table cell
public Builder tableCellPadding(@Dimension int tableCellPadding);
// color of table borders
public Builder tableBorderColor(@ColorInt int tableBorderColor);
// the `stroke` width of table border
public Builder tableBorderWidth(@Dimension int tableBorderWidth);
// the background of odd table rows
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:
@ -29,6 +165,8 @@ final AsyncDrawable.Loader loader = new AsyncDrawable.Loader() {
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);
}
});
@ -55,7 +193,7 @@ Tables are supported but with some limitations. First of all: table will always
## Syntax highlight
This library does not provide ready-to-be-used implementation of syntax highlight, but it can be easily added via `SyntaxHighlight` interface whilst building `SpannableConfiguration`:
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() {
@ -93,5 +231,21 @@ The primary goal of additing this abstraction is to give ability to convert rela
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:
```java
SpannableHtmlParser.create(SpannableTheme, AsyncDrawable.Loader)
SpannableHtmlParser.create(SpannableTheme, AsyncDrawable.Loader, UrlProcessor, LinkSpan.Resolver)
```
[commonmark-java]: https://github.com/atlassian/commonmark-java
[mil-README]: https://github.com/noties/Markwon/blob/master/library-image-loader/README.md

View File

@ -70,7 +70,7 @@ public class SpannableConfiguration {
private UrlProcessor urlProcessor;
private SpannableHtmlParser htmlParser;
public Builder(Context context) {
Builder(Context context) {
this.context = context;
}

View File

@ -163,7 +163,7 @@ public class SpannableHtmlParser {
private ImageProvider imageProvider;
private HtmlParser parser;
public Builder simpleTag(@NonNull String tag, @NonNull SpanProvider provider) {
Builder simpleTag(@NonNull String tag, @NonNull SpanProvider provider) {
simpleTags.put(tag, provider);
return this;
}

View File

@ -5,23 +5,25 @@ import android.content.res.TypedArray;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.support.annotation.AttrRes;
import android.support.annotation.ColorInt;
import android.support.annotation.Dimension;
import android.support.annotation.FloatRange;
import android.support.annotation.IntRange;
import android.support.annotation.NonNull;
import android.text.TextPaint;
import android.util.TypedValue;
import android.widget.TextView;
@SuppressWarnings("WeakerAccess")
public class SpannableTheme {
// this method should be used if TextView is known beforehand
// it will correctly measure the `space` char and set it as `codeMultilineMargin`
// otherwise this value must be set explicitly
public static SpannableTheme create(@NonNull TextView textView) {
return builderWithDefaults(textView.getContext())
.codeMultilineMargin((int) (textView.getPaint().measureText("\u00a0") + .5F))
.build();
}
//
// // this method should be used if TextView is known beforehand
// // it will correctly measure the `space` char and set it as `codeMultilineMargin`
// // otherwise this value must be set explicitly
// public static SpannableTheme create(@NonNull TextView textView) {
// return builderWithDefaults(textView.getContext())
// .codeMultilineMargin((int) (textView.getPaint().measureText("\u00a0") + .5F))
// .build();
// }
// this create default theme (except for `codeMultilineMargin` property)
public static SpannableTheme create(@NonNull Context context) {
@ -37,16 +39,16 @@ public class SpannableTheme {
}
public static Builder builderWithDefaults(@NonNull Context context) {
final Px px = new Px(context);
final Dip dip = new Dip(context);
return new Builder()
.linkColor(resolve(context, android.R.attr.textColorLink))
.codeMultilineMargin(px.px(8))
.blockMargin(px.px(24))
.bulletListItemStrokeWidth(px.px(1))
.headingBreakHeight(px.px(1))
.thematicBreakHeight(px.px(2))
.tableCellPadding(px.px(4))
.tableBorderWidth(px.px(1));
.codeMultilineMargin(dip.toPx(8))
.blockMargin(dip.toPx(24))
.bulletListItemStrokeWidth(dip.toPx(1))
.headingBreakHeight(dip.toPx(1))
.thematicBreakHeight(dip.toPx(2))
.tableCellPadding(dip.toPx(4))
.tableBorderWidth(dip.toPx(1));
}
private static int resolve(Context context, @AttrRes int attr) {
@ -385,11 +387,9 @@ public class SpannableTheme {
private int tableOddRowBackgroundColor;
Builder() {
}
Builder(@NonNull SpannableTheme theme) {
this.linkColor = theme.linkColor;
this.blockMargin = theme.blockMargin;
this.blockQuoteWidth = theme.blockQuoteWidth;
@ -413,107 +413,107 @@ public class SpannableTheme {
this.tableOddRowBackgroundColor = theme.tableOddRowBackgroundColor;
}
public Builder linkColor(int linkColor) {
public Builder linkColor(@ColorInt int linkColor) {
this.linkColor = linkColor;
return this;
}
public Builder blockMargin(int blockMargin) {
public Builder blockMargin(@Dimension int blockMargin) {
this.blockMargin = blockMargin;
return this;
}
public Builder blockQuoteWidth(int blockQuoteWidth) {
public Builder blockQuoteWidth(@Dimension int blockQuoteWidth) {
this.blockQuoteWidth = blockQuoteWidth;
return this;
}
public Builder blockQuoteColor(int blockQuoteColor) {
public Builder blockQuoteColor(@ColorInt int blockQuoteColor) {
this.blockQuoteColor = blockQuoteColor;
return this;
}
public Builder listItemColor(int listItemColor) {
public Builder listItemColor(@ColorInt int listItemColor) {
this.listItemColor = listItemColor;
return this;
}
public Builder bulletListItemStrokeWidth(int bulletListItemStrokeWidth) {
public Builder bulletListItemStrokeWidth(@Dimension int bulletListItemStrokeWidth) {
this.bulletListItemStrokeWidth = bulletListItemStrokeWidth;
return this;
}
public Builder bulletWidth(int bulletWidth) {
public Builder bulletWidth(@Dimension int bulletWidth) {
this.bulletWidth = bulletWidth;
return this;
}
public Builder codeTextColor(int codeTextColor) {
public Builder codeTextColor(@ColorInt int codeTextColor) {
this.codeTextColor = codeTextColor;
return this;
}
public Builder codeBackgroundColor(int codeBackgroundColor) {
public Builder codeBackgroundColor(@ColorInt int codeBackgroundColor) {
this.codeBackgroundColor = codeBackgroundColor;
return this;
}
public Builder codeMultilineMargin(int codeMultilineMargin) {
public Builder codeMultilineMargin(@Dimension int codeMultilineMargin) {
this.codeMultilineMargin = codeMultilineMargin;
return this;
}
public Builder codeTypeface(Typeface codeTypeface) {
public Builder codeTypeface(@NonNull Typeface codeTypeface) {
this.codeTypeface = codeTypeface;
return this;
}
public Builder codeTextSize(int codeTextSize) {
public Builder codeTextSize(@Dimension int codeTextSize) {
this.codeTextSize = codeTextSize;
return this;
}
public Builder headingBreakHeight(int headingBreakHeight) {
public Builder headingBreakHeight(@Dimension int headingBreakHeight) {
this.headingBreakHeight = headingBreakHeight;
return this;
}
public Builder headingBreakColor(int headingBreakColor) {
public Builder headingBreakColor(@ColorInt int headingBreakColor) {
this.headingBreakColor = headingBreakColor;
return this;
}
public Builder scriptTextSizeRatio(float scriptTextSizeRatio) {
public Builder scriptTextSizeRatio(@FloatRange(from = .0F, to = Float.MAX_VALUE) float scriptTextSizeRatio) {
this.scriptTextSizeRatio = scriptTextSizeRatio;
return this;
}
public Builder thematicBreakColor(int thematicBreakColor) {
public Builder thematicBreakColor(@ColorInt int thematicBreakColor) {
this.thematicBreakColor = thematicBreakColor;
return this;
}
public Builder thematicBreakHeight(int thematicBreakHeight) {
public Builder thematicBreakHeight(@Dimension int thematicBreakHeight) {
this.thematicBreakHeight = thematicBreakHeight;
return this;
}
public Builder tableCellPadding(int tableCellPadding) {
public Builder tableCellPadding(@Dimension int tableCellPadding) {
this.tableCellPadding = tableCellPadding;
return this;
}
public Builder tableBorderColor(int tableBorderColor) {
public Builder tableBorderColor(@ColorInt int tableBorderColor) {
this.tableBorderColor = tableBorderColor;
return this;
}
public Builder tableBorderWidth(int tableBorderWidth) {
public Builder tableBorderWidth(@Dimension int tableBorderWidth) {
this.tableBorderWidth = tableBorderWidth;
return this;
}
public Builder tableOddRowBackgroundColor(int tableOddRowBackgroundColor) {
public Builder tableOddRowBackgroundColor(@ColorInt int tableOddRowBackgroundColor) {
this.tableOddRowBackgroundColor = tableOddRowBackgroundColor;
return this;
}
@ -523,14 +523,14 @@ public class SpannableTheme {
}
}
private static class Px {
private static class Dip {
private final float density;
Px(@NonNull Context context) {
Dip(@NonNull Context context) {
this.density = context.getResources().getDisplayMetrics().density;
}
int px(int dp) {
int toPx(int dp) {
return (int) (dp * density + .5F);
}
}