BlockHandler abstraction in core module
This commit is contained in:
parent
69c2d1255c
commit
0b813e43f7
@ -14,6 +14,7 @@ dependency (must be explicitly added to `Markwon` whilst configuring)
|
|||||||
* non-empty bounds for `AsyncDrawable` when no dimensions are not yet available ([#189])
|
* non-empty bounds for `AsyncDrawable` when no dimensions are not yet available ([#189])
|
||||||
* `linkify` - option to use `LinkifyCompat` in `LinkifyPlugin` ([#201])
|
* `linkify` - option to use `LinkifyCompat` in `LinkifyPlugin` ([#201])
|
||||||
<br>Thanks to [@drakeet]
|
<br>Thanks to [@drakeet]
|
||||||
|
* `MarkwonVisitor.BlockHandler` and `BlockHandlerDef` implementation to control how blocks insert new lines after them
|
||||||
|
|
||||||
|
|
||||||
```java
|
```java
|
||||||
|
@ -0,0 +1,23 @@
|
|||||||
|
package io.noties.markwon;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
|
import org.commonmark.node.Node;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since $nap;
|
||||||
|
*/
|
||||||
|
public class BlockHandlerDef implements MarkwonVisitor.BlockHandler {
|
||||||
|
@Override
|
||||||
|
public void blockStart(@NonNull MarkwonVisitor visitor, @NonNull Node node) {
|
||||||
|
visitor.ensureNewLine();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void blockEnd(@NonNull MarkwonVisitor visitor, @NonNull Node node) {
|
||||||
|
if (visitor.hasNext(node)) {
|
||||||
|
visitor.ensureNewLine();
|
||||||
|
visitor.forceNewLine();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -23,6 +23,19 @@ public interface MarkwonVisitor extends Visitor {
|
|||||||
void visit(@NonNull MarkwonVisitor visitor, @NonNull N n);
|
void visit(@NonNull MarkwonVisitor visitor, @NonNull N n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Primary purpose is to control the spacing applied before/after certain blocks, which
|
||||||
|
* visitors are created elsewhere
|
||||||
|
*
|
||||||
|
* @since $nap;
|
||||||
|
*/
|
||||||
|
interface BlockHandler {
|
||||||
|
|
||||||
|
void blockStart(@NonNull MarkwonVisitor visitor, @NonNull Node node);
|
||||||
|
|
||||||
|
void blockEnd(@NonNull MarkwonVisitor visitor, @NonNull Node node);
|
||||||
|
}
|
||||||
|
|
||||||
interface Builder {
|
interface Builder {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -33,6 +46,16 @@ public interface MarkwonVisitor extends Visitor {
|
|||||||
@NonNull
|
@NonNull
|
||||||
<N extends Node> Builder on(@NonNull Class<N> node, @Nullable NodeVisitor<? super N> nodeVisitor);
|
<N extends Node> Builder on(@NonNull Class<N> node, @Nullable NodeVisitor<? super N> nodeVisitor);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param blockHandler to handle block start/end
|
||||||
|
* @see BlockHandler
|
||||||
|
* @see BlockHandlerDef
|
||||||
|
* @since $nap;
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("UnusedReturnValue")
|
||||||
|
@NonNull
|
||||||
|
Builder blockHandler(@NonNull BlockHandler blockHandler);
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
MarkwonVisitor build(@NonNull MarkwonConfiguration configuration, @NonNull RenderProps renderProps);
|
MarkwonVisitor build(@NonNull MarkwonConfiguration configuration, @NonNull RenderProps renderProps);
|
||||||
}
|
}
|
||||||
@ -133,4 +156,14 @@ public interface MarkwonVisitor extends Visitor {
|
|||||||
*/
|
*/
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
<N extends Node> void setSpansForNodeOptional(@NonNull Class<N> node, int start);
|
<N extends Node> void setSpansForNodeOptional(@NonNull Class<N> node, int start);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since $nap;
|
||||||
|
*/
|
||||||
|
void blockStart(@NonNull Node node);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since $nap;
|
||||||
|
*/
|
||||||
|
void blockEnd(@NonNull Node node);
|
||||||
}
|
}
|
||||||
|
@ -45,15 +45,20 @@ class MarkwonVisitorImpl implements MarkwonVisitor {
|
|||||||
|
|
||||||
private final Map<Class<? extends Node>, NodeVisitor<? extends Node>> nodes;
|
private final Map<Class<? extends Node>, NodeVisitor<? extends Node>> nodes;
|
||||||
|
|
||||||
|
// @since $nap;
|
||||||
|
private final BlockHandler blockHandler;
|
||||||
|
|
||||||
MarkwonVisitorImpl(
|
MarkwonVisitorImpl(
|
||||||
@NonNull MarkwonConfiguration configuration,
|
@NonNull MarkwonConfiguration configuration,
|
||||||
@NonNull RenderProps renderProps,
|
@NonNull RenderProps renderProps,
|
||||||
@NonNull SpannableBuilder builder,
|
@NonNull SpannableBuilder builder,
|
||||||
@NonNull Map<Class<? extends Node>, NodeVisitor<? extends Node>> nodes) {
|
@NonNull Map<Class<? extends Node>, NodeVisitor<? extends Node>> nodes,
|
||||||
|
@NonNull BlockHandler blockHandler) {
|
||||||
this.configuration = configuration;
|
this.configuration = configuration;
|
||||||
this.renderProps = renderProps;
|
this.renderProps = renderProps;
|
||||||
this.builder = builder;
|
this.builder = builder;
|
||||||
this.nodes = nodes;
|
this.nodes = nodes;
|
||||||
|
this.blockHandler = blockHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -268,9 +273,20 @@ class MarkwonVisitorImpl implements MarkwonVisitor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void blockStart(@NonNull Node node) {
|
||||||
|
blockHandler.blockStart(this, node);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void blockEnd(@NonNull Node node) {
|
||||||
|
blockHandler.blockEnd(this, node);
|
||||||
|
}
|
||||||
|
|
||||||
static class BuilderImpl implements Builder {
|
static class BuilderImpl implements Builder {
|
||||||
|
|
||||||
private final Map<Class<? extends Node>, NodeVisitor<? extends Node>> nodes = new HashMap<>();
|
private final Map<Class<? extends Node>, NodeVisitor<? extends Node>> nodes = new HashMap<>();
|
||||||
|
private BlockHandler blockHandler;
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
@ -290,14 +306,28 @@ class MarkwonVisitorImpl implements MarkwonVisitor {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public Builder blockHandler(@NonNull BlockHandler blockHandler) {
|
||||||
|
this.blockHandler = blockHandler;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public MarkwonVisitor build(@NonNull MarkwonConfiguration configuration, @NonNull RenderProps renderProps) {
|
public MarkwonVisitor build(@NonNull MarkwonConfiguration configuration, @NonNull RenderProps renderProps) {
|
||||||
|
// @since $nap;
|
||||||
|
BlockHandler blockHandler = this.blockHandler;
|
||||||
|
if (blockHandler == null) {
|
||||||
|
blockHandler = new BlockHandlerDef();
|
||||||
|
}
|
||||||
|
|
||||||
return new MarkwonVisitorImpl(
|
return new MarkwonVisitorImpl(
|
||||||
configuration,
|
configuration,
|
||||||
renderProps,
|
renderProps,
|
||||||
new SpannableBuilder(),
|
new SpannableBuilder(),
|
||||||
Collections.unmodifiableMap(nodes));
|
Collections.unmodifiableMap(nodes),
|
||||||
|
blockHandler);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@ public class SoftBreakAddsNewLinePlugin extends AbstractMarkwonPlugin {
|
|||||||
builder.on(SoftLineBreak.class, new MarkwonVisitor.NodeVisitor<SoftLineBreak>() {
|
builder.on(SoftLineBreak.class, new MarkwonVisitor.NodeVisitor<SoftLineBreak>() {
|
||||||
@Override
|
@Override
|
||||||
public void visit(@NonNull MarkwonVisitor visitor, @NonNull SoftLineBreak softLineBreak) {
|
public void visit(@NonNull MarkwonVisitor visitor, @NonNull SoftLineBreak softLineBreak) {
|
||||||
visitor.forceNewLine();
|
visitor.ensureNewLine();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -210,17 +210,14 @@ public class CorePlugin extends AbstractMarkwonPlugin {
|
|||||||
@Override
|
@Override
|
||||||
public void visit(@NonNull MarkwonVisitor visitor, @NonNull BlockQuote blockQuote) {
|
public void visit(@NonNull MarkwonVisitor visitor, @NonNull BlockQuote blockQuote) {
|
||||||
|
|
||||||
visitor.ensureNewLine();
|
visitor.blockStart(blockQuote);
|
||||||
|
|
||||||
final int length = visitor.length();
|
final int length = visitor.length();
|
||||||
|
|
||||||
visitor.visitChildren(blockQuote);
|
visitor.visitChildren(blockQuote);
|
||||||
visitor.setSpansForNodeOptional(blockQuote, length);
|
visitor.setSpansForNodeOptional(blockQuote, length);
|
||||||
|
|
||||||
if (visitor.hasNext(blockQuote)) {
|
visitor.blockEnd(blockQuote);
|
||||||
visitor.ensureNewLine();
|
|
||||||
visitor.forceNewLine();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -316,7 +313,7 @@ public class CorePlugin extends AbstractMarkwonPlugin {
|
|||||||
@NonNull String code,
|
@NonNull String code,
|
||||||
@NonNull Node node) {
|
@NonNull Node node) {
|
||||||
|
|
||||||
visitor.ensureNewLine();
|
visitor.blockStart(node);
|
||||||
|
|
||||||
final int length = visitor.length();
|
final int length = visitor.length();
|
||||||
|
|
||||||
@ -333,10 +330,7 @@ public class CorePlugin extends AbstractMarkwonPlugin {
|
|||||||
|
|
||||||
visitor.setSpansForNodeOptional(node, length);
|
visitor.setSpansForNodeOptional(node, length);
|
||||||
|
|
||||||
if (visitor.hasNext(node)) {
|
visitor.blockEnd(node);
|
||||||
visitor.ensureNewLine();
|
|
||||||
visitor.forceNewLine();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void bulletList(@NonNull MarkwonVisitor.Builder builder) {
|
private static void bulletList(@NonNull MarkwonVisitor.Builder builder) {
|
||||||
@ -402,7 +396,7 @@ public class CorePlugin extends AbstractMarkwonPlugin {
|
|||||||
@Override
|
@Override
|
||||||
public void visit(@NonNull MarkwonVisitor visitor, @NonNull ThematicBreak thematicBreak) {
|
public void visit(@NonNull MarkwonVisitor visitor, @NonNull ThematicBreak thematicBreak) {
|
||||||
|
|
||||||
visitor.ensureNewLine();
|
visitor.blockStart(thematicBreak);
|
||||||
|
|
||||||
final int length = visitor.length();
|
final int length = visitor.length();
|
||||||
|
|
||||||
@ -411,10 +405,7 @@ public class CorePlugin extends AbstractMarkwonPlugin {
|
|||||||
|
|
||||||
visitor.setSpansForNodeOptional(thematicBreak, length);
|
visitor.setSpansForNodeOptional(thematicBreak, length);
|
||||||
|
|
||||||
if (visitor.hasNext(thematicBreak)) {
|
visitor.blockEnd(thematicBreak);
|
||||||
visitor.ensureNewLine();
|
|
||||||
visitor.forceNewLine();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -424,7 +415,7 @@ public class CorePlugin extends AbstractMarkwonPlugin {
|
|||||||
@Override
|
@Override
|
||||||
public void visit(@NonNull MarkwonVisitor visitor, @NonNull Heading heading) {
|
public void visit(@NonNull MarkwonVisitor visitor, @NonNull Heading heading) {
|
||||||
|
|
||||||
visitor.ensureNewLine();
|
visitor.blockStart(heading);
|
||||||
|
|
||||||
final int length = visitor.length();
|
final int length = visitor.length();
|
||||||
visitor.visitChildren(heading);
|
visitor.visitChildren(heading);
|
||||||
@ -433,10 +424,7 @@ public class CorePlugin extends AbstractMarkwonPlugin {
|
|||||||
|
|
||||||
visitor.setSpansForNodeOptional(heading, length);
|
visitor.setSpansForNodeOptional(heading, length);
|
||||||
|
|
||||||
if (visitor.hasNext(heading)) {
|
visitor.blockEnd(heading);
|
||||||
visitor.ensureNewLine();
|
|
||||||
visitor.forceNewLine();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -467,7 +455,7 @@ public class CorePlugin extends AbstractMarkwonPlugin {
|
|||||||
final boolean inTightList = isInTightList(paragraph);
|
final boolean inTightList = isInTightList(paragraph);
|
||||||
|
|
||||||
if (!inTightList) {
|
if (!inTightList) {
|
||||||
visitor.ensureNewLine();
|
visitor.blockStart(paragraph);
|
||||||
}
|
}
|
||||||
|
|
||||||
final int length = visitor.length();
|
final int length = visitor.length();
|
||||||
@ -478,9 +466,8 @@ public class CorePlugin extends AbstractMarkwonPlugin {
|
|||||||
// @since 1.1.1 apply paragraph span
|
// @since 1.1.1 apply paragraph span
|
||||||
visitor.setSpansForNodeOptional(paragraph, length);
|
visitor.setSpansForNodeOptional(paragraph, length);
|
||||||
|
|
||||||
if (!inTightList && visitor.hasNext(paragraph)) {
|
if (!inTightList) {
|
||||||
visitor.ensureNewLine();
|
visitor.blockEnd(paragraph);
|
||||||
visitor.forceNewLine();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -17,19 +17,16 @@ public class SimpleBlockNodeVisitor implements MarkwonVisitor.NodeVisitor<Node>
|
|||||||
@Override
|
@Override
|
||||||
public void visit(@NonNull MarkwonVisitor visitor, @NonNull Node node) {
|
public void visit(@NonNull MarkwonVisitor visitor, @NonNull Node node) {
|
||||||
|
|
||||||
|
visitor.blockStart(node);
|
||||||
|
|
||||||
// @since 3.0.1 we keep track of start in order to apply spans (optionally)
|
// @since 3.0.1 we keep track of start in order to apply spans (optionally)
|
||||||
final int length = visitor.length();
|
final int length = visitor.length();
|
||||||
|
|
||||||
visitor.ensureNewLine();
|
|
||||||
|
|
||||||
visitor.visitChildren(node);
|
visitor.visitChildren(node);
|
||||||
|
|
||||||
// @since 3.0.1 we apply optional spans
|
// @since 3.0.1 we apply optional spans
|
||||||
visitor.setSpansForNodeOptional(node, length);
|
visitor.setSpansForNodeOptional(node, length);
|
||||||
|
|
||||||
if (visitor.hasNext(node)) {
|
visitor.blockEnd(node);
|
||||||
visitor.ensureNewLine();
|
|
||||||
visitor.forceNewLine();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,8 @@ public class AbstractMarkwonVisitorImpl extends MarkwonVisitorImpl {
|
|||||||
@NonNull MarkwonConfiguration configuration,
|
@NonNull MarkwonConfiguration configuration,
|
||||||
@NonNull RenderProps renderProps,
|
@NonNull RenderProps renderProps,
|
||||||
@NonNull SpannableBuilder spannableBuilder,
|
@NonNull SpannableBuilder spannableBuilder,
|
||||||
@NonNull Map<Class<? extends Node>, NodeVisitor<? extends Node>> nodes) {
|
@NonNull Map<Class<? extends Node>, NodeVisitor<? extends Node>> nodes,
|
||||||
super(configuration, renderProps, spannableBuilder, nodes);
|
@NonNull BlockHandler blockHandler) {
|
||||||
|
super(configuration, renderProps, spannableBuilder, nodes, blockHandler);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,8 @@ public class MarkwonVisitorImplTest {
|
|||||||
mock(MarkwonConfiguration.class),
|
mock(MarkwonConfiguration.class),
|
||||||
renderProps,
|
renderProps,
|
||||||
spannableBuilder,
|
spannableBuilder,
|
||||||
Collections.<Class<? extends Node>, MarkwonVisitor.NodeVisitor<? extends Node>>emptyMap());
|
Collections.<Class<? extends Node>, MarkwonVisitor.NodeVisitor<? extends Node>>emptyMap(),
|
||||||
|
mock(MarkwonVisitor.BlockHandler.class));
|
||||||
|
|
||||||
impl.clear();
|
impl.clear();
|
||||||
|
|
||||||
@ -61,7 +62,8 @@ public class MarkwonVisitorImplTest {
|
|||||||
mock(MarkwonConfiguration.class),
|
mock(MarkwonConfiguration.class),
|
||||||
mock(RenderProps.class),
|
mock(RenderProps.class),
|
||||||
builder,
|
builder,
|
||||||
Collections.<Class<? extends Node>, MarkwonVisitor.NodeVisitor<? extends Node>>emptyMap());
|
Collections.<Class<? extends Node>, MarkwonVisitor.NodeVisitor<? extends Node>>emptyMap(),
|
||||||
|
mock(MarkwonVisitor.BlockHandler.class));
|
||||||
|
|
||||||
// at the start - won't add anything
|
// at the start - won't add anything
|
||||||
impl.ensureNewLine();
|
impl.ensureNewLine();
|
||||||
@ -92,7 +94,8 @@ public class MarkwonVisitorImplTest {
|
|||||||
mock(MarkwonConfiguration.class),
|
mock(MarkwonConfiguration.class),
|
||||||
mock(RenderProps.class),
|
mock(RenderProps.class),
|
||||||
builder,
|
builder,
|
||||||
Collections.<Class<? extends Node>, MarkwonVisitor.NodeVisitor<? extends Node>>emptyMap());
|
Collections.<Class<? extends Node>, MarkwonVisitor.NodeVisitor<? extends Node>>emptyMap(),
|
||||||
|
mock(MarkwonVisitor.BlockHandler.class));
|
||||||
|
|
||||||
assertEquals(0, builder.length());
|
assertEquals(0, builder.length());
|
||||||
|
|
||||||
@ -144,7 +147,8 @@ public class MarkwonVisitorImplTest {
|
|||||||
mock(MarkwonConfiguration.class),
|
mock(MarkwonConfiguration.class),
|
||||||
mock(RenderProps.class),
|
mock(RenderProps.class),
|
||||||
mock(SpannableBuilder.class),
|
mock(SpannableBuilder.class),
|
||||||
Collections.<Class<? extends Node>, MarkwonVisitor.NodeVisitor<? extends Node>>emptyMap());
|
Collections.<Class<? extends Node>, MarkwonVisitor.NodeVisitor<? extends Node>>emptyMap(),
|
||||||
|
mock(MarkwonVisitor.BlockHandler.class));
|
||||||
|
|
||||||
final BlockQuote node = mock(BlockQuote.class);
|
final BlockQuote node = mock(BlockQuote.class);
|
||||||
final Node child = mock(Node.class);
|
final Node child = mock(Node.class);
|
||||||
@ -163,7 +167,8 @@ public class MarkwonVisitorImplTest {
|
|||||||
mock(MarkwonConfiguration.class),
|
mock(MarkwonConfiguration.class),
|
||||||
mock(RenderProps.class),
|
mock(RenderProps.class),
|
||||||
mock(SpannableBuilder.class),
|
mock(SpannableBuilder.class),
|
||||||
Collections.<Class<? extends Node>, MarkwonVisitor.NodeVisitor<? extends Node>>emptyMap());
|
Collections.<Class<? extends Node>, MarkwonVisitor.NodeVisitor<? extends Node>>emptyMap(),
|
||||||
|
mock(MarkwonVisitor.BlockHandler.class));
|
||||||
|
|
||||||
final Node noNext = mock(Node.class);
|
final Node noNext = mock(Node.class);
|
||||||
assertFalse(impl.hasNext(noNext));
|
assertFalse(impl.hasNext(noNext));
|
||||||
@ -195,7 +200,8 @@ public class MarkwonVisitorImplTest {
|
|||||||
mock(MarkwonConfiguration.class),
|
mock(MarkwonConfiguration.class),
|
||||||
mock(RenderProps.class),
|
mock(RenderProps.class),
|
||||||
builder,
|
builder,
|
||||||
Collections.<Class<? extends Node>, MarkwonVisitor.NodeVisitor<? extends Node>>emptyMap());
|
Collections.<Class<? extends Node>, MarkwonVisitor.NodeVisitor<? extends Node>>emptyMap(),
|
||||||
|
mock(MarkwonVisitor.BlockHandler.class));
|
||||||
|
|
||||||
for (int i = 0; i < 13; i++) {
|
for (int i = 0; i < 13; i++) {
|
||||||
builder.setLength(i);
|
builder.setLength(i);
|
||||||
@ -221,7 +227,8 @@ public class MarkwonVisitorImplTest {
|
|||||||
configuration,
|
configuration,
|
||||||
mock(RenderProps.class),
|
mock(RenderProps.class),
|
||||||
mock(SpannableBuilder.class),
|
mock(SpannableBuilder.class),
|
||||||
Collections.<Class<? extends Node>, MarkwonVisitor.NodeVisitor<? extends Node>>emptyMap());
|
Collections.<Class<? extends Node>, MarkwonVisitor.NodeVisitor<? extends Node>>emptyMap(),
|
||||||
|
mock(MarkwonVisitor.BlockHandler.class));
|
||||||
|
|
||||||
impl.setSpansForNode(Node.class, 0);
|
impl.setSpansForNode(Node.class, 0);
|
||||||
|
|
||||||
@ -252,7 +259,8 @@ public class MarkwonVisitorImplTest {
|
|||||||
configuration,
|
configuration,
|
||||||
mock(RenderProps.class),
|
mock(RenderProps.class),
|
||||||
builder,
|
builder,
|
||||||
Collections.<Class<? extends Node>, MarkwonVisitor.NodeVisitor<? extends Node>>emptyMap());
|
Collections.<Class<? extends Node>, MarkwonVisitor.NodeVisitor<? extends Node>>emptyMap(),
|
||||||
|
mock(MarkwonVisitor.BlockHandler.class));
|
||||||
|
|
||||||
// append something
|
// append something
|
||||||
builder.append("no-spans-test");
|
builder.append("no-spans-test");
|
||||||
|
@ -107,6 +107,12 @@ public class CorePluginTest {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public MarkwonVisitor.Builder blockHandler(@NonNull MarkwonVisitor.BlockHandler blockHandler) {
|
||||||
|
throw new RuntimeException();
|
||||||
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public MarkwonVisitor build(@NonNull MarkwonConfiguration configuration, @NonNull RenderProps renderProps) {
|
public MarkwonVisitor build(@NonNull MarkwonConfiguration configuration, @NonNull RenderProps renderProps) {
|
||||||
|
@ -91,7 +91,8 @@ public class SyntaxHighlightTest {
|
|||||||
configuration,
|
configuration,
|
||||||
mock(RenderProps.class),
|
mock(RenderProps.class),
|
||||||
new SpannableBuilder(),
|
new SpannableBuilder(),
|
||||||
visitorMap);
|
visitorMap,
|
||||||
|
mock(MarkwonVisitor.BlockHandler.class));
|
||||||
|
|
||||||
final SpannableBuilder builder = visitor.builder();
|
final SpannableBuilder builder = visitor.builder();
|
||||||
|
|
||||||
|
@ -191,7 +191,7 @@ public class JLatexMathPlugin extends AbstractMarkwonPlugin {
|
|||||||
@Override
|
@Override
|
||||||
public void visit(@NonNull MarkwonVisitor visitor, @NonNull JLatexMathBlock jLatexMathBlock) {
|
public void visit(@NonNull MarkwonVisitor visitor, @NonNull JLatexMathBlock jLatexMathBlock) {
|
||||||
|
|
||||||
visitor.ensureNewLine();
|
visitor.blockStart(jLatexMathBlock);
|
||||||
|
|
||||||
final String latex = jLatexMathBlock.latex();
|
final String latex = jLatexMathBlock.latex();
|
||||||
|
|
||||||
@ -217,10 +217,7 @@ public class JLatexMathPlugin extends AbstractMarkwonPlugin {
|
|||||||
|
|
||||||
visitor.setSpans(length, span);
|
visitor.setSpans(length, span);
|
||||||
|
|
||||||
if (visitor.hasNext(jLatexMathBlock)) {
|
visitor.blockEnd(jLatexMathBlock);
|
||||||
visitor.ensureNewLine();
|
|
||||||
visitor.forceNewLine();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -121,12 +121,15 @@ public class TablePlugin extends AbstractMarkwonPlugin {
|
|||||||
@Override
|
@Override
|
||||||
public void visit(@NonNull MarkwonVisitor visitor, @NonNull TableBlock tableBlock) {
|
public void visit(@NonNull MarkwonVisitor visitor, @NonNull TableBlock tableBlock) {
|
||||||
|
|
||||||
|
visitor.blockStart(tableBlock);
|
||||||
|
|
||||||
visitor.visitChildren(tableBlock);
|
visitor.visitChildren(tableBlock);
|
||||||
|
|
||||||
if (visitor.hasNext(tableBlock)) {
|
// if (visitor.hasNext(tableBlock)) {
|
||||||
visitor.ensureNewLine();
|
// visitor.ensureNewLine();
|
||||||
visitor.forceNewLine();
|
// visitor.forceNewLine();
|
||||||
}
|
// }
|
||||||
|
visitor.blockEnd(tableBlock);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.on(TableBody.class, new MarkwonVisitor.NodeVisitor<TableBody>() {
|
.on(TableBody.class, new MarkwonVisitor.NodeVisitor<TableBody>() {
|
||||||
|
@ -11,19 +11,19 @@ import androidx.annotation.NonNull;
|
|||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
import org.commonmark.node.Heading;
|
import org.commonmark.node.Heading;
|
||||||
|
import org.commonmark.node.Node;
|
||||||
import org.commonmark.node.Paragraph;
|
import org.commonmark.node.Paragraph;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
|
||||||
import io.noties.markwon.AbstractMarkwonPlugin;
|
import io.noties.markwon.AbstractMarkwonPlugin;
|
||||||
|
import io.noties.markwon.BlockHandlerDef;
|
||||||
import io.noties.markwon.Markwon;
|
import io.noties.markwon.Markwon;
|
||||||
import io.noties.markwon.MarkwonConfiguration;
|
import io.noties.markwon.MarkwonConfiguration;
|
||||||
import io.noties.markwon.MarkwonSpansFactory;
|
import io.noties.markwon.MarkwonSpansFactory;
|
||||||
import io.noties.markwon.MarkwonVisitor;
|
import io.noties.markwon.MarkwonVisitor;
|
||||||
import io.noties.markwon.RenderProps;
|
|
||||||
import io.noties.markwon.SoftBreakAddsNewLinePlugin;
|
import io.noties.markwon.SoftBreakAddsNewLinePlugin;
|
||||||
import io.noties.markwon.SpanFactory;
|
|
||||||
import io.noties.markwon.core.CoreProps;
|
import io.noties.markwon.core.CoreProps;
|
||||||
import io.noties.markwon.core.MarkwonTheme;
|
import io.noties.markwon.core.MarkwonTheme;
|
||||||
import io.noties.markwon.core.spans.LastLineSpacingSpan;
|
import io.noties.markwon.core.spans.LastLineSpacingSpan;
|
||||||
@ -52,7 +52,9 @@ public class BasicPluginsActivity extends ActivityWithMenuOptions {
|
|||||||
.add("softBreakAddsSpace", this::softBreakAddsSpace)
|
.add("softBreakAddsSpace", this::softBreakAddsSpace)
|
||||||
.add("softBreakAddsNewLine", this::softBreakAddsNewLine)
|
.add("softBreakAddsNewLine", this::softBreakAddsNewLine)
|
||||||
.add("additionalSpacing", this::additionalSpacing)
|
.add("additionalSpacing", this::additionalSpacing)
|
||||||
.add("headingNoSpace", this::headingNoSpace);
|
.add("headingNoSpace", this::headingNoSpace)
|
||||||
|
.add("headingNoSpaceBlockHandler", this::headingNoSpaceBlockHandler)
|
||||||
|
.add("allBlocksNoForcedLine", this::allBlocksNoForcedLine);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -311,6 +313,68 @@ public class BasicPluginsActivity extends ActivityWithMenuOptions {
|
|||||||
markwon.setMarkdown(textView, md);
|
markwon.setMarkdown(textView, md);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void headingNoSpaceBlockHandler() {
|
||||||
|
final Markwon markwon = Markwon.builder(this)
|
||||||
|
.usePlugin(new AbstractMarkwonPlugin() {
|
||||||
|
@Override
|
||||||
|
public void configureVisitor(@NonNull MarkwonVisitor.Builder builder) {
|
||||||
|
builder.blockHandler(new BlockHandlerDef() {
|
||||||
|
@Override
|
||||||
|
public void blockEnd(@NonNull MarkwonVisitor visitor, @NonNull Node node) {
|
||||||
|
if (node instanceof Heading) {
|
||||||
|
if (visitor.hasNext(node)) {
|
||||||
|
visitor.ensureNewLine();
|
||||||
|
// ensure new line but do not force insert one
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
super.blockEnd(visitor, node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.build();
|
||||||
|
|
||||||
|
final String md = "" +
|
||||||
|
"# Title title title title title title title title title title \n\ntext text text text";
|
||||||
|
|
||||||
|
markwon.setMarkdown(textView, md);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void allBlocksNoForcedLine() {
|
||||||
|
final MarkwonVisitor.BlockHandler blockHandler = new BlockHandlerDef() {
|
||||||
|
@Override
|
||||||
|
public void blockEnd(@NonNull MarkwonVisitor visitor, @NonNull Node node) {
|
||||||
|
if (visitor.hasNext(node)) {
|
||||||
|
visitor.ensureNewLine();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
final Markwon markwon = Markwon.builder(this)
|
||||||
|
.usePlugin(new AbstractMarkwonPlugin() {
|
||||||
|
@Override
|
||||||
|
public void configureVisitor(@NonNull MarkwonVisitor.Builder builder) {
|
||||||
|
builder.blockHandler(blockHandler);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.build();
|
||||||
|
|
||||||
|
final String md = "" +
|
||||||
|
"# Hello there!\n\n" +
|
||||||
|
"* a first\n" +
|
||||||
|
"* second\n" +
|
||||||
|
"- third\n" +
|
||||||
|
"* * nested one\n\n" +
|
||||||
|
"> block quote\n\n" +
|
||||||
|
"> > and nested one\n\n" +
|
||||||
|
"```java\n" +
|
||||||
|
"final int i = 0;\n" +
|
||||||
|
"```\n\n";
|
||||||
|
|
||||||
|
markwon.setMarkdown(textView, md);
|
||||||
|
}
|
||||||
|
|
||||||
// public void step_6() {
|
// public void step_6() {
|
||||||
//
|
//
|
||||||
// final Markwon markwon = Markwon.builder(this)
|
// final Markwon markwon = Markwon.builder(this)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user