Add sample and documentation for inline-parser

This commit is contained in:
Dimitry Ivanov 2019-11-13 14:38:49 +03:00
parent 93a14b4731
commit f2f5026694
12 changed files with 215 additions and 21 deletions

View File

@ -2,6 +2,7 @@
# 4.2.0-SNAPSHOT # 4.2.0-SNAPSHOT
* `MarkwonEditor` to highlight markdown input whilst editing (new module: `markwon-editor`) * `MarkwonEditor` to highlight markdown input whilst editing (new module: `markwon-editor`)
* `MarkwonInlineParser` to customize inline parsing (new module: `markwon-inline-parser`)
* `Markwon#configuration` method to expose `MarkwonConfiguration` via public API * `Markwon#configuration` method to expose `MarkwonConfiguration` via public API
* `HeadingSpan#getLevel` getter * `HeadingSpan#getLevel` getter
* Add `SvgPictureMediaDecoder` in `image` module to deal with SVG without dimensions ([#165]) * Add `SvgPictureMediaDecoder` in `image` module to deal with SVG without dimensions ([#165])

View File

@ -104,6 +104,7 @@ module.exports = {
'/docs/v4/image/', '/docs/v4/image/',
'/docs/v4/image-glide/', '/docs/v4/image-glide/',
'/docs/v4/image-picasso/', '/docs/v4/image-picasso/',
'/docs/v4/inline-parser/',
'/docs/v4/linkify/', '/docs/v4/linkify/',
'/docs/v4/recycler/', '/docs/v4/recycler/',
'/docs/v4/recycler-table/', '/docs/v4/recycler-table/',

View File

@ -0,0 +1,78 @@
# Inline Parser <Badge text="4.2.0" />
**Experimental** commonmark-java inline parser that allows customizing
core features and/or extend with own.
Usage of _internal_ classes:
```java
import org.commonmark.internal.Bracket;
import org.commonmark.internal.Delimiter;
import org.commonmark.internal.ReferenceParser;
import org.commonmark.internal.util.Escaping;
import org.commonmark.internal.util.Html5Entities;
import org.commonmark.internal.util.Parsing;
import org.commonmark.internal.inline.AsteriskDelimiterProcessor;
import org.commonmark.internal.inline.UnderscoreDelimiterProcessor;
```
---
```java
// all default (like current commonmark-java InlineParserImpl)
final InlineParserFactory factory = MarkwonInlineParser.factoryBuilder()
.includeDefaults()
.build();
```
```java
// disable images (current markdown images will be considered as links):
final InlineParserFactory factory = MarkwonInlineParser.factoryBuilder()
.includeDefaults()
.excludeInlineProcessor(BangInlineProcessor.class)
.build();
```
```java
// disable core delimiter processors for `*`|`_` and `**`|`__`
final InlineParserFactory factory = MarkwonInlineParser.factoryBuilder()
.includeDefaults()
.excludeDelimiterProcessor(AsteriskDelimiterProcessor.class)
.excludeDelimiterProcessor(UnderscoreDelimiterProcessor.class)
.build();
```
```java
// disable _all_ markdown inlines except for links (open and close bracket handling `[` & `]`)
final InlineParserFactory inlineParserFactory = MarkwonInlineParser.factoryBuilder()
// note that there is no `includeDefaults` method call
.referencesEnabled(true)
.addInlineProcessor(new OpenBracketInlineProcessor())
.addInlineProcessor(new CloseBracketInlineProcessor())
.build();
```
To use custom InlineParser:
```java
final Markwon markwon = Markwon.builder(this)
.usePlugin(new AbstractMarkwonPlugin() {
@Override
public void configureParser(@NonNull Parser.Builder builder) {
builder.inlineParserFactory(inlineParserFactory);
}
})
.build();
```
---
The list of available inline processors:
* `AutolinkInlineProcessor` (`<` =&gt; `<me@mydoma.in>`)
* `BackslashInlineProcessor` (`\\`)
* `BackticksInlineProcessor` (<code>&#96;</code> =&gt; <code>&#96;code&#96;</code>)
* `BangInlineProcessor` (`!` =&gt; `![alt](#src)`)
* `CloseBracketInlineProcessor` (`]` =&gt; `[link](#href)`, `![alt](#src)`)
* `EntityInlineProcessor` (`&` =&gt; `&amp;`)
* `HtmlInlineProcessor` (`<` =&gt; `<html></html>`)
* `NewLineInlineProcessor` (`\n`)
* `OpenBracketInlineProcessor` (`[` =&gt; `[link](#href)`)

View File

@ -4,17 +4,13 @@
```java ```java
import org.commonmark.internal.Bracket; import org.commonmark.internal.Bracket;
import org.commonmark.internal.Delimiter;
import org.commonmark.internal.ReferenceParser;
import org.commonmark.internal.util.Escaping; import org.commonmark.internal.util.Escaping;
import org.commonmark.internal.util.Html5Entities; import org.commonmark.internal.util.Html5Entities;
import org.commonmark.internal.util.Parsing; import org.commonmark.internal.util.Parsing;
import org.commonmark.internal.Bracket;
import org.commonmark.internal.Delimiter;
import org.commonmark.internal.ReferenceParser;
import org.commonmark.internal.inline.AsteriskDelimiterProcessor; import org.commonmark.internal.inline.AsteriskDelimiterProcessor;
import org.commonmark.internal.inline.UnderscoreDelimiterProcessor; import org.commonmark.internal.inline.UnderscoreDelimiterProcessor;
import org.commonmark.internal.util.Escaping;
import org.commonmark.internal.Bracket;
import org.commonmark.internal.Delimiter;
``` ```
`StaggeredDelimiterProcessor` class source is copied (required for InlineParser) `StaggeredDelimiterProcessor` class source is copied (required for InlineParser)

View File

@ -1,7 +0,0 @@
package io.noties.markwon.inlineparser;
/**
* @since 4.2.0-SNAPSHOT
*/
public class AsteriskDelimiterProcessor extends org.commonmark.internal.inline.AsteriskDelimiterProcessor {
}

View File

@ -6,6 +6,8 @@ import androidx.annotation.Nullable;
import org.commonmark.internal.Bracket; import org.commonmark.internal.Bracket;
import org.commonmark.internal.Delimiter; import org.commonmark.internal.Delimiter;
import org.commonmark.internal.ReferenceParser; import org.commonmark.internal.ReferenceParser;
import org.commonmark.internal.inline.AsteriskDelimiterProcessor;
import org.commonmark.internal.inline.UnderscoreDelimiterProcessor;
import org.commonmark.internal.util.Escaping; import org.commonmark.internal.util.Escaping;
import org.commonmark.node.Link; import org.commonmark.node.Link;
import org.commonmark.node.Node; import org.commonmark.node.Node;

View File

@ -1,7 +0,0 @@
package io.noties.markwon.inlineparser;
/**
* @since 4.2.0-SNAPSHOT
*/
public class UnderscoreDelimiterProcessor extends org.commonmark.internal.inline.UnderscoreDelimiterProcessor {
}

View File

@ -33,6 +33,8 @@
android:name=".editor.EditorActivity" android:name=".editor.EditorActivity"
android:windowSoftInputMode="adjustResize" /> android:windowSoftInputMode="adjustResize" />
<activity android:name=".inlineparser.InlineParserActivity" />
</application> </application>
</manifest> </manifest>

View File

@ -24,6 +24,7 @@ import io.noties.markwon.sample.customextension.CustomExtensionActivity;
import io.noties.markwon.sample.customextension2.CustomExtensionActivity2; import io.noties.markwon.sample.customextension2.CustomExtensionActivity2;
import io.noties.markwon.sample.editor.EditorActivity; import io.noties.markwon.sample.editor.EditorActivity;
import io.noties.markwon.sample.html.HtmlActivity; import io.noties.markwon.sample.html.HtmlActivity;
import io.noties.markwon.sample.inlineparser.InlineParserActivity;
import io.noties.markwon.sample.latex.LatexActivity; import io.noties.markwon.sample.latex.LatexActivity;
import io.noties.markwon.sample.precomputed.PrecomputedActivity; import io.noties.markwon.sample.precomputed.PrecomputedActivity;
import io.noties.markwon.sample.recycler.RecyclerActivity; import io.noties.markwon.sample.recycler.RecyclerActivity;
@ -122,6 +123,10 @@ public class MainActivity extends Activity {
activity = EditorActivity.class; activity = EditorActivity.class;
break; break;
case INLINE_PARSER:
activity = InlineParserActivity.class;
break;
default: default:
throw new IllegalStateException("No Activity is associated with sample-item: " + item); throw new IllegalStateException("No Activity is associated with sample-item: " + item);
} }

View File

@ -23,7 +23,9 @@ public enum Sample {
PRECOMPUTED_TEXT(R.string.sample_precomputed_text), PRECOMPUTED_TEXT(R.string.sample_precomputed_text),
EDITOR(R.string.sample_editor); EDITOR(R.string.sample_editor),
INLINE_PARSER(R.string.sample_inline_parser);
private final int textResId; private final int textResId;

View File

@ -0,0 +1,119 @@
package io.noties.markwon.sample.inlineparser;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.commonmark.node.Block;
import org.commonmark.node.BlockQuote;
import org.commonmark.node.Heading;
import org.commonmark.node.HtmlBlock;
import org.commonmark.node.ListBlock;
import org.commonmark.node.ThematicBreak;
import org.commonmark.parser.InlineParserFactory;
import org.commonmark.parser.Parser;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import io.noties.markwon.AbstractMarkwonPlugin;
import io.noties.markwon.Markwon;
import io.noties.markwon.inlineparser.BackticksInlineProcessor;
import io.noties.markwon.inlineparser.CloseBracketInlineProcessor;
import io.noties.markwon.inlineparser.MarkwonInlineParser;
import io.noties.markwon.inlineparser.OpenBracketInlineProcessor;
import io.noties.markwon.sample.R;
public class InlineParserActivity extends Activity {
private TextView textView;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_text_view);
this.textView = findViewById(R.id.text_view);
// links_only();
disable_code();
}
private void links_only() {
// create an inline-parser-factory that will _ONLY_ parse links
// this would mean:
// * no emphasises (strong and regular aka bold and italics),
// * no images,
// * no code,
// * no HTML entities (&amp;)
// * no HTML tags
// markdown blocks are still parsed
final InlineParserFactory inlineParserFactory = MarkwonInlineParser.factoryBuilder()
.referencesEnabled(true)
.addInlineProcessor(new OpenBracketInlineProcessor())
.addInlineProcessor(new CloseBracketInlineProcessor())
.build();
final Markwon markwon = Markwon.builder(this)
.usePlugin(new AbstractMarkwonPlugin() {
@Override
public void configureParser(@NonNull Parser.Builder builder) {
builder.inlineParserFactory(inlineParserFactory);
}
})
.build();
// note that image is considered a link now
final String md = "**bold_bold-italic_** <u>html-u</u>, [link](#) ![alt](#image) `code`";
markwon.setMarkdown(textView, md);
}
private void disable_code() {
// parses all as usual, but ignores code (inline and block)
final InlineParserFactory inlineParserFactory = MarkwonInlineParser.factoryBuilder()
.includeDefaults()
.excludeInlineProcessor(BackticksInlineProcessor.class)
.build();
// unfortunately there is no _exclude_ method for parser-builder
final Set<Class<? extends Block>> enabledBlocks = new HashSet<Class<? extends Block>>() {{
// IndentedCodeBlock.class and FencedCodeBlock.class are missing
// this is full list (including above) that can be passed to `enabledBlockTypes` method
addAll(Arrays.asList(
BlockQuote.class,
Heading.class,
HtmlBlock.class,
ThematicBreak.class,
ListBlock.class));
}};
final Markwon markwon = Markwon.builder(this)
.usePlugin(new AbstractMarkwonPlugin() {
@Override
public void configureParser(@NonNull Parser.Builder builder) {
builder
.inlineParserFactory(inlineParserFactory)
.enabledBlockTypes(enabledBlocks);
}
})
.build();
final String md = "# Head!\n\n" +
"* one\n" +
"+ two\n\n" +
"and **bold** to `you`!\n\n" +
"> a quote _em_\n\n" +
"```java\n" +
"final int i = 0;\n" +
"```\n\n" +
"**Good day!**";
markwon.setMarkdown(textView, md);
}
}

View File

@ -27,4 +27,6 @@
<string name="sample_editor"># \# Editor\n\n`MarkwonEditor` sample usage to highlight user input in EditText</string> <string name="sample_editor"># \# Editor\n\n`MarkwonEditor` sample usage to highlight user input in EditText</string>
<string name="sample_inline_parser"># \# Inline Parser\n\nUsage of custom inline parser</string>
</resources> </resources>