Create HtmlPlugin
This commit is contained in:
parent
27ed17aaff
commit
66bb33a76b
@ -29,6 +29,7 @@ android {
|
|||||||
dependencies {
|
dependencies {
|
||||||
|
|
||||||
implementation project(':markwon')
|
implementation project(':markwon')
|
||||||
|
implementation project(':markwon-html')
|
||||||
implementation project(':markwon-image-gif')
|
implementation project(':markwon-image-gif')
|
||||||
implementation project(':markwon-image-svg')
|
implementation project(':markwon-image-svg')
|
||||||
implementation project(':markwon-syntax-highlight')
|
implementation project(':markwon-syntax-highlight')
|
||||||
|
@ -9,6 +9,7 @@ import android.view.View;
|
|||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import pl.droidsonroids.gif.GifDrawable;
|
import pl.droidsonroids.gif.GifDrawable;
|
||||||
|
import ru.noties.debug.Debug;
|
||||||
import ru.noties.markwon.spans.AsyncDrawableSpan;
|
import ru.noties.markwon.spans.AsyncDrawableSpan;
|
||||||
|
|
||||||
public abstract class GifProcessor {
|
public abstract class GifProcessor {
|
||||||
@ -25,16 +26,21 @@ public abstract class GifProcessor {
|
|||||||
@Override
|
@Override
|
||||||
public void process(@NonNull final TextView textView) {
|
public void process(@NonNull final TextView textView) {
|
||||||
|
|
||||||
|
Debug.i("textView: %s", textView);
|
||||||
|
|
||||||
// here is what we will do additionally:
|
// here is what we will do additionally:
|
||||||
// we query for all asyncDrawableSpans
|
// we query for all asyncDrawableSpans
|
||||||
// we check if they are inside clickableSpan
|
// we check if they are inside clickableSpan
|
||||||
// if not we apply onGifListener
|
// if not we apply onGifListener
|
||||||
|
|
||||||
final Spannable spannable = spannable(textView);
|
final Spannable spannable = spannable(textView);
|
||||||
|
Debug.i(spannable);
|
||||||
if (spannable == null) {
|
if (spannable == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Debug.i(spannable);
|
||||||
|
|
||||||
final AsyncDrawableSpan[] asyncDrawableSpans =
|
final AsyncDrawableSpan[] asyncDrawableSpans =
|
||||||
spannable.getSpans(0, spannable.length(), AsyncDrawableSpan.class);
|
spannable.getSpans(0, spannable.length(), AsyncDrawableSpan.class);
|
||||||
if (asyncDrawableSpans == null
|
if (asyncDrawableSpans == null
|
||||||
@ -42,6 +48,8 @@ public abstract class GifProcessor {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Debug.i(asyncDrawableSpans);
|
||||||
|
|
||||||
int start;
|
int start;
|
||||||
int end;
|
int end;
|
||||||
ClickableSpan[] clickableSpans;
|
ClickableSpan[] clickableSpans;
|
||||||
@ -51,6 +59,8 @@ public abstract class GifProcessor {
|
|||||||
start = spannable.getSpanStart(asyncDrawableSpan);
|
start = spannable.getSpanStart(asyncDrawableSpan);
|
||||||
end = spannable.getSpanEnd(asyncDrawableSpan);
|
end = spannable.getSpanEnd(asyncDrawableSpan);
|
||||||
|
|
||||||
|
Debug.i(asyncDrawableSpan, start, end);
|
||||||
|
|
||||||
if (start < 0
|
if (start < 0
|
||||||
|| end < 0) {
|
|| end < 0) {
|
||||||
continue;
|
continue;
|
||||||
@ -74,6 +84,7 @@ public abstract class GifProcessor {
|
|||||||
@Nullable
|
@Nullable
|
||||||
private static Spannable spannable(@NonNull TextView textView) {
|
private static Spannable spannable(@NonNull TextView textView) {
|
||||||
final CharSequence charSequence = textView.getText();
|
final CharSequence charSequence = textView.getText();
|
||||||
|
Debug.i("type: %s, spanned: %s, spannable: %s", charSequence.getClass().getName(), charSequence instanceof Spanned, charSequence instanceof Spannable);
|
||||||
if (charSequence instanceof Spannable) {
|
if (charSequence instanceof Spannable) {
|
||||||
return (Spannable) charSequence;
|
return (Spannable) charSequence;
|
||||||
}
|
}
|
||||||
@ -85,6 +96,8 @@ public abstract class GifProcessor {
|
|||||||
@NonNull AsyncDrawableSpan span,
|
@NonNull AsyncDrawableSpan span,
|
||||||
@NonNull GifAwareAsyncDrawable drawable) {
|
@NonNull GifAwareAsyncDrawable drawable) {
|
||||||
|
|
||||||
|
Debug.i("textView: %s, span: %s, drawable: %s", textView, span, drawable);
|
||||||
|
|
||||||
// important thing here is to obtain new spannable from textView
|
// important thing here is to obtain new spannable from textView
|
||||||
// as with each `setText()` new spannable is created and keeping reference
|
// as with each `setText()` new spannable is created and keeping reference
|
||||||
// to an older one won't affect textView
|
// to an older one won't affect textView
|
||||||
|
@ -14,6 +14,7 @@ import javax.inject.Inject;
|
|||||||
|
|
||||||
import ru.noties.debug.Debug;
|
import ru.noties.debug.Debug;
|
||||||
import ru.noties.markwon.core.CorePlugin;
|
import ru.noties.markwon.core.CorePlugin;
|
||||||
|
import ru.noties.markwon.html.impl.HtmlPlugin;
|
||||||
import ru.noties.markwon.image.ImagesPlugin;
|
import ru.noties.markwon.image.ImagesPlugin;
|
||||||
import ru.noties.markwon.image.gif.GifPlugin;
|
import ru.noties.markwon.image.gif.GifPlugin;
|
||||||
import ru.noties.markwon.image.svg.SvgPlugin;
|
import ru.noties.markwon.image.svg.SvgPlugin;
|
||||||
@ -21,6 +22,8 @@ import ru.noties.markwon.syntax.Prism4jTheme;
|
|||||||
import ru.noties.markwon.syntax.Prism4jThemeDarkula;
|
import ru.noties.markwon.syntax.Prism4jThemeDarkula;
|
||||||
import ru.noties.markwon.syntax.Prism4jThemeDefault;
|
import ru.noties.markwon.syntax.Prism4jThemeDefault;
|
||||||
import ru.noties.markwon.syntax.SyntaxHighlightPlugin;
|
import ru.noties.markwon.syntax.SyntaxHighlightPlugin;
|
||||||
|
import ru.noties.markwon.table.TablePlugin;
|
||||||
|
import ru.noties.markwon.tasklist.TaskListPlugin;
|
||||||
import ru.noties.prism4j.Prism4j;
|
import ru.noties.prism4j.Prism4j;
|
||||||
|
|
||||||
@ActivityScope
|
@ActivityScope
|
||||||
@ -84,6 +87,9 @@ public class MarkdownRenderer {
|
|||||||
.use(GifPlugin.create(false))
|
.use(GifPlugin.create(false))
|
||||||
.use(SyntaxHighlightPlugin.create(prism4j, prism4jTheme))
|
.use(SyntaxHighlightPlugin.create(prism4j, prism4jTheme))
|
||||||
.use(GifAwarePlugin.create(context))
|
.use(GifAwarePlugin.create(context))
|
||||||
|
.use(TablePlugin.create(context))
|
||||||
|
.use(TaskListPlugin.create(context))
|
||||||
|
.use(HtmlPlugin.create())
|
||||||
.use(new AbstractMarkwonPlugin() {
|
.use(new AbstractMarkwonPlugin() {
|
||||||
@Override
|
@Override
|
||||||
public void configureConfiguration(@NonNull MarkwonConfiguration.Builder builder) {
|
public void configureConfiguration(@NonNull MarkwonConfiguration.Builder builder) {
|
||||||
|
@ -0,0 +1,85 @@
|
|||||||
|
package ru.noties.markwon.html.impl;
|
||||||
|
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
|
|
||||||
|
import org.commonmark.node.Document;
|
||||||
|
import org.commonmark.node.HtmlBlock;
|
||||||
|
import org.commonmark.node.HtmlInline;
|
||||||
|
|
||||||
|
import ru.noties.markwon.AbstractMarkwonPlugin;
|
||||||
|
import ru.noties.markwon.MarkwonConfiguration;
|
||||||
|
import ru.noties.markwon.MarkwonVisitor;
|
||||||
|
import ru.noties.markwon.html.MarkwonHtmlParser;
|
||||||
|
import ru.noties.markwon.html.MarkwonHtmlRenderer;
|
||||||
|
|
||||||
|
public class HtmlPlugin extends AbstractMarkwonPlugin {
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
public static HtmlPlugin create() {
|
||||||
|
return create(MarkwonHtmlRendererImpl.create(), MarkwonHtmlParserImpl.create());
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
public static HtmlPlugin create(@NonNull MarkwonHtmlRenderer renderer) {
|
||||||
|
return create(renderer, MarkwonHtmlParserImpl.create());
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
public static HtmlPlugin create(@NonNull MarkwonHtmlParser parser) {
|
||||||
|
return create(MarkwonHtmlRendererImpl.create(), parser);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
public static HtmlPlugin create(@NonNull MarkwonHtmlRenderer renderer, @NonNull MarkwonHtmlParser parser) {
|
||||||
|
return new HtmlPlugin(renderer, parser);
|
||||||
|
}
|
||||||
|
|
||||||
|
private final MarkwonHtmlRenderer renderer;
|
||||||
|
private final MarkwonHtmlParser parser;
|
||||||
|
|
||||||
|
public HtmlPlugin(@NonNull MarkwonHtmlRenderer renderer, @NonNull MarkwonHtmlParser parser) {
|
||||||
|
this.renderer = renderer;
|
||||||
|
this.parser = parser;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void configureConfiguration(@NonNull MarkwonConfiguration.Builder builder) {
|
||||||
|
builder
|
||||||
|
.htmlParser(parser)
|
||||||
|
.htmlRenderer(renderer);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void configureVisitor(@NonNull MarkwonVisitor.Builder builder) {
|
||||||
|
builder
|
||||||
|
.on(Document.class, new MarkwonVisitor.NodeVisitor<Document>() {
|
||||||
|
@Override
|
||||||
|
public void visit(@NonNull MarkwonVisitor visitor, @NonNull Document document) {
|
||||||
|
|
||||||
|
visitor.visitChildren(document);
|
||||||
|
|
||||||
|
final MarkwonConfiguration configuration = visitor.configuration();
|
||||||
|
configuration.htmlRenderer().render(configuration, visitor.builder(), configuration.htmlParser());
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.on(HtmlBlock.class, new MarkwonVisitor.NodeVisitor<HtmlBlock>() {
|
||||||
|
@Override
|
||||||
|
public void visit(@NonNull MarkwonVisitor visitor, @NonNull HtmlBlock htmlBlock) {
|
||||||
|
visitHtml(visitor, htmlBlock.getLiteral());
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.on(HtmlInline.class, new MarkwonVisitor.NodeVisitor<HtmlInline>() {
|
||||||
|
@Override
|
||||||
|
public void visit(@NonNull MarkwonVisitor visitor, @NonNull HtmlInline htmlInline) {
|
||||||
|
visitHtml(visitor, htmlInline.getLiteral());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void visitHtml(@NonNull MarkwonVisitor visitor, @Nullable String html) {
|
||||||
|
if (html != null) {
|
||||||
|
visitor.configuration().htmlParser().processFragment(visitor.builder(), html);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -34,8 +34,24 @@ public class MarkwonHtmlRendererImpl extends MarkwonHtmlRenderer {
|
|||||||
return builderWithDefaults().build();
|
return builderWithDefaults().build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 3.0.0
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
public static MarkwonHtmlRendererImpl create(boolean allowNonClosedTags) {
|
||||||
|
return builderWithDefaults(allowNonClosedTags).build();
|
||||||
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
public static Builder builderWithDefaults() {
|
public static Builder builderWithDefaults() {
|
||||||
|
return builderWithDefaults(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 3.0.0
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
public static Builder builderWithDefaults(boolean allowNonClosedTags) {
|
||||||
|
|
||||||
final EmphasisHandler emphasisHandler = new EmphasisHandler();
|
final EmphasisHandler emphasisHandler = new EmphasisHandler();
|
||||||
final StrongEmphasisHandler strongEmphasisHandler = new StrongEmphasisHandler();
|
final StrongEmphasisHandler strongEmphasisHandler = new StrongEmphasisHandler();
|
||||||
@ -44,6 +60,7 @@ public class MarkwonHtmlRendererImpl extends MarkwonHtmlRenderer {
|
|||||||
final ListHandler listHandler = new ListHandler();
|
final ListHandler listHandler = new ListHandler();
|
||||||
|
|
||||||
return builder()
|
return builder()
|
||||||
|
.allowNonClosedTags(allowNonClosedTags)
|
||||||
.handler("i", emphasisHandler)
|
.handler("i", emphasisHandler)
|
||||||
.handler("em", emphasisHandler)
|
.handler("em", emphasisHandler)
|
||||||
.handler("cite", emphasisHandler)
|
.handler("cite", emphasisHandler)
|
||||||
@ -77,9 +94,11 @@ public class MarkwonHtmlRendererImpl extends MarkwonHtmlRenderer {
|
|||||||
|
|
||||||
public static final float SCRIPT_DEF_TEXT_SIZE_RATIO = .75F;
|
public static final float SCRIPT_DEF_TEXT_SIZE_RATIO = .75F;
|
||||||
|
|
||||||
|
private final boolean allowNonClosedTags;
|
||||||
private final Map<String, TagHandler> tagHandlers;
|
private final Map<String, TagHandler> tagHandlers;
|
||||||
|
|
||||||
private MarkwonHtmlRendererImpl(@NonNull Map<String, TagHandler> tagHandlers) {
|
private MarkwonHtmlRendererImpl(boolean allowNonClosedTags, @NonNull Map<String, TagHandler> tagHandlers) {
|
||||||
|
this.allowNonClosedTags = allowNonClosedTags;
|
||||||
this.tagHandlers = tagHandlers;
|
this.tagHandlers = tagHandlers;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,7 +109,7 @@ public class MarkwonHtmlRendererImpl extends MarkwonHtmlRenderer {
|
|||||||
@NonNull MarkwonHtmlParser parser) {
|
@NonNull MarkwonHtmlParser parser) {
|
||||||
|
|
||||||
final int end;
|
final int end;
|
||||||
if (!configuration.htmlAllowNonClosedTags()) {
|
if (!allowNonClosedTags) {
|
||||||
end = HtmlTag.NO_END;
|
end = HtmlTag.NO_END;
|
||||||
} else {
|
} else {
|
||||||
end = builder.length();
|
end = builder.length();
|
||||||
@ -152,6 +171,7 @@ public class MarkwonHtmlRendererImpl extends MarkwonHtmlRenderer {
|
|||||||
public static class Builder {
|
public static class Builder {
|
||||||
|
|
||||||
private final Map<String, TagHandler> tagHandlers = new HashMap<>(2);
|
private final Map<String, TagHandler> tagHandlers = new HashMap<>(2);
|
||||||
|
private boolean allowNonClosedTags;
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
public Builder handler(@NonNull String tagName, @NonNull TagHandler tagHandler) {
|
public Builder handler(@NonNull String tagName, @NonNull TagHandler tagHandler) {
|
||||||
@ -159,9 +179,23 @@ public class MarkwonHtmlRendererImpl extends MarkwonHtmlRenderer {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param allowNonClosedTags that indicates if non-closed html tags should be rendered.
|
||||||
|
* If this argument is true then all non-closed HTML tags
|
||||||
|
* will be closed at the end of a document. Otherwise they will
|
||||||
|
* be delivered non-closed {@code HtmlTag#isClosed()} and thus not
|
||||||
|
* rendered at all
|
||||||
|
* @since 3.0.0
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
public Builder allowNonClosedTags(boolean allowNonClosedTags) {
|
||||||
|
this.allowNonClosedTags = allowNonClosedTags;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
public MarkwonHtmlRendererImpl build() {
|
public MarkwonHtmlRendererImpl build() {
|
||||||
return new MarkwonHtmlRendererImpl(Collections.unmodifiableMap(tagHandlers));
|
return new MarkwonHtmlRendererImpl(allowNonClosedTags, Collections.unmodifiableMap(tagHandlers));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -39,7 +39,7 @@ public class MarkwonConfiguration {
|
|||||||
private final SpannableFactory factory; // @since 1.1.0
|
private final SpannableFactory factory; // @since 1.1.0
|
||||||
private final MarkwonHtmlParser htmlParser; // @since 2.0.0
|
private final MarkwonHtmlParser htmlParser; // @since 2.0.0
|
||||||
private final MarkwonHtmlRenderer htmlRenderer; // @since 2.0.0
|
private final MarkwonHtmlRenderer htmlRenderer; // @since 2.0.0
|
||||||
private final boolean htmlAllowNonClosedTags; // @since 2.0.0
|
// private final boolean htmlAllowNonClosedTags; // @since 2.0.0
|
||||||
|
|
||||||
private MarkwonConfiguration(@NonNull Builder builder) {
|
private MarkwonConfiguration(@NonNull Builder builder) {
|
||||||
this.theme = builder.theme;
|
this.theme = builder.theme;
|
||||||
@ -51,7 +51,7 @@ public class MarkwonConfiguration {
|
|||||||
this.factory = builder.factory;
|
this.factory = builder.factory;
|
||||||
this.htmlParser = builder.htmlParser;
|
this.htmlParser = builder.htmlParser;
|
||||||
this.htmlRenderer = builder.htmlRenderer;
|
this.htmlRenderer = builder.htmlRenderer;
|
||||||
this.htmlAllowNonClosedTags = builder.htmlAllowNonClosedTags;
|
// this.htmlAllowNonClosedTags = builder.htmlAllowNonClosedTags;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -113,12 +113,12 @@ public class MarkwonConfiguration {
|
|||||||
return htmlRenderer;
|
return htmlRenderer;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// /**
|
||||||
* @since 2.0.0
|
// * @since 2.0.0
|
||||||
*/
|
// */
|
||||||
public boolean htmlAllowNonClosedTags() {
|
// public boolean htmlAllowNonClosedTags() {
|
||||||
return htmlAllowNonClosedTags;
|
// return htmlAllowNonClosedTags;
|
||||||
}
|
// }
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public static class Builder {
|
public static class Builder {
|
||||||
@ -134,7 +134,7 @@ public class MarkwonConfiguration {
|
|||||||
private SpannableFactory factory; // @since 1.1.0
|
private SpannableFactory factory; // @since 1.1.0
|
||||||
private MarkwonHtmlParser htmlParser; // @since 2.0.0
|
private MarkwonHtmlParser htmlParser; // @since 2.0.0
|
||||||
private MarkwonHtmlRenderer htmlRenderer; // @since 2.0.0
|
private MarkwonHtmlRenderer htmlRenderer; // @since 2.0.0
|
||||||
private boolean htmlAllowNonClosedTags; // @since 2.0.0
|
// private boolean htmlAllowNonClosedTags; // @since 2.0.0
|
||||||
|
|
||||||
Builder(@NonNull Context context) {
|
Builder(@NonNull Context context) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
@ -151,7 +151,7 @@ public class MarkwonConfiguration {
|
|||||||
this.factory = configuration.factory;
|
this.factory = configuration.factory;
|
||||||
this.htmlParser = configuration.htmlParser;
|
this.htmlParser = configuration.htmlParser;
|
||||||
this.htmlRenderer = configuration.htmlRenderer;
|
this.htmlRenderer = configuration.htmlRenderer;
|
||||||
this.htmlAllowNonClosedTags = configuration.htmlAllowNonClosedTags;
|
// this.htmlAllowNonClosedTags = configuration.htmlAllowNonClosedTags;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
@ -208,18 +208,18 @@ public class MarkwonConfiguration {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// /**
|
||||||
* @param htmlAllowNonClosedTags that indicates if non-closed html tags should be rendered.
|
// * @param htmlAllowNonClosedTags that indicates if non-closed html tags should be rendered.
|
||||||
* If this argument is true then all non-closed HTML tags
|
// * If this argument is true then all non-closed HTML tags
|
||||||
* will be closed at the end of a document. Otherwise they will
|
// * will be closed at the end of a document. Otherwise they will
|
||||||
* be delivered non-closed {@code HtmlTag#isClosed()}
|
// * be delivered non-closed {@code HtmlTag#isClosed()}
|
||||||
* @since 2.0.0
|
// * @since 2.0.0
|
||||||
*/
|
// */
|
||||||
@NonNull
|
// @NonNull
|
||||||
public Builder htmlAllowNonClosedTags(boolean htmlAllowNonClosedTags) {
|
// public Builder htmlAllowNonClosedTags(boolean htmlAllowNonClosedTags) {
|
||||||
this.htmlAllowNonClosedTags = htmlAllowNonClosedTags;
|
// this.htmlAllowNonClosedTags = htmlAllowNonClosedTags;
|
||||||
return this;
|
// return this;
|
||||||
}
|
// }
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
public MarkwonConfiguration build(@NonNull MarkwonTheme theme, @NonNull AsyncDrawableLoader asyncDrawableLoader) {
|
public MarkwonConfiguration build(@NonNull MarkwonTheme theme, @NonNull AsyncDrawableLoader asyncDrawableLoader) {
|
||||||
|
@ -4,23 +4,16 @@ import android.support.annotation.NonNull;
|
|||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
|
|
||||||
import org.commonmark.ext.gfm.strikethrough.Strikethrough;
|
import org.commonmark.ext.gfm.strikethrough.Strikethrough;
|
||||||
import org.commonmark.ext.gfm.tables.TableBody;
|
|
||||||
import org.commonmark.ext.gfm.tables.TableCell;
|
|
||||||
import org.commonmark.ext.gfm.tables.TableHead;
|
|
||||||
import org.commonmark.ext.gfm.tables.TableRow;
|
|
||||||
import org.commonmark.node.AbstractVisitor;
|
import org.commonmark.node.AbstractVisitor;
|
||||||
import org.commonmark.node.BlockQuote;
|
import org.commonmark.node.BlockQuote;
|
||||||
import org.commonmark.node.BulletList;
|
import org.commonmark.node.BulletList;
|
||||||
import org.commonmark.node.Code;
|
import org.commonmark.node.Code;
|
||||||
import org.commonmark.node.CustomBlock;
|
import org.commonmark.node.CustomBlock;
|
||||||
import org.commonmark.node.CustomNode;
|
import org.commonmark.node.CustomNode;
|
||||||
import org.commonmark.node.Document;
|
|
||||||
import org.commonmark.node.Emphasis;
|
import org.commonmark.node.Emphasis;
|
||||||
import org.commonmark.node.FencedCodeBlock;
|
import org.commonmark.node.FencedCodeBlock;
|
||||||
import org.commonmark.node.HardLineBreak;
|
import org.commonmark.node.HardLineBreak;
|
||||||
import org.commonmark.node.Heading;
|
import org.commonmark.node.Heading;
|
||||||
import org.commonmark.node.HtmlBlock;
|
|
||||||
import org.commonmark.node.HtmlInline;
|
|
||||||
import org.commonmark.node.Image;
|
import org.commonmark.node.Image;
|
||||||
import org.commonmark.node.IndentedCodeBlock;
|
import org.commonmark.node.IndentedCodeBlock;
|
||||||
import org.commonmark.node.Link;
|
import org.commonmark.node.Link;
|
||||||
@ -29,29 +22,25 @@ import org.commonmark.node.ListItem;
|
|||||||
import org.commonmark.node.Node;
|
import org.commonmark.node.Node;
|
||||||
import org.commonmark.node.OrderedList;
|
import org.commonmark.node.OrderedList;
|
||||||
import org.commonmark.node.Paragraph;
|
import org.commonmark.node.Paragraph;
|
||||||
import org.commonmark.node.SoftLineBreak;
|
|
||||||
import org.commonmark.node.StrongEmphasis;
|
import org.commonmark.node.StrongEmphasis;
|
||||||
import org.commonmark.node.Text;
|
import org.commonmark.node.Text;
|
||||||
import org.commonmark.node.ThematicBreak;
|
import org.commonmark.node.ThematicBreak;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import ru.noties.markwon.SpannableBuilder;
|
|
||||||
import ru.noties.markwon.MarkwonConfiguration;
|
import ru.noties.markwon.MarkwonConfiguration;
|
||||||
|
import ru.noties.markwon.SpannableBuilder;
|
||||||
import ru.noties.markwon.SpannableFactory;
|
import ru.noties.markwon.SpannableFactory;
|
||||||
import ru.noties.markwon.html.api.MarkwonHtmlParser;
|
|
||||||
import ru.noties.markwon.spans.MarkwonTheme;
|
import ru.noties.markwon.spans.MarkwonTheme;
|
||||||
import ru.noties.markwon.table.TableRowSpan;
|
import ru.noties.markwon.table.TableRowSpan;
|
||||||
import ru.noties.markwon.tasklist.TaskListBlock;
|
import ru.noties.markwon.tasklist.TaskListBlock;
|
||||||
import ru.noties.markwon.tasklist.TaskListItem;
|
|
||||||
|
|
||||||
@SuppressWarnings("WeakerAccess")
|
@SuppressWarnings("WeakerAccess")
|
||||||
public class SpannableMarkdownVisitor extends AbstractVisitor {
|
public class SpannableMarkdownVisitor extends AbstractVisitor {
|
||||||
|
|
||||||
private final MarkwonConfiguration configuration;
|
private final MarkwonConfiguration configuration;
|
||||||
private final SpannableBuilder builder;
|
private final SpannableBuilder builder;
|
||||||
private final MarkwonHtmlParser htmlParser;
|
// private final MarkwonHtmlParser htmlParser;
|
||||||
|
|
||||||
private final MarkwonTheme theme;
|
private final MarkwonTheme theme;
|
||||||
private final SpannableFactory factory;
|
private final SpannableFactory factory;
|
||||||
@ -69,18 +58,18 @@ public class SpannableMarkdownVisitor extends AbstractVisitor {
|
|||||||
) {
|
) {
|
||||||
this.configuration = configuration;
|
this.configuration = configuration;
|
||||||
this.builder = builder;
|
this.builder = builder;
|
||||||
this.htmlParser = configuration.htmlParser();
|
// this.htmlParser = configuration.htmlParser();
|
||||||
|
|
||||||
this.theme = configuration.theme();
|
this.theme = configuration.theme();
|
||||||
this.factory = configuration.factory();
|
this.factory = configuration.factory();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
// @Override
|
||||||
public void visit(Document document) {
|
// public void visit(Document document) {
|
||||||
super.visit(document);
|
// super.visit(document);
|
||||||
|
//
|
||||||
configuration.htmlRenderer().render(configuration, builder, htmlParser);
|
// configuration.htmlRenderer().render(configuration, builder, htmlParser);
|
||||||
}
|
// }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(Text text) {
|
public void visit(Text text) {
|
||||||
@ -276,15 +265,15 @@ public class SpannableMarkdownVisitor extends AbstractVisitor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
// @Override
|
||||||
public void visit(SoftLineBreak softLineBreak) {
|
// public void visit(SoftLineBreak softLineBreak) {
|
||||||
// @since 1.1.1 there is an option to treat soft break as a hard break (thus adding new line)
|
// // @since 1.1.1 there is an option to treat soft break as a hard break (thus adding new line)
|
||||||
if (configuration.softBreakAddsNewLine()) {
|
// if (configuration.softBreakAddsNewLine()) {
|
||||||
newLine();
|
// newLine();
|
||||||
} else {
|
// } else {
|
||||||
builder.append(' ');
|
// builder.append(' ');
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(HardLineBreak hardLineBreak) {
|
public void visit(HardLineBreak hardLineBreak) {
|
||||||
@ -463,21 +452,21 @@ public class SpannableMarkdownVisitor extends AbstractVisitor {
|
|||||||
// user can open it in external viewer?
|
// user can open it in external viewer?
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
// @Override
|
||||||
public void visit(HtmlBlock htmlBlock) {
|
// public void visit(HtmlBlock htmlBlock) {
|
||||||
visitHtml(htmlBlock.getLiteral());
|
// visitHtml(htmlBlock.getLiteral());
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Override
|
// @Override
|
||||||
public void visit(HtmlInline htmlInline) {
|
// public void visit(HtmlInline htmlInline) {
|
||||||
visitHtml(htmlInline.getLiteral());
|
// visitHtml(htmlInline.getLiteral());
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
private void visitHtml(@Nullable String html) {
|
// private void visitHtml(@Nullable String html) {
|
||||||
if (html != null) {
|
// if (html != null) {
|
||||||
htmlParser.processFragment(builder, html);
|
// htmlParser.processFragment(builder, html);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(Link link) {
|
public void visit(Link link) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user