Add reducer and nodeRenderer
This commit is contained in:
parent
12ef0b5703
commit
128612d5b2
@ -19,7 +19,7 @@
|
|||||||
@click="selectAll"
|
@click="selectAll"
|
||||||
>
|
>
|
||||||
<div class="selected-artifact-script">
|
<div class="selected-artifact-script">
|
||||||
<span class="token keyword">final def</span> markwon_version = <span class="token string">'latest_version'</span>
|
<span class="token keyword">final def</span> markwon_version = <span class="token string">'{{latestVersion}}'</span>
|
||||||
</div>
|
</div>
|
||||||
<br>
|
<br>
|
||||||
<div class="selected-artifact-script" v-for="artifact in selectedArtifacts">
|
<div class="selected-artifact-script" v-for="artifact in selectedArtifacts">
|
||||||
@ -42,7 +42,8 @@ export default {
|
|||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
artifacts,
|
artifacts,
|
||||||
selected: ['core']
|
selected: ['core'],
|
||||||
|
latestVersion: 'latest_version'
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
@ -15,8 +15,8 @@ Markwon.builder(context)
|
|||||||
|
|
||||||
:::danger
|
:::danger
|
||||||
Customizing `MarkwonHtmlRenderer` is not enough to include HTML content in your application.
|
Customizing `MarkwonHtmlRenderer` is not enough to include HTML content in your application.
|
||||||
You must explicitly include [markwon-html](/docs/v3/html/) artifact (include HtmlParser)
|
You must explicitly include [markwon-html](/docs/v3/html/) artifact (includes HtmlParser)
|
||||||
to you project and register `HtmlPlugin`:
|
to your project and register `HtmlPlugin`:
|
||||||
|
|
||||||
```java
|
```java
|
||||||
Markwon.builder(context)
|
Markwon.builder(context)
|
||||||
|
@ -0,0 +1,184 @@
|
|||||||
|
package ru.noties.markwon;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.support.annotation.IdRes;
|
||||||
|
import android.support.annotation.LayoutRes;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import org.commonmark.node.Node;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 3.0.0
|
||||||
|
*/
|
||||||
|
public abstract class MarkwonNodeRenderer {
|
||||||
|
|
||||||
|
public interface ViewProvider<N extends Node> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Please note that you should not attach created View to specified group. It will be done
|
||||||
|
* automatically.
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
View provide(
|
||||||
|
@NonNull LayoutInflater inflater,
|
||||||
|
@NonNull ViewGroup group,
|
||||||
|
@NonNull Markwon markwon,
|
||||||
|
@NonNull N n);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
public static Builder builder(@NonNull ViewProvider<Node> defaultViewProvider) {
|
||||||
|
return new Builder(defaultViewProvider);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param defaultViewProviderLayoutResId layout resource id to be used in default view provider
|
||||||
|
* @param defaultViewProviderTextViewId id of a TextView in specified layout
|
||||||
|
* @return Builder
|
||||||
|
* @see SimpleTextViewProvider
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
public static Builder builder(
|
||||||
|
@LayoutRes int defaultViewProviderLayoutResId,
|
||||||
|
@IdRes int defaultViewProviderTextViewId) {
|
||||||
|
return new Builder(new SimpleTextViewProvider(
|
||||||
|
defaultViewProviderLayoutResId,
|
||||||
|
defaultViewProviderTextViewId));
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract void render(@NonNull ViewGroup group, @NonNull Markwon markwon, @NonNull String markdown);
|
||||||
|
|
||||||
|
public abstract void render(@NonNull ViewGroup group, @NonNull Markwon markwon, @NonNull Node root);
|
||||||
|
|
||||||
|
|
||||||
|
public static class Builder {
|
||||||
|
|
||||||
|
private final ViewProvider<Node> defaultViewProvider;
|
||||||
|
|
||||||
|
private MarkwonReducer reducer;
|
||||||
|
private Map<Class<? extends Node>, ViewProvider<Node>> viewProviders;
|
||||||
|
private LayoutInflater inflater;
|
||||||
|
|
||||||
|
public Builder(@NonNull ViewProvider<Node> defaultViewProvider) {
|
||||||
|
this.defaultViewProvider = defaultViewProvider;
|
||||||
|
this.viewProviders = new HashMap<>(3);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
public Builder reducer(@NonNull MarkwonReducer reducer) {
|
||||||
|
this.reducer = reducer;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
public <N extends Node> Builder viewProvider(
|
||||||
|
@NonNull Class<N> type,
|
||||||
|
@NonNull ViewProvider<? super N> viewProvider) {
|
||||||
|
//noinspection unchecked
|
||||||
|
viewProviders.put(type, (ViewProvider<Node>) viewProvider);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
public Builder inflater(@NonNull LayoutInflater inflater) {
|
||||||
|
this.inflater = inflater;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
public MarkwonNodeRenderer build() {
|
||||||
|
if (reducer == null) {
|
||||||
|
reducer = MarkwonReducer.directChildren();
|
||||||
|
}
|
||||||
|
return new Impl(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class SimpleTextViewProvider implements ViewProvider<Node> {
|
||||||
|
|
||||||
|
private final int layoutResId;
|
||||||
|
private final int textViewId;
|
||||||
|
|
||||||
|
public SimpleTextViewProvider(@LayoutRes int layoutResId, @IdRes int textViewId) {
|
||||||
|
this.layoutResId = layoutResId;
|
||||||
|
this.textViewId = textViewId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public View provide(
|
||||||
|
@NonNull LayoutInflater inflater,
|
||||||
|
@NonNull ViewGroup group,
|
||||||
|
@NonNull Markwon markwon,
|
||||||
|
@NonNull Node node) {
|
||||||
|
final View view = inflater.inflate(layoutResId, group, false);
|
||||||
|
final TextView textView = view.findViewById(textViewId);
|
||||||
|
markwon.setParsedMarkdown(textView, markwon.render(node));
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class Impl extends MarkwonNodeRenderer {
|
||||||
|
|
||||||
|
private final MarkwonReducer reducer;
|
||||||
|
private final Map<Class<? extends Node>, ViewProvider<Node>> viewProviders;
|
||||||
|
private final ViewProvider<Node> defaultViewProvider;
|
||||||
|
|
||||||
|
private LayoutInflater inflater;
|
||||||
|
|
||||||
|
Impl(@NonNull Builder builder) {
|
||||||
|
this.reducer = builder.reducer;
|
||||||
|
this.viewProviders = builder.viewProviders;
|
||||||
|
this.defaultViewProvider = builder.defaultViewProvider;
|
||||||
|
this.inflater = builder.inflater;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void render(@NonNull ViewGroup group, @NonNull Markwon markwon, @NonNull String markdown) {
|
||||||
|
render(group, markwon, markwon.parse(markdown));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void render(@NonNull ViewGroup group, @NonNull Markwon markwon, @NonNull Node root) {
|
||||||
|
|
||||||
|
final LayoutInflater inflater = ensureLayoutInflater(group.getContext());
|
||||||
|
|
||||||
|
ViewProvider<Node> viewProvider;
|
||||||
|
|
||||||
|
for (Node node : reducer.reduce(root)) {
|
||||||
|
viewProvider = viewProvider(node);
|
||||||
|
group.addView(viewProvider.provide(inflater, group, markwon, node));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
private LayoutInflater ensureLayoutInflater(@NonNull Context context) {
|
||||||
|
LayoutInflater inflater = this.inflater;
|
||||||
|
if (inflater == null) {
|
||||||
|
inflater = this.inflater = LayoutInflater.from(context);
|
||||||
|
}
|
||||||
|
return inflater;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
private ViewProvider<Node> viewProvider(@NonNull Node node) {
|
||||||
|
|
||||||
|
// check for specific node view provider
|
||||||
|
final ViewProvider<Node> provider = viewProviders.get(node.getClass());
|
||||||
|
if (provider != null) {
|
||||||
|
return provider;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if it's not present, then we can return a default one
|
||||||
|
return defaultViewProvider;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,57 @@
|
|||||||
|
package ru.noties.markwon;
|
||||||
|
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
|
||||||
|
import org.commonmark.node.Node;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 3.0.0
|
||||||
|
*/
|
||||||
|
public abstract class MarkwonReducer {
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
public static MarkwonReducer directChildren() {
|
||||||
|
return new DirectChildren();
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
public abstract List<Node> reduce(@NonNull Node node);
|
||||||
|
|
||||||
|
|
||||||
|
static class DirectChildren extends MarkwonReducer {
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public List<Node> reduce(@NonNull Node root) {
|
||||||
|
|
||||||
|
final List<Node> list;
|
||||||
|
|
||||||
|
// we will extract all blocks that are direct children of Document
|
||||||
|
Node node = root.getFirstChild();
|
||||||
|
|
||||||
|
// please note, that if there are no children -> we will return a list with
|
||||||
|
// single element (which was supplied)
|
||||||
|
if (node == null) {
|
||||||
|
list = Collections.singletonList(root);
|
||||||
|
} else {
|
||||||
|
|
||||||
|
list = new ArrayList<>();
|
||||||
|
|
||||||
|
Node temp;
|
||||||
|
|
||||||
|
while (node != null) {
|
||||||
|
list.add(node);
|
||||||
|
temp = node.getNext();
|
||||||
|
node.unlink();
|
||||||
|
node = temp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -42,16 +42,10 @@ public abstract class MarkwonHtmlRenderer {
|
|||||||
Builder allowNonClosedTags(boolean allowNonClosedTags);
|
Builder allowNonClosedTags(boolean allowNonClosedTags);
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
Builder setHandler(@NonNull String tagName, @NonNull TagHandler tagHandler);
|
Builder setHandler(@NonNull String tagName, @Nullable TagHandler tagHandler);
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
Builder setHandler(@NonNull Collection<String> tagNames, @NonNull TagHandler tagHandler);
|
Builder setHandler(@NonNull Collection<String> tagNames, @Nullable TagHandler tagHandler);
|
||||||
|
|
||||||
@NonNull
|
|
||||||
Builder removeHandler(@NonNull String tagName);
|
|
||||||
|
|
||||||
@NonNull
|
|
||||||
Builder removeHandlers(@NonNull String... tagNames);
|
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
MarkwonHtmlRenderer build();
|
MarkwonHtmlRenderer build();
|
||||||
|
@ -100,36 +100,26 @@ class MarkwonHtmlRendererImpl extends MarkwonHtmlRenderer {
|
|||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public Builder setHandler(@NonNull String tagName, @NonNull TagHandler tagHandler) {
|
public Builder setHandler(@NonNull String tagName, @Nullable TagHandler tagHandler) {
|
||||||
tagHandlers.put(tagName, tagHandler);
|
if (tagHandler == null) {
|
||||||
return this;
|
tagHandlers.remove(tagName);
|
||||||
}
|
} else {
|
||||||
|
|
||||||
@NonNull
|
|
||||||
@Override
|
|
||||||
public Builder setHandler(@NonNull Collection<String> tagNames, @NonNull TagHandler tagHandler) {
|
|
||||||
for (String tagName : tagNames) {
|
|
||||||
if (tagName != null) {
|
|
||||||
tagHandlers.put(tagName, tagHandler);
|
tagHandlers.put(tagName, tagHandler);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public Builder removeHandler(@NonNull String tagName) {
|
public Builder setHandler(@NonNull Collection<String> tagNames, @Nullable TagHandler tagHandler) {
|
||||||
tagHandlers.remove(tagName);
|
if (tagHandler == null) {
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NonNull
|
|
||||||
@Override
|
|
||||||
public Builder removeHandlers(@NonNull String... tagNames) {
|
|
||||||
for (String tagName : tagNames) {
|
for (String tagName : tagNames) {
|
||||||
if (tagName != null) {
|
|
||||||
tagHandlers.remove(tagName);
|
tagHandlers.remove(tagName);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
for (String tagName : tagNames) {
|
||||||
|
tagHandlers.put(tagName, tagHandler);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,7 @@ import ru.noties.markwon.AbstractMarkwonPlugin;
|
|||||||
import ru.noties.markwon.MarkwonSpansFactory;
|
import ru.noties.markwon.MarkwonSpansFactory;
|
||||||
import ru.noties.markwon.MarkwonVisitor;
|
import ru.noties.markwon.MarkwonVisitor;
|
||||||
import ru.noties.markwon.RenderProps;
|
import ru.noties.markwon.RenderProps;
|
||||||
|
import ru.noties.markwon.core.SimpleBlockNodeVisitor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @since 3.0.0
|
* @since 3.0.0
|
||||||
@ -75,20 +76,7 @@ public class TaskListPlugin extends AbstractMarkwonPlugin {
|
|||||||
@Override
|
@Override
|
||||||
public void configureVisitor(@NonNull MarkwonVisitor.Builder builder) {
|
public void configureVisitor(@NonNull MarkwonVisitor.Builder builder) {
|
||||||
builder
|
builder
|
||||||
.on(TaskListBlock.class, new MarkwonVisitor.NodeVisitor<TaskListBlock>() {
|
.on(TaskListBlock.class, new SimpleBlockNodeVisitor())
|
||||||
@Override
|
|
||||||
public void visit(@NonNull MarkwonVisitor visitor, @NonNull TaskListBlock taskListBlock) {
|
|
||||||
|
|
||||||
visitor.ensureNewLine();
|
|
||||||
|
|
||||||
visitor.visitChildren(taskListBlock);
|
|
||||||
|
|
||||||
if (visitor.hasNext(taskListBlock)) {
|
|
||||||
visitor.ensureNewLine();
|
|
||||||
visitor.forceNewLine();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.on(TaskListItem.class, new MarkwonVisitor.NodeVisitor<TaskListItem>() {
|
.on(TaskListItem.class, new MarkwonVisitor.NodeVisitor<TaskListItem>() {
|
||||||
@Override
|
@Override
|
||||||
public void visit(@NonNull MarkwonVisitor visitor, @NonNull TaskListItem taskListItem) {
|
public void visit(@NonNull MarkwonVisitor visitor, @NonNull TaskListItem taskListItem) {
|
||||||
|
@ -14,6 +14,7 @@ import org.commonmark.node.Node;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import ru.noties.markwon.Markwon;
|
import ru.noties.markwon.Markwon;
|
||||||
|
import ru.noties.markwon.MarkwonReducer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adapter to display markdown in a RecyclerView. It is done by extracting root blocks from a
|
* Adapter to display markdown in a RecyclerView. It is done by extracting root blocks from a
|
||||||
@ -92,7 +93,7 @@ public abstract class MarkwonAdapter extends RecyclerView.Adapter<MarkwonAdapter
|
|||||||
* @see #include(Class, Entry)
|
* @see #include(Class, Entry)
|
||||||
* @see #defaultEntry(int)
|
* @see #defaultEntry(int)
|
||||||
* @see #defaultEntry(Entry)
|
* @see #defaultEntry(Entry)
|
||||||
* @see #reducer(Reducer)
|
* @see #reducer(MarkwonReducer)
|
||||||
*/
|
*/
|
||||||
public interface Builder {
|
public interface Builder {
|
||||||
|
|
||||||
@ -136,15 +137,15 @@ public abstract class MarkwonAdapter extends RecyclerView.Adapter<MarkwonAdapter
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Specify how root Node will be <em>reduced</em> to a list of nodes. There is a default
|
* Specify how root Node will be <em>reduced</em> to a list of nodes. There is a default
|
||||||
* {@link Reducer} that will be used if not provided explicitly (there is no need to
|
* {@link MarkwonReducer} that will be used if not provided explicitly (there is no need to
|
||||||
* register your own unless you require it).
|
* register your own unless you require it).
|
||||||
*
|
*
|
||||||
* @param reducer {@link Reducer}
|
* @param reducer {@link MarkwonReducer}
|
||||||
* @return self
|
* @return self
|
||||||
* @see Reducer
|
* @see MarkwonReducer
|
||||||
*/
|
*/
|
||||||
@NonNull
|
@NonNull
|
||||||
Builder reducer(@NonNull Reducer reducer);
|
Builder reducer(@NonNull MarkwonReducer reducer);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return {@link MarkwonAdapter}
|
* @return {@link MarkwonAdapter}
|
||||||
@ -169,12 +170,6 @@ public abstract class MarkwonAdapter extends RecyclerView.Adapter<MarkwonAdapter
|
|||||||
void clear();
|
void clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface Reducer {
|
|
||||||
|
|
||||||
@NonNull
|
|
||||||
List<Node> reduce(@NonNull Node root);
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract void setMarkdown(@NonNull Markwon markwon, @NonNull String markdown);
|
public abstract void setMarkdown(@NonNull Markwon markwon, @NonNull String markdown);
|
||||||
|
|
||||||
public abstract void setParsedMarkdown(@NonNull Markwon markwon, @NonNull Node document);
|
public abstract void setParsedMarkdown(@NonNull Markwon markwon, @NonNull Node document);
|
||||||
|
@ -7,17 +7,17 @@ import android.view.ViewGroup;
|
|||||||
|
|
||||||
import org.commonmark.node.Node;
|
import org.commonmark.node.Node;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import ru.noties.markwon.Markwon;
|
import ru.noties.markwon.Markwon;
|
||||||
|
import ru.noties.markwon.MarkwonReducer;
|
||||||
|
|
||||||
class MarkwonAdapterImpl extends MarkwonAdapter {
|
class MarkwonAdapterImpl extends MarkwonAdapter {
|
||||||
|
|
||||||
private final SparseArray<Entry<Node, Holder>> entries;
|
private final SparseArray<Entry<Node, Holder>> entries;
|
||||||
private final Entry<Node, Holder> defaultEntry;
|
private final Entry<Node, Holder> defaultEntry;
|
||||||
private final Reducer reducer;
|
private final MarkwonReducer reducer;
|
||||||
|
|
||||||
private LayoutInflater layoutInflater;
|
private LayoutInflater layoutInflater;
|
||||||
|
|
||||||
@ -28,7 +28,7 @@ class MarkwonAdapterImpl extends MarkwonAdapter {
|
|||||||
MarkwonAdapterImpl(
|
MarkwonAdapterImpl(
|
||||||
@NonNull SparseArray<Entry<Node, Holder>> entries,
|
@NonNull SparseArray<Entry<Node, Holder>> entries,
|
||||||
@NonNull Entry<Node, Holder> defaultEntry,
|
@NonNull Entry<Node, Holder> defaultEntry,
|
||||||
@NonNull Reducer reducer) {
|
@NonNull MarkwonReducer reducer) {
|
||||||
this.entries = entries;
|
this.entries = entries;
|
||||||
this.defaultEntry = defaultEntry;
|
this.defaultEntry = defaultEntry;
|
||||||
this.reducer = reducer;
|
this.reducer = reducer;
|
||||||
@ -133,7 +133,7 @@ class MarkwonAdapterImpl extends MarkwonAdapter {
|
|||||||
private final SparseArray<Entry<Node, Holder>> entries = new SparseArray<>(3);
|
private final SparseArray<Entry<Node, Holder>> entries = new SparseArray<>(3);
|
||||||
|
|
||||||
private Entry<Node, Holder> defaultEntry;
|
private Entry<Node, Holder> defaultEntry;
|
||||||
private Reducer reducer;
|
private MarkwonReducer reducer;
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
@ -163,7 +163,7 @@ class MarkwonAdapterImpl extends MarkwonAdapter {
|
|||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public Builder reducer(@NonNull Reducer reducer) {
|
public Builder reducer(@NonNull MarkwonReducer reducer) {
|
||||||
this.reducer = reducer;
|
this.reducer = reducer;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@ -178,33 +178,10 @@ class MarkwonAdapterImpl extends MarkwonAdapter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (reducer == null) {
|
if (reducer == null) {
|
||||||
reducer = new ReducerImpl();
|
reducer = MarkwonReducer.directChildren();
|
||||||
}
|
}
|
||||||
|
|
||||||
return new MarkwonAdapterImpl(entries, defaultEntry, reducer);
|
return new MarkwonAdapterImpl(entries, defaultEntry, reducer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static class ReducerImpl implements Reducer {
|
|
||||||
|
|
||||||
@NonNull
|
|
||||||
@Override
|
|
||||||
public List<Node> reduce(@NonNull Node root) {
|
|
||||||
|
|
||||||
final List<Node> list = new ArrayList<>();
|
|
||||||
|
|
||||||
// we will extract all blocks that are direct children of Document
|
|
||||||
Node node = root.getFirstChild();
|
|
||||||
Node temp;
|
|
||||||
|
|
||||||
while (node != null) {
|
|
||||||
list.add(node);
|
|
||||||
temp = node.getNext();
|
|
||||||
node.unlink();
|
|
||||||
node = temp;
|
|
||||||
}
|
|
||||||
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -2,12 +2,13 @@
|
|||||||
|
|
||||||
<string name="app_name">MarkwonSample</string>
|
<string name="app_name">MarkwonSample</string>
|
||||||
|
|
||||||
|
<!--do not indent (will be treated as code block otherwise)-->
|
||||||
<string name="input"><![CDATA[
|
<string name="input"><![CDATA[
|
||||||
# Hello! @ic-android-black-24\n\n
|
# Hello! @ic-android-black-24\n\n
|
||||||
Home 36 black: @ic-home-black-36\n\n
|
Home 36 black: @ic-home-black-36\n\n
|
||||||
Memory 48 black: @ic-memory-black-48\n\n
|
Memory 48 black: @ic-memory-black-48\n\n
|
||||||
### I AM ANOTHER HEADER\n\n
|
### I AM ANOTHER HEADER\n\n
|
||||||
Sentiment Satisfied 64 red: @ic-sentiment_satisfied-red-64
|
Sentiment Satisfied 64 red: @ic-sentiment_satisfied-red-64
|
||||||
]]>
|
]]>
|
||||||
</string>
|
</string>
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user