Working with documentation v4
This commit is contained in:
parent
8b0edc32c3
commit
8944f39592
@ -1,5 +1,9 @@
|
|||||||
# https://docs.travis-ci.com/user/languages/android/
|
# https://docs.travis-ci.com/user/languages/android/
|
||||||
|
|
||||||
language: android
|
language: android
|
||||||
|
|
||||||
|
# so, out of blue travis requires this now (without it build would not even execute, immediate failure when downloading jdk)
|
||||||
|
dist: trusty
|
||||||
jdk: openjdk8
|
jdk: openjdk8
|
||||||
sudo: false
|
sudo: false
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
|
|
||||||
// this is a generated file, do not modify. To update it run 'collectArtifacts.js' script
|
// this is a generated file, do not modify. To update it run 'collectArtifacts.js' script
|
||||||
const artifacts = [{"id":"core","name":"Core","group":"io.noties.markwon","description":"Core Markwon artifact that includes basic markdown parsing and rendering"},{"id":"ext-latex","name":"LaTeX","group":"io.noties.markwon","description":"Extension to add LaTeX formulas to Markwon markdown"},{"id":"ext-strikethrough","name":"Strikethrough","group":"io.noties.markwon","description":"Extension to add strikethrough markup to Markwon markdown"},{"id":"ext-tables","name":"Tables","group":"io.noties.markwon","description":"Extension to add tables markup (GFM) to Markwon markdown"},{"id":"ext-tasklist","name":"Task List","group":"io.noties.markwon","description":"Extension to add task lists (GFM) to Markwon markdown"},{"id":"html","name":"HTML","group":"io.noties.markwon","description":"Provides HTML parsing functionality"},{"id":"image","name":"Image","group":"io.noties.markwon","description":"Markwon image loading module (with optional GIF and SVG support)"},{"id":"image-gif","name":"Image GIF","group":"io.noties.markwon","description":"Adds GIF media support to Markwon markdown"},{"id":"image-glide","name":"Image Glide","group":"io.noties.markwon","description":"Markwon image loading module (based on Glide library)"},{"id":"image-okhttp","name":"Image OkHttp","group":"io.noties.markwon","description":"Adds OkHttp client to retrieve images data from network"},{"id":"image-picasso","name":"Image Picasso","group":"io.noties.markwon","description":"Markwon image loading module (based on Picasso library)"},{"id":"image-svg","name":"Image SVG","group":"io.noties.markwon","description":"Adds SVG media support to Markwon markdown"},{"id":"linkify","name":"Linkify","group":"io.noties.markwon","description":"Markwon plugin to linkify text (based on Android Linkify)"},{"id":"recycler","name":"Recycler","group":"io.noties.markwon","description":"Provides RecyclerView.Adapter to display Markwon markdown"},{"id":"recycler-table","name":"Recycler Table","group":"io.noties.markwon","description":"Provides MarkwonAdapter.Entry to render TableBlocks inside Android-native TableLayout widget"},{"id":"syntax-highlight","name":"Syntax Highlight","group":"io.noties.markwon","description":"Add syntax highlight to Markwon markdown via Prism4j library"}];
|
const artifacts = [{"id":"core","name":"Core","group":"io.noties.markwon","description":"Core Markwon artifact that includes basic markdown parsing and rendering"},{"id":"ext-latex","name":"LaTeX","group":"io.noties.markwon","description":"Extension to add LaTeX formulas to Markwon markdown"},{"id":"ext-strikethrough","name":"Strikethrough","group":"io.noties.markwon","description":"Extension to add strikethrough markup to Markwon markdown"},{"id":"ext-tables","name":"Tables","group":"io.noties.markwon","description":"Extension to add tables markup (GFM) to Markwon markdown"},{"id":"ext-tasklist","name":"Task List","group":"io.noties.markwon","description":"Extension to add task lists (GFM) to Markwon markdown"},{"id":"html","name":"HTML","group":"io.noties.markwon","description":"Provides HTML parsing functionality"},{"id":"image","name":"Image","group":"io.noties.markwon","description":"Markwon image loading module (with optional GIF and SVG support)"},{"id":"image-glide","name":"Image Glide","group":"io.noties.markwon","description":"Markwon image loading module (based on Glide library)"},{"id":"image-picasso","name":"Image Picasso","group":"io.noties.markwon","description":"Markwon image loading module (based on Picasso library)"},{"id":"linkify","name":"Linkify","group":"io.noties.markwon","description":"Markwon plugin to linkify text (based on Android Linkify)"},{"id":"recycler","name":"Recycler","group":"io.noties.markwon","description":"Provides RecyclerView.Adapter to display Markwon markdown"},{"id":"recycler-table","name":"Recycler Table","group":"io.noties.markwon","description":"Provides MarkwonAdapter.Entry to render TableBlocks inside Android-native TableLayout widget"},{"id":"syntax-highlight","name":"Syntax Highlight","group":"io.noties.markwon","description":"Add syntax highlight to Markwon markdown via Prism4j library"}];
|
||||||
export { artifacts };
|
export { artifacts };
|
||||||
|
24
docs/.vuepress/components/MavenBadge4.vue
Normal file
24
docs/.vuepress/components/MavenBadge4.vue
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
<template>
|
||||||
|
<a :href="mavenSearchUrl()"><img :src="shieldImgageUrl()" :alt="displayLabel"></a>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'MavenBadge',
|
||||||
|
props: ['artifact', 'label'],
|
||||||
|
methods: {
|
||||||
|
mavenSearchUrl: function() {
|
||||||
|
return `http://search.maven.org/#search|ga|1|g%3A%22io.noties.markwon%22%20AND%20a%3A%22${this.artifact}%22`;
|
||||||
|
},
|
||||||
|
shieldImgageUrl: function() {
|
||||||
|
return `https://img.shields.io/maven-central/v/io.noties.markwon/${this.artifact}.svg?label=${this.displayLabel}`;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
displayLabel() {
|
||||||
|
return this.label || this.artifact;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
@ -54,6 +54,17 @@ module.exports = {
|
|||||||
'/docs/v4/core/render-props.md'
|
'/docs/v4/core/render-props.md'
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
'/docs/v4/ext-latex/',
|
||||||
|
'/docs/v4/ext-strikethrough/',
|
||||||
|
'/docs/v4/ext-tables/',
|
||||||
|
'/docs/v4/ext-tasklist/',
|
||||||
|
'/docs/v4/html/',
|
||||||
|
'/docs/v4/image/',
|
||||||
|
'/docs/v4/image-glide/',
|
||||||
|
'/docs/v4/image-picasso/',
|
||||||
|
'/docs/v4/recycler/',
|
||||||
|
'/docs/v4/recycler-table/',
|
||||||
|
'/docs/v4/syntax-highlight/',
|
||||||
'/docs/v4/recipes.md',
|
'/docs/v4/recipes.md',
|
||||||
'/docs/v4/migration-3-4.md'
|
'/docs/v4/migration-3-4.md'
|
||||||
],
|
],
|
||||||
|
@ -7,6 +7,8 @@ title: 'Overview'
|
|||||||
<br><br>
|
<br><br>
|
||||||
<MavenBadges2xx/>
|
<MavenBadges2xx/>
|
||||||
|
|
||||||
|
<LegacyWarning />
|
||||||
|
|
||||||
**Markwon** is a markdown library for Android. It parses markdown following
|
**Markwon** is a markdown library for Android. It parses markdown following
|
||||||
<Link name="commonmark-spec" /> with the help of amazing <Link name="commonmark-java" /> library
|
<Link name="commonmark-spec" /> with the help of amazing <Link name="commonmark-java" /> library
|
||||||
and renders result as _Android-native_ Spannables. **No HTML** is involved
|
and renders result as _Android-native_ Spannables. **No HTML** is involved
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
# Configuration
|
# Configuration
|
||||||
|
|
||||||
|
<LegacyWarning />
|
||||||
|
|
||||||
`SpannableConfiguration` is the core component that controls how markdown is parsed and rendered.
|
`SpannableConfiguration` is the core component that controls how markdown is parsed and rendered.
|
||||||
It can be obtained via factory methods:
|
It can be obtained via factory methods:
|
||||||
|
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
# Factory <Badge text="1.1.0" />
|
# Factory <Badge text="1.1.0" />
|
||||||
|
|
||||||
|
<LegacyWarning />
|
||||||
|
|
||||||
`SpannableFactory` is used to create Span implementations.
|
`SpannableFactory` is used to create Span implementations.
|
||||||
|
|
||||||
```java
|
```java
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
# Getting started
|
# Getting started
|
||||||
|
|
||||||
|
<LegacyWarning />
|
||||||
|
|
||||||
## Quick one
|
## Quick one
|
||||||
|
|
||||||
This is the most simple way to set markdown to a `TextView` or any of its siblings:
|
This is the most simple way to set markdown to a `TextView` or any of its siblings:
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
# HTML <Badge text="2.0.0" />
|
# HTML <Badge text="2.0.0" />
|
||||||
|
|
||||||
|
<LegacyWarning />
|
||||||
|
|
||||||
Starting with version `2.0.0` `Markwon` brings the whole HTML parsing/rendering
|
Starting with version `2.0.0` `Markwon` brings the whole HTML parsing/rendering
|
||||||
stack _on-site_. The main reason for this are _special_ definitions of HTML nodes
|
stack _on-site_. The main reason for this are _special_ definitions of HTML nodes
|
||||||
by <Link name="commonmark-spec" />. More specifically: <Link name="commonmark-spec#inline" displayName="inline" />
|
by <Link name="commonmark-spec" />. More specifically: <Link name="commonmark-spec#inline" displayName="inline" />
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
# Images
|
# Images
|
||||||
|
|
||||||
|
<LegacyWarning />
|
||||||
|
|
||||||
By default `Markwon` doesn't handle images. Although `AsyncDrawable.Loader` is
|
By default `Markwon` doesn't handle images. Although `AsyncDrawable.Loader` is
|
||||||
defined in main artifact, it does not provide implementation.
|
defined in main artifact, it does not provide implementation.
|
||||||
|
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
# Installation
|
# Installation
|
||||||
|
|
||||||
|
<LegacyWarning />
|
||||||
|
|
||||||
<MavenBadges2xx />
|
<MavenBadges2xx />
|
||||||
|
|
||||||
In order to start using `Markwon` add this to your dependencies block
|
In order to start using `Markwon` add this to your dependencies block
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
# Syntax highlight
|
# Syntax highlight
|
||||||
|
|
||||||
|
<LegacyWarning />
|
||||||
|
|
||||||
<MavenBadge2xx artifact="markwon-syntax-highlight" />
|
<MavenBadge2xx artifact="markwon-syntax-highlight" />
|
||||||
|
|
||||||
This is a simple module to add **syntax highlight** functionality to your markdown rendered with `Markwon` library. It is based on [Prism4j](https://github.com/noties/Prism4j) so lead there to understand how to configure `Prism4j` instance.
|
This is a simple module to add **syntax highlight** functionality to your markdown rendered with `Markwon` library. It is based on [Prism4j](https://github.com/noties/Prism4j) so lead there to understand how to configure `Prism4j` instance.
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
# Theme
|
# Theme
|
||||||
|
|
||||||
|
<LegacyWarning />
|
||||||
|
|
||||||
Here is the list of properties that can be configured via `SpannableTheme`. If you wish to control what
|
Here is the list of properties that can be configured via `SpannableTheme`. If you wish to control what
|
||||||
is out of this list, you can use [SpannableFactory](/docs/v2/factory.md)
|
is out of this list, you can use [SpannableFactory](/docs/v2/factory.md)
|
||||||
abstraction which lets you to gather full control of Spans that are used to display markdown.
|
abstraction which lets you to gather full control of Spans that are used to display markdown.
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
# MarkwonView
|
# MarkwonView
|
||||||
|
|
||||||
|
<LegacyWarning />
|
||||||
|
|
||||||
<MavenBadge2xx artifact="markwon-view" />
|
<MavenBadge2xx artifact="markwon-view" />
|
||||||
|
|
||||||
This is simple library containing 2 views that are able to display markdown:
|
This is simple library containing 2 views that are able to display markdown:
|
||||||
|
49
docs/docs/v4/ext-latex/README.md
Normal file
49
docs/docs/v4/ext-latex/README.md
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
# LaTeX extension
|
||||||
|
|
||||||
|
<MavenBadge4 :artifact="'ext-latex'" />
|
||||||
|
|
||||||
|
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(JLatexMathPlugin.create(textSize))
|
||||||
|
.build();
|
||||||
|
```
|
||||||
|
|
||||||
|
This extension uses [jlatexmath-android](https://github.com/noties/jlatexmath-android) artifact to create LaTeX drawable.
|
||||||
|
|
||||||
|
## Config
|
||||||
|
|
||||||
|
```java
|
||||||
|
final Markwon markwon = Markwon.builder(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)
|
||||||
|
// @since 4.0.0 - optional, by default cached-thread-pool will be used
|
||||||
|
.executorService(Executors.newCachedThreadPool());
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
.build();
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
:::tip
|
||||||
|
Since <Badge text="4.0.0" /> `JLatexMathPlugin` operates independently of `ImagesPlugin`
|
||||||
|
:::
|
29
docs/docs/v4/ext-strikethrough/README.md
Normal file
29
docs/docs/v4/ext-strikethrough/README.md
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
# Strikethrough extension
|
||||||
|
|
||||||
|
<MavenBadge4 :artifact="'ext-strikethrough'" />
|
||||||
|
|
||||||
|
This module adds `strikethrough` functionality to `Markwon` via `StrikethroughPlugin`:
|
||||||
|
|
||||||
|
```java
|
||||||
|
Markwon.builder(context)
|
||||||
|
.usePlugin(StrikethroughPlugin.create())
|
||||||
|
```
|
||||||
|
|
||||||
|
This plugin registers `SpanFactory` for `Strikethrough` node, so it's possible to customize Strikethrough Span that is used in rendering:
|
||||||
|
|
||||||
|
```java
|
||||||
|
Markwon.builder(context)
|
||||||
|
.usePlugin(StrikethroughPlugin.create())
|
||||||
|
.usePlugin(new AbstractMarkwonPlugin() {
|
||||||
|
@Override
|
||||||
|
public void configureSpansFactory(@NonNull MarkwonSpansFactory.Builder builder) {
|
||||||
|
builder.setFactory(Strikethrough.class, new SpanFactory() {
|
||||||
|
@Override
|
||||||
|
public Object getSpans(@NonNull MarkwonConfiguration configuration, @NonNull RenderProps props) {
|
||||||
|
// will use Underline span instead of Strikethrough
|
||||||
|
return new UnderlineSpan();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
```
|
99
docs/docs/v4/ext-tables/README.md
Normal file
99
docs/docs/v4/ext-tables/README.md
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
# Tables extension
|
||||||
|
|
||||||
|
<MavenBadge4 :artifact="'ext-tables'" />
|
||||||
|
|
||||||
|
This extension adds support for GFM tables.
|
||||||
|
|
||||||
|
```java
|
||||||
|
final Markwon markwon = Markwon.builder(context)
|
||||||
|
// create default instance of TablePlugin
|
||||||
|
.usePlugin(TablePlugin.create(context))
|
||||||
|
```
|
||||||
|
|
||||||
|
```java
|
||||||
|
final TableTheme tableTheme = TableTheme.builder()
|
||||||
|
.tableBorderColor(Color.RED)
|
||||||
|
.tableBorderWidth(0)
|
||||||
|
.tableCellPadding(0)
|
||||||
|
.tableHeaderRowBackgroundColor(Color.BLACK)
|
||||||
|
.tableEvenRowBackgroundColor(Color.GREEN)
|
||||||
|
.tableOddRowBackgroundColor(Color.YELLOW)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
final Markwon markwon = Markwon.builder(context)
|
||||||
|
.usePlugin(TablePlugin.create(tableTheme))
|
||||||
|
```
|
||||||
|
|
||||||
|
```java
|
||||||
|
Markwon.builder(context)
|
||||||
|
.usePlugin(TablePlugin.create(builder ->
|
||||||
|
builder
|
||||||
|
.tableBorderColor(Color.RED)
|
||||||
|
.tableBorderWidth(0)
|
||||||
|
.tableCellPadding(0)
|
||||||
|
.tableHeaderRowBackgroundColor(Color.BLACK)
|
||||||
|
.tableEvenRowBackgroundColor(Color.GREEN)
|
||||||
|
.tableOddRowBackgroundColor(Color.YELLOW)
|
||||||
|
))
|
||||||
|
```
|
||||||
|
|
||||||
|
Please note, that _by default_ tables have limitations. For example, there is no support
|
||||||
|
for images inside table cells. And table contents won't be copied to clipboard if a TextView
|
||||||
|
has such functionality. Table will always take full width of a TextView in which it is displayed.
|
||||||
|
All columns will always be of the same width. So, _default_ implementation provides basic
|
||||||
|
functionality which can answer some needs. These all come from the limited nature of the TextView
|
||||||
|
to display such content.
|
||||||
|
|
||||||
|
In order to provide full-fledged experience, tables must be displayed in a special widget.
|
||||||
|
Since version `3.0.0` Markwon provides a special artifact `markwon-recycler` that allows
|
||||||
|
to render markdown in a set of widgets in a RecyclerView. It also gives ability to change
|
||||||
|
display widget form TextView to any other.
|
||||||
|
|
||||||
|
```java
|
||||||
|
final Table table = Table.parse(Markwon, TableBlock);
|
||||||
|
myTableWidget.setTable(table);
|
||||||
|
```
|
||||||
|
|
||||||
|
:::tip
|
||||||
|
To take advantage of this functionality and render tables without limitations (including
|
||||||
|
horizontally scrollable layout when its contents exceed screen width), refer to [recycler-table](/docs/v3/recycler-table/)
|
||||||
|
module documentation that adds support for rendering `TableBlock` markdown node inside Android-native `TableLayout` widget.
|
||||||
|
:::
|
||||||
|
|
||||||
|
## Theme
|
||||||
|
|
||||||
|
### Cell padding
|
||||||
|
|
||||||
|
Padding inside a table cell
|
||||||
|
|
||||||
|
<ThemeProperty name="tableCellPadding" type="@Px int" defaults="0" />
|
||||||
|
|
||||||
|
### Border color
|
||||||
|
|
||||||
|
The color of table borders
|
||||||
|
|
||||||
|
<ThemeProperty name="tableBorderColor" type="@ColorInt int" defaults="(text color) with 75 (0-255) alpha" />
|
||||||
|
|
||||||
|
### Border width
|
||||||
|
|
||||||
|
The width of table borders
|
||||||
|
|
||||||
|
<ThemeProperty name="tableBorderWidth" type="@Px int" defaults="Stroke with of context TextPaint" />
|
||||||
|
|
||||||
|
### Odd row background
|
||||||
|
|
||||||
|
Background of an odd table row
|
||||||
|
|
||||||
|
<ThemeProperty name="tableOddRowBackgroundColor" type="@ColorInt int" defaults="(text color) with 22 (0-255) alpha" />
|
||||||
|
|
||||||
|
### Even row background <Badge text="1.1.1" />
|
||||||
|
|
||||||
|
Background of an even table row
|
||||||
|
|
||||||
|
<ThemeProperty name="tableEventRowBackgroundColor" type="@ColorInt int" defaults="0" />
|
||||||
|
|
||||||
|
### Header row background <Badge text="1.1.1" />
|
||||||
|
|
||||||
|
Background of header table row
|
||||||
|
|
||||||
|
<ThemeProperty name="tableHeaderRowBackgroundColor" type="@ColorInt int" defaults="0" />
|
146
docs/docs/v4/ext-tasklist/README.md
Normal file
146
docs/docs/v4/ext-tasklist/README.md
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
# Task list extension
|
||||||
|
|
||||||
|
<MavenBadge4 :artifact="'ext-tasklist'" />
|
||||||
|
|
||||||
|
Adds support for GFM (Github-flavored markdown) task-lists:
|
||||||
|
|
||||||
|
```java
|
||||||
|
Markwon.builder(context)
|
||||||
|
.usePlugin(TaskListPlugin.create(context));
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Create a default instance of `TaskListPlugin` with `TaskListDrawable` initialized to use
|
||||||
|
`android.R.attr.textColorLink` as primary color and `android.R.attr.colorBackground` as background
|
||||||
|
```java
|
||||||
|
TaskListPlugin.create(context);
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Create an instance of `TaskListPlugin` with exact color values to use:
|
||||||
|
```java
|
||||||
|
// obtain color values
|
||||||
|
final int checkedFillColor = /* */;
|
||||||
|
final int normalOutlineColor = /* */;
|
||||||
|
final int checkMarkColor = /* */;
|
||||||
|
|
||||||
|
TaskListPlugin.create(checkedFillColor, normalOutlineColor, checkMarkColor);
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Specify own drawable for a task list item:
|
||||||
|
|
||||||
|
```java
|
||||||
|
// obtain drawable
|
||||||
|
final Drawable drawable = /* */;
|
||||||
|
|
||||||
|
TaskListPlugin.create(drawable);
|
||||||
|
```
|
||||||
|
|
||||||
|
:::warning
|
||||||
|
Please note that custom drawable for a task list item must correctly handle state
|
||||||
|
in order to display done/not-done:
|
||||||
|
|
||||||
|
```java
|
||||||
|
public class MyTaskListDrawable extends Drawable {
|
||||||
|
|
||||||
|
private boolean isChecked;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(@NonNull Canvas canvas) {
|
||||||
|
// draw accordingly to the isChecked value
|
||||||
|
}
|
||||||
|
|
||||||
|
/* implementation omitted */
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean onStateChange(int[] state) {
|
||||||
|
final boolean isChecked = contains(state, android.R.attr.state_checked);
|
||||||
|
final boolean result = this.isChecked != isChecked;
|
||||||
|
if (result) {
|
||||||
|
this.isChecked = isChecked;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean contains(@Nullable int[] states, int value) {
|
||||||
|
if (states != null) {
|
||||||
|
for (int state : states) {
|
||||||
|
if (state == value) {
|
||||||
|
// NB return here
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
:::
|
||||||
|
|
||||||
|
## Task list mutation
|
||||||
|
|
||||||
|
It is possible to mutate task list item state (toggle done/not-done). But note
|
||||||
|
that `Markwon` won't handle state change internally by any means and this change
|
||||||
|
is merely a visual one. If you need to persist state of a task list
|
||||||
|
item change you have to implement it yourself. This should get your started:
|
||||||
|
|
||||||
|
```java
|
||||||
|
final Markwon markwon = Markwon.builder(context)
|
||||||
|
.usePlugin(TaskListPlugin.create(context))
|
||||||
|
.usePlugin(new AbstractMarkwonPlugin() {
|
||||||
|
@Override
|
||||||
|
public void configureSpansFactory(@NonNull MarkwonSpansFactory.Builder builder) {
|
||||||
|
|
||||||
|
// obtain original SpanFactory set by TaskListPlugin
|
||||||
|
final SpanFactory origin = builder.getFactory(TaskListItem.class);
|
||||||
|
if (origin == null) {
|
||||||
|
// or throw, as it's a bit weird state and we expect
|
||||||
|
// this factory to be present
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.setFactory(TaskListItem.class, new SpanFactory() {
|
||||||
|
@Override
|
||||||
|
public Object getSpans(@NonNull MarkwonConfiguration configuration, @NonNull RenderProps props) {
|
||||||
|
// it's a bit non-secure behavior and we should validate
|
||||||
|
// the type of returned span first, but for the sake of brevity
|
||||||
|
// we skip this step
|
||||||
|
final TaskListSpan span = (TaskListSpan) origin.getSpans(configuration, props);
|
||||||
|
|
||||||
|
if (span == null) {
|
||||||
|
// or throw
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// return an array of spans
|
||||||
|
return new Object[]{
|
||||||
|
span,
|
||||||
|
new ClickableSpan() {
|
||||||
|
@Override
|
||||||
|
public void onClick(@NonNull View widget) {
|
||||||
|
// toggle VISUAL state
|
||||||
|
span.setDone(!span.isDone());
|
||||||
|
|
||||||
|
// do not forget to invalidate widget
|
||||||
|
widget.invalidate();
|
||||||
|
|
||||||
|
// execute your persistence logic
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateDrawState(@NonNull TextPaint ds) {
|
||||||
|
// no-op, so appearance is not changed (otherwise
|
||||||
|
// task list item will look like a link)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.build();
|
||||||
|
```
|
107
docs/docs/v4/html/README.md
Normal file
107
docs/docs/v4/html/README.md
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
# HTML
|
||||||
|
|
||||||
|
<MavenBadge4 :artifact="'html'" />
|
||||||
|
|
||||||
|
This artifact encapsulates HTML parsing from the core artifact and provides
|
||||||
|
few predefined `TagHandlers`
|
||||||
|
|
||||||
|
```java
|
||||||
|
final Markwon markwon = Markwon.builder(context)
|
||||||
|
.usePlugin(HtmlPlugin.create())
|
||||||
|
.build();
|
||||||
|
```
|
||||||
|
|
||||||
|
As this artifact brings modified [jsoup](https://github.com/jhy/jsoup) library
|
||||||
|
it was moved to a standalone module in order to minimize dependencies and unused code
|
||||||
|
in applications that does not require HTML render capabilities.
|
||||||
|
|
||||||
|
Before <Badge text="2.0.0" /> `Markwon` used android `Html` class for parsing and
|
||||||
|
rendering. Unfortunately, according to markdown specification, markdown can contain
|
||||||
|
HTML in _unpredictable_ way if rendered _outside_ of browser. For example:
|
||||||
|
|
||||||
|
```markdown{4}
|
||||||
|
<i>
|
||||||
|
Hello from italics tag
|
||||||
|
|
||||||
|
</i><b>bold></b>
|
||||||
|
```
|
||||||
|
|
||||||
|
This snippet could be represented as:
|
||||||
|
* HtmlBlock (`<i>\nHello from italics tag`)
|
||||||
|
* HtmlInline (`<i>`)
|
||||||
|
* HtmlInline (`<b>`)
|
||||||
|
* Text (`bold`)
|
||||||
|
* HtmlInline (`</b>`)
|
||||||
|
|
||||||
|
:::tip A bit of background
|
||||||
|
<br>
|
||||||
|
<GithubIssue id="52" displayName="This issue" /> had brought attention to differences between HTML & commonmark implementations. <br><br>
|
||||||
|
:::
|
||||||
|
|
||||||
|
Unfortunately Android `HTML` class cannot parse a _fragment_ of HTML to later
|
||||||
|
be included in a bigger set of content. This is why the decision was made to bring
|
||||||
|
HTML parsing _in-markwon-house_
|
||||||
|
|
||||||
|
## Predefined TagHandlers
|
||||||
|
* `<img>`
|
||||||
|
* `<a>`
|
||||||
|
* `<blockquote>`
|
||||||
|
* `<sub>`
|
||||||
|
* `<sup>`
|
||||||
|
* `<b>, <strong>`
|
||||||
|
* `<s>, <del>`
|
||||||
|
* `<u>, <ins>`
|
||||||
|
* `<ul>, <ol>`
|
||||||
|
* `<i>, <cite>, <em>, <dfn>`
|
||||||
|
* `<h1>, <h2>, <h3>, <h4>, <h5>, <h6>`
|
||||||
|
|
||||||
|
:::tip
|
||||||
|
All predefined tag handlers will use styling spans for native markdown content.
|
||||||
|
So, if your `Markwon` instance was configured to, for example, render Emphasis
|
||||||
|
nodes as a <span style="color: #FF0000">red text</span> then HTML tag handler will
|
||||||
|
use the same span. This includes images, links, UrlResolver, LinkProcessor, etc
|
||||||
|
:::
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Staring with <Badge text="4.0.0" /> you can exclude all default tag handlers:
|
||||||
|
|
||||||
|
```java
|
||||||
|
.usePlugin(HtmlPlugin.create(new HtmlPlugin.HtmlConfigure() {
|
||||||
|
@Override
|
||||||
|
public void configureHtml(@NonNull HtmlPlugin plugin) {
|
||||||
|
plugin.excludeDefaults(true);
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
```
|
||||||
|
|
||||||
|
or via plugin:
|
||||||
|
|
||||||
|
```java
|
||||||
|
.usePlugin(new AbstractMarkwonPlugin() {
|
||||||
|
@Override
|
||||||
|
public void configure(@NonNull Registry registry) {
|
||||||
|
registry.require(HtmlPlugin.class, new Action<HtmlPlugin>() {
|
||||||
|
@Override
|
||||||
|
public void apply(@NonNull HtmlPlugin htmlPlugin) {
|
||||||
|
htmlPlugin.excludeDefaults(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
If you wish to exclude some of them `TagHandlerNoOp` can be used:
|
||||||
|
|
||||||
|
```java
|
||||||
|
.usePlugin(HtmlPlugin.create(new HtmlPlugin.HtmlConfigure() {
|
||||||
|
@Override
|
||||||
|
public void configureHtml(@NonNull HtmlPlugin plugin) {
|
||||||
|
plugin.addHandler(TagHandlerNoOp.create("h4", "h5", "h6", "img"));
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
```
|
||||||
|
|
||||||
|
## TagHandler
|
||||||
|
|
||||||
|
|
3
docs/docs/v4/image-glide/README.md
Normal file
3
docs/docs/v4/image-glide/README.md
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# Image Glide
|
||||||
|
|
||||||
|
<MavenBadge4 :artifact="'image-glide'" />
|
3
docs/docs/v4/image-picasso/README.md
Normal file
3
docs/docs/v4/image-picasso/README.md
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# Image Picasso
|
||||||
|
|
||||||
|
<MavenBadge4 :artifact="'image-picasso'" />
|
172
docs/docs/v4/image/README.md
Normal file
172
docs/docs/v4/image/README.md
Normal file
@ -0,0 +1,172 @@
|
|||||||
|
# Image
|
||||||
|
|
||||||
|
<MavenBadge4 :artifact="'image'" />
|
||||||
|
|
||||||
|
In order to display images in your markdown `ImagesPlugin` can be used.
|
||||||
|
|
||||||
|
```java
|
||||||
|
final Markwon markwon = Markwon.builder(context)
|
||||||
|
.usePlugin(ImagesPlugin.create())
|
||||||
|
```
|
||||||
|
|
||||||
|
:::tip
|
||||||
|
There are also modules that add image loading capabilities to markdown
|
||||||
|
based on image-loading libraries: [image-glide](/docs/v4/image-glide/) and
|
||||||
|
[image-picasso](/docs/v4/image-picasso/)
|
||||||
|
:::
|
||||||
|
|
||||||
|
`ImagesPlugin` splits the image-loading into 2 parts: scheme-handling and media-decoding.
|
||||||
|
|
||||||
|
## SchemeHandler
|
||||||
|
|
||||||
|
To add a scheme-handler to `ImagesPlugin`:
|
||||||
|
|
||||||
|
```java
|
||||||
|
final Markwon markwon = Markwon.builder(context)
|
||||||
|
.usePlugin(ImagesPlugin.create())
|
||||||
|
.usePlugin(new AbstractMarkwonPlugin() {
|
||||||
|
@Override
|
||||||
|
public void configure(@NonNull Registry registry) {
|
||||||
|
registry.require(ImagesPlugin.class, new Action<ImagesPlugin>() {
|
||||||
|
@Override
|
||||||
|
public void apply(@NonNull ImagesPlugin imagesPlugin) {
|
||||||
|
imagesPlugin.addSchemeHandler(DataUriSchemeHandler.create());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
```java
|
||||||
|
final Markwon markwon = Markwon.builder(context)
|
||||||
|
.usePlugin(ImagesPlugin.create(new ImagesPlugin.ImagesConfigure() {
|
||||||
|
@Override
|
||||||
|
public void configureImages(@NonNull ImagesPlugin plugin) {
|
||||||
|
plugin.addSchemeHandler(DataUriSchemeHandler.create());
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
```
|
||||||
|
|
||||||
|
`ImagesPlugin` comes with a set of predefined scheme-handlers:
|
||||||
|
* `FileSchemeHandler` - `file://`
|
||||||
|
* `DataUriSchemeHandler` - `data:`
|
||||||
|
* `NetworkSchemeHandler` - `http`, `https`
|
||||||
|
* `OkHttpNetworkSchemeHandler` - `http`, `https`
|
||||||
|
|
||||||
|
### FileSchemeHandler
|
||||||
|
|
||||||
|
Loads images via `file://` scheme. Allows loading images from `assets` folder.
|
||||||
|
|
||||||
|
```java
|
||||||
|
// default implementation, no assets handling
|
||||||
|
FileSchemeHandler.create();
|
||||||
|
|
||||||
|
// assets loading
|
||||||
|
FileSchemeHandler.createWithAssets(context);
|
||||||
|
```
|
||||||
|
|
||||||
|
:::warning
|
||||||
|
Assets loading will work when your URL will include `android_asset` the the path,
|
||||||
|
for example: `file:///android_asset/image.png` (mind the 3 slashes `///`). If you wish
|
||||||
|
to _assume_ all images without proper scheme to point to assets folder, then you can use
|
||||||
|
[UrlProcessorAndroidAssets](/docs/v4/core/configuration.html#urlprocessorandroidassets)
|
||||||
|
:::
|
||||||
|
|
||||||
|
By default `ImagesPlugin` includes _plain_ `FileSchemeHandler` (without assets support),
|
||||||
|
so if you wish to change that you can explicitly specify it:
|
||||||
|
|
||||||
|
```java
|
||||||
|
final Markwon markwon = Markwon.builder(context)
|
||||||
|
.usePlugin(ImagesPlugin.create(new ImagesPlugin.ImagesConfigure() {
|
||||||
|
@Override
|
||||||
|
public void configureImages(@NonNull ImagesPlugin plugin) {
|
||||||
|
plugin.addSchemeHandler(FileSchemeHandler.createWithAssets(context));
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
```
|
||||||
|
|
||||||
|
### DataUriSchemeHandler
|
||||||
|
`DataUriSchemeHandler` allows _inlining_ images with `data:` scheme (`data:image/svg+xml;base64,MTIz`).
|
||||||
|
This scheme-handler is registered by default, so you do not need to add it explicitly.
|
||||||
|
|
||||||
|
### NetworkSchemeHandler
|
||||||
|
`NetworkSchemeHandler` allows obtaining images from `http://` and `https://` uris
|
||||||
|
(internally it uses `HttpURLConnection`). This scheme-handler is registered by default
|
||||||
|
|
||||||
|
### OkHttpNetworkSchemeHandler
|
||||||
|
`OkHttpNetworkSchemeHandler` allows obtaining images from `http://` and `https://` uris
|
||||||
|
via [okhttp library](https://github.com/square/okhttp). Please note that in order to use
|
||||||
|
this scheme-handler you must explicitly add `okhttp` library to your project.
|
||||||
|
|
||||||
|
```java
|
||||||
|
// default instance
|
||||||
|
OkHttpNetworkSchemeHandler.create();
|
||||||
|
|
||||||
|
// specify OkHttpClient to use
|
||||||
|
OkHttpNetworkSchemeHandler.create(new OkHttpClient());
|
||||||
|
|
||||||
|
// @since 4.0.0
|
||||||
|
OkHttpNetworkSchemeHandler.create(Call.Factory);
|
||||||
|
```
|
||||||
|
|
||||||
|
### Custom SchemeHandler
|
||||||
|
|
||||||
|
```java
|
||||||
|
public abstract class SchemeHandler {
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
public abstract ImageItem handle(@NonNull String raw, @NonNull Uri uri);
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
public abstract Collection<String> supportedSchemes();
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Starting with <Badge text="4.0.0" /> `SchemeHandler` can return a result (when no
|
||||||
|
further decoding is required):
|
||||||
|
|
||||||
|
```java
|
||||||
|
final Markwon markwon = Markwon.builder(context)
|
||||||
|
.usePlugin(ImagesPlugin.create(new ImagesPlugin.ImagesConfigure() {
|
||||||
|
@Override
|
||||||
|
public void configureImages(@NonNull ImagesPlugin plugin) {
|
||||||
|
// for example to return a drawable resource
|
||||||
|
plugin.addSchemeHandler(new SchemeHandler() {
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public ImageItem handle(@NonNull String raw, @NonNull Uri uri) {
|
||||||
|
|
||||||
|
final int resourceId = context.getResources().getIdentifier(
|
||||||
|
raw.substring("resources://".length()),
|
||||||
|
"drawable",
|
||||||
|
context.getPackageName());
|
||||||
|
|
||||||
|
// it's fine if it throws, async-image-loader will catch exception
|
||||||
|
final Drawable drawable = context.getDrawable(resourceId);
|
||||||
|
|
||||||
|
// it's important to apply bounds to resulting drawable
|
||||||
|
DrawableUtils.applyIntrinsicBounds(drawable);
|
||||||
|
|
||||||
|
return ImageItem.withResult(drawable);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public Collection<String> supportedSchemes() {
|
||||||
|
return Collections.singleton("resources");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
```
|
||||||
|
|
||||||
|
:::tip
|
||||||
|
If you are using [html](/docs/v4/html/) you do not have to additionally setup
|
||||||
|
images displayed via `<img>` tag, as `HtmlPlugin` automatically uses configured
|
||||||
|
image loader. But images referenced in HTML come with additional support for
|
||||||
|
sizes, which is not supported natively by markdown, allowing absolute or relative sizes:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<img src="./assets/my-image" width="100%">
|
||||||
|
```
|
||||||
|
:::
|
@ -1,3 +1,53 @@
|
|||||||
# Recipes
|
# Recipes
|
||||||
|
|
||||||
todo
|
|
||||||
|
## SpannableFactory
|
||||||
|
|
||||||
|
Consider using `NoCopySpannableFactory` when a `TextView` will be used to display markdown
|
||||||
|
multiple times (for example in a `RecyclerView`):
|
||||||
|
|
||||||
|
```java
|
||||||
|
// call after inflation and before setting markdown
|
||||||
|
textView.setSpannableFactory(NoCopySpannableFactory.getInstance());
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Autolink
|
||||||
|
|
||||||
|
Do not use `autolink` XML attribute on your `TextView` as it will remove all links except autolinked ones.
|
||||||
|
Consider using [linkify plugin](/docs/v4/linkify.md) or commonmark-java [autolink extension](https://github.com/atlassian/commonmark-java)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Custom typeface
|
||||||
|
|
||||||
|
When using a custom typeface on a `TextView` you might find that **bold** and *italic* nodes
|
||||||
|
are displayed incorrectly. Consider registering own `SpanFactories` for `StrongEmphasis` and `Emphasis` nodes:
|
||||||
|
|
||||||
|
```java
|
||||||
|
final Markwon markwon = Markwon.builder(context)
|
||||||
|
.usePlugin(new AbstractMarkwonPlugin() {
|
||||||
|
@Override
|
||||||
|
public void configureSpansFactory(@NonNull MarkwonSpansFactory.Builder builder) {
|
||||||
|
builder
|
||||||
|
.setFactory(StrongEmphasis.class, new SpanFactory() {
|
||||||
|
@Override
|
||||||
|
public Object getSpans(@NonNull MarkwonConfiguration configuration, @NonNull RenderProps props) {
|
||||||
|
return new StyleSpan(Typeface.BOLD);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.setFactory(Emphasis.class, new SpanFactory() {
|
||||||
|
@Override
|
||||||
|
public Object getSpans(@NonNull MarkwonConfiguration configuration, @NonNull RenderProps props) {
|
||||||
|
return new StyleSpan(Typeface.ITALIC);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.build();
|
||||||
|
```
|
||||||
|
|
||||||
|
Please check that `StyleSpan` works for you. If it doesn't consider
|
||||||
|
using `CustomTypefaceSpan` with your typeface directly.
|
||||||
|
|
||||||
|
|
||||||
|
92
docs/docs/v4/recycler-table/README.md
Normal file
92
docs/docs/v4/recycler-table/README.md
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
# Recycler Table <Badge text="3.0.0" />
|
||||||
|
|
||||||
|
<MavenBadge4 :artifact="'recycler-table'" />
|
||||||
|
|
||||||
|
Artifact that provides [MarkwonAdapter.Entry](/docs/v3/recycler/) to render `TableBlock` inside
|
||||||
|
Android-native `TableLayout` widget.
|
||||||
|
|
||||||
|
<img :src="$withBase('/assets/recycler-table-screenshot.png')" alt="screenshot" width="45%">
|
||||||
|
<br>
|
||||||
|
<small><em><sup>*</sup> It's possible to wrap `TableLayout` inside a `HorizontalScrollView` to include all table content</em></small>
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Register instance of `TableEntry` with `MarkwonAdapter` to render TableBlocks:
|
||||||
|
```java
|
||||||
|
final MarkwonAdapter adapter = MarkwonAdapter.builder(R.layout.adapter_default_entry, R.id.text)
|
||||||
|
.include(TableBlock.class, TableEntry.create(builder -> builder
|
||||||
|
.tableLayout(R.layout.adapter_table_block, R.id.table_layout)
|
||||||
|
.textLayoutIsRoot(R.layout.view_table_entry_cell)))
|
||||||
|
.build();
|
||||||
|
```
|
||||||
|
|
||||||
|
`TableEntry` requires at least 2 arguments:
|
||||||
|
* `tableLayout` - layout with `TableLayout` inside
|
||||||
|
* `textLayout` - layout with `TextView` inside (represents independent table cell)
|
||||||
|
|
||||||
|
In case when required view is the root of layout specific builder methods can be used:
|
||||||
|
* `tableLayoutIsRoot(int)`
|
||||||
|
* `textLayoutIsRoot(int)`
|
||||||
|
|
||||||
|
If your layouts have different structure (for example wrap a `TableView` inside a `HorizontalScrollView`)
|
||||||
|
then you should use methods that accept ID of required view inside layout:
|
||||||
|
* `tableLayout(int, int)`
|
||||||
|
* `textLayout(int, int)`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
To display `TableBlock` as a `TableLayout` specific `MarkwonPlugin` must be used: `TableEntryPlugin`.
|
||||||
|
|
||||||
|
:::warning
|
||||||
|
Do not use `TablePlugin` if you wish to display markdown tables via `TableEntry`. Use **TableEntryPlugin** instead
|
||||||
|
:::
|
||||||
|
|
||||||
|
`TableEntryPlugin` can reuse existing `TablePlugin` to make appearance of tables the same in both contexts:
|
||||||
|
when rendering _natively_ in a TextView and when rendering in RecyclerView with TableEntry.
|
||||||
|
|
||||||
|
* `TableEntryPlugin.create(Context)` - creates plugin with default `TableTheme`
|
||||||
|
* `TableEntryPlugin.create(TableTheme)` - creates plugin with provided `TableTheme`
|
||||||
|
* `TableEntryPlugin.create(TablePlugin.ThemeConfigure)` - creates plugin with theme configured by `ThemeConfigure`
|
||||||
|
* `TableEntryPlugin.create(TablePlugin)` - creates plugin with `TableTheme` used in provided `TablePlugin`
|
||||||
|
|
||||||
|
```java
|
||||||
|
final Markwon markwon = Markwon.builder(context)
|
||||||
|
.usePlugin(TableEntryPlugin.create(context))
|
||||||
|
// other plugins
|
||||||
|
.build();
|
||||||
|
```
|
||||||
|
|
||||||
|
```java
|
||||||
|
final Markwon markwon = Markwon.builder(context)
|
||||||
|
.usePlugin(TableEntryPlugin.create(builder -> builder
|
||||||
|
.tableBorderWidth(0)
|
||||||
|
.tableHeaderRowBackgroundColor(Color.RED)))
|
||||||
|
// other plugins
|
||||||
|
.build();
|
||||||
|
```
|
||||||
|
|
||||||
|
## Table with scrollable content
|
||||||
|
|
||||||
|
To stretch table columns to fit the width of screen or to make table scrollable when content exceeds screen width
|
||||||
|
this layout can be used:
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<HorizontalScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:clipChildren="false"
|
||||||
|
android:clipToPadding="false"
|
||||||
|
android:paddingLeft="16dip"
|
||||||
|
android:paddingTop="8dip"
|
||||||
|
android:paddingRight="16dip"
|
||||||
|
android:paddingBottom="8dip"
|
||||||
|
android:scrollbarStyle="outsideInset">
|
||||||
|
|
||||||
|
<TableLayout
|
||||||
|
android:id="@+id/table_layout"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:stretchColumns="*" />
|
||||||
|
|
||||||
|
</HorizontalScrollView>
|
||||||
|
```
|
153
docs/docs/v4/recycler/README.md
Normal file
153
docs/docs/v4/recycler/README.md
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
# Recycler <Badge text="3.0.0" />
|
||||||
|
|
||||||
|
<MavenBadge4 :artifact="'recycler'" />
|
||||||
|
|
||||||
|
This artifact allows displaying markdown in a set of Android widgets
|
||||||
|
inside a RecyclerView. Can be useful when displaying lengthy markdown
|
||||||
|
content or **displaying certain markdown blocks inside specific widgets**.
|
||||||
|
|
||||||
|
```java
|
||||||
|
// create an adapter that will use a TextView for each block of markdown
|
||||||
|
// `createTextViewIsRoot` accepts a layout in which TextView is the root view
|
||||||
|
final MarkwonAdapter adapter =
|
||||||
|
MarkwonAdapter.createTextViewIsRoot(R.layout.adapter_default_entry);
|
||||||
|
```
|
||||||
|
|
||||||
|
```java
|
||||||
|
// `create` method accepts a layout with TextView and ID of a TextView
|
||||||
|
// which allows wrapping a TextView inside another widget or combine with other widgets
|
||||||
|
final MarkwonAdapter adapter =
|
||||||
|
MarkwonAdapter.create(R.layout.adapter_default_entry, R.id.text_view);
|
||||||
|
|
||||||
|
// initialize RecyclerView (LayoutManager, Decorations, etc)
|
||||||
|
final RecyclerView recyclerView = obtainRecyclerView();
|
||||||
|
|
||||||
|
// set adapter
|
||||||
|
recyclerView.setAdapter(adapter);
|
||||||
|
|
||||||
|
// obtain an instance of Markwon (register all required plugins)
|
||||||
|
final Markwon markwon = obtainMarkwon();
|
||||||
|
|
||||||
|
// set markdown to be displayed
|
||||||
|
adapter.setMarkdown(markwon, "# This is markdown!");
|
||||||
|
|
||||||
|
// NB, adapter does not handle updates on its own, please use
|
||||||
|
// whatever method appropriate for you.
|
||||||
|
adapter.notifyDataSetChanged();
|
||||||
|
```
|
||||||
|
|
||||||
|
Initialized adapter above will use a TextView for each markdown block.
|
||||||
|
In order to tell adapter to render certain blocks differently a `builder` can be used.
|
||||||
|
For example, let's render `FencedCodeBlock` inside a `HorizontalScrollView`:
|
||||||
|
|
||||||
|
```java
|
||||||
|
// we still need to have a _default_ entry
|
||||||
|
final MarkwonAdapter adapter =
|
||||||
|
MarkwonAdapter.builderTextViewIsRoot(R.layout.adapter_default_entry)
|
||||||
|
.include(FencedCodeBlock.class, new FencedCodeBlockEntry())
|
||||||
|
.build();
|
||||||
|
```
|
||||||
|
|
||||||
|
where `FencedCodeBlockEntry` is:
|
||||||
|
|
||||||
|
```java
|
||||||
|
public class FencedCodeBlockEntry extends MarkwonAdapter.Entry<FencedCodeBlock, FencedCodeBlockEntry.Holder> {
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public Holder createHolder(@NonNull LayoutInflater inflater, @NonNull ViewGroup parent) {
|
||||||
|
return new Holder(inflater.inflate(R.layout.adapter_fenced_code_block, parent, false));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void bindHolder(@NonNull Markwon markwon, @NonNull Holder holder, @NonNull FencedCodeBlock node) {
|
||||||
|
markwon.setParsedMarkdown(holder.textView, markwon.render(node));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Holder extends MarkwonAdapter.Holder {
|
||||||
|
|
||||||
|
final TextView textView;
|
||||||
|
|
||||||
|
public Holder(@NonNull View itemView) {
|
||||||
|
super(itemView);
|
||||||
|
|
||||||
|
this.textView = requireView(R.id.text_view);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
and its layout (`R.layout.adapter_fenced_code_block`):
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<HorizontalScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:clipChildren="false"
|
||||||
|
android:clipToPadding="false"
|
||||||
|
android:fillViewport="true"
|
||||||
|
android:paddingLeft="16dip"
|
||||||
|
android:paddingRight="16dip"
|
||||||
|
android:scrollbarStyle="outsideInset">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/text"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="#0f000000"
|
||||||
|
android:fontFamily="monospace"
|
||||||
|
android:lineSpacingExtra="2dip"
|
||||||
|
android:paddingLeft="16dip"
|
||||||
|
android:paddingTop="8dip"
|
||||||
|
android:paddingRight="16dip"
|
||||||
|
android:paddingBottom="8dip"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||||
|
android:textSize="14sp" />
|
||||||
|
|
||||||
|
</HorizontalScrollView>
|
||||||
|
```
|
||||||
|
|
||||||
|
As we apply styling to `FencedCodeBlock` _manually_, we no longer need
|
||||||
|
`Markwon` to apply styling spans for us, so `Markwon` initialization could be:
|
||||||
|
|
||||||
|
```java
|
||||||
|
final Markwon markwon = Markwon.builder(context)
|
||||||
|
// your other plugins
|
||||||
|
.usePlugin(new AbstractMarkwonPlugin() {
|
||||||
|
@Override
|
||||||
|
public void configureVisitor(@NonNull MarkwonVisitor.Builder builder) {
|
||||||
|
builder.on(FencedCodeBlock.class, (visitor, fencedCodeBlock) -> {
|
||||||
|
// we actually won't be applying code spans here, as our custom view will
|
||||||
|
// draw background and apply mono typeface
|
||||||
|
//
|
||||||
|
// NB the `trim` operation on literal (as code will have a new line at the end)
|
||||||
|
final CharSequence code = visitor.configuration()
|
||||||
|
.syntaxHighlight()
|
||||||
|
.highlight(fencedCodeBlock.getInfo(), fencedCodeBlock.getLiteral().trim());
|
||||||
|
visitor.builder().append(code);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.build();
|
||||||
|
```
|
||||||
|
|
||||||
|
Previously we have created a `FencedCodeBlockEntry` but all it does is apply markdown to a TextView.
|
||||||
|
For such a case there is a `SimpleEntry` that could be used instead:
|
||||||
|
|
||||||
|
```java
|
||||||
|
final MarkwonAdapter adapter =
|
||||||
|
MarkwonAdapter.builderTextViewIsRoot(R.layout.adapter_default_entry)
|
||||||
|
.include(FencedCodeBlock.class, SimpleEntry.create(R.layout.adapter_fenced_code_block, R.id.text_view))
|
||||||
|
.build();
|
||||||
|
```
|
||||||
|
|
||||||
|
:::tip
|
||||||
|
`SimpleEntry` also takes care of _caching_ parsed markdown. So each node will be
|
||||||
|
parsed only once and each subsequent adapter binding call will reuse previously cached markdown.
|
||||||
|
:::
|
||||||
|
|
||||||
|
:::tip Tables
|
||||||
|
There is a standalone artifact that adds support for displaying markdown tables
|
||||||
|
natively via `TableLayout`. Please refer to its [documentation](/docs/v3/recycler-table/)
|
||||||
|
:::
|
74
docs/docs/v4/syntax-highlight/README.md
Normal file
74
docs/docs/v4/syntax-highlight/README.md
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
# Syntax highlight
|
||||||
|
|
||||||
|
<MavenBadge4 :artifact="'syntax-highlight'" />
|
||||||
|
|
||||||
|
This is a module to add **syntax highlight** functionality to your markdown rendered with `Markwon` library. It is based on [Prism4j](https://github.com/noties/Prism4j) so lead there to understand how to configure `Prism4j` instance.
|
||||||
|
|
||||||
|
<img :src="$withBase('/art/markwon-syntax-default.png')" alt="theme-default" width="80%">
|
||||||
|
|
||||||
|
|
||||||
|
<img :src="$withBase('/art/markwon-syntax-darkula.png')" alt="theme-darkula" width="80%">
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
First, we need to obtain an instance of `Prism4jSyntaxHighlight` which implements Markwon's `SyntaxHighlight`:
|
||||||
|
|
||||||
|
```java
|
||||||
|
final SyntaxHighlight highlight =
|
||||||
|
Prism4jSyntaxHighlight.create(Prism4j, Prism4jTheme);
|
||||||
|
```
|
||||||
|
|
||||||
|
we also can obtain an instance of `Prism4jSyntaxHighlight` that has a _fallback_ option (if a language is not defined in `Prism4j` instance, fallback language can be used):
|
||||||
|
|
||||||
|
```java
|
||||||
|
final SyntaxHighlight highlight =
|
||||||
|
Prism4jSyntaxHighlight.create(Prism4j, Prism4jTheme, String);
|
||||||
|
```
|
||||||
|
|
||||||
|
Generally obtaining a `Prism4j` instance is pretty easy:
|
||||||
|
|
||||||
|
```java
|
||||||
|
final Prism4j prism4j = new Prism4j(new GrammarLocatorDef());
|
||||||
|
```
|
||||||
|
|
||||||
|
Where `GrammarLocatorDef` is a generated grammar locator (if you use `prism4j-bundler` annotation processor)
|
||||||
|
|
||||||
|
`Prism4jTheme` is a specific type that is defined in this module (`prism4j` doesn't know anything about rendering). It has 2 implementations:
|
||||||
|
|
||||||
|
* `Prism4jThemeDefault`
|
||||||
|
* `Prism4jThemeDarkula`
|
||||||
|
|
||||||
|
Both of them can be obtained via factory method `create`:
|
||||||
|
|
||||||
|
* `Prism4jThemeDefault.create()`
|
||||||
|
* `Prism4jThemeDarkula.create()`
|
||||||
|
|
||||||
|
But of cause nothing is stopping you from defining your own theme:
|
||||||
|
|
||||||
|
```java
|
||||||
|
public interface Prism4jTheme {
|
||||||
|
|
||||||
|
@ColorInt
|
||||||
|
int background();
|
||||||
|
|
||||||
|
@ColorInt
|
||||||
|
int textColor();
|
||||||
|
|
||||||
|
void apply(
|
||||||
|
@NonNull String language,
|
||||||
|
@NonNull Prism4j.Syntax syntax,
|
||||||
|
@NonNull SpannableStringBuilder builder,
|
||||||
|
int start,
|
||||||
|
int end
|
||||||
|
);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
:::tip
|
||||||
|
You can extend `Prism4jThemeBase` which has some helper methods
|
||||||
|
:::
|
||||||
|
|
||||||
|
```java
|
||||||
|
final Markwon markwon = Markwon.builder(context)
|
||||||
|
.usePlugin(SyntaxHighlightPlugin.create(prism4j, prism4jTheme))
|
||||||
|
```
|
Loading…
x
Reference in New Issue
Block a user