Switch to use SpannableFactory for html parsing

This commit is contained in:
Dimitry Ivanov 2018-07-21 14:08:33 +03:00
parent 9f532df752
commit bd08178a55
13 changed files with 211 additions and 91 deletions

View File

@ -31,7 +31,7 @@ public class SpannableConfiguration {
private final UrlProcessor urlProcessor; private final UrlProcessor urlProcessor;
private final SpannableHtmlParser htmlParser; private final SpannableHtmlParser htmlParser;
private final ImageSizeResolver imageSizeResolver; private final ImageSizeResolver imageSizeResolver;
private final SpannableFactory spannableFactory; // @since 1.1.0 private final SpannableFactory factory; // @since 1.1.0
private SpannableConfiguration(@NonNull Builder builder) { private SpannableConfiguration(@NonNull Builder builder) {
this.theme = builder.theme; this.theme = builder.theme;
@ -41,7 +41,7 @@ public class SpannableConfiguration {
this.urlProcessor = builder.urlProcessor; this.urlProcessor = builder.urlProcessor;
this.htmlParser = builder.htmlParser; this.htmlParser = builder.htmlParser;
this.imageSizeResolver = builder.imageSizeResolver; this.imageSizeResolver = builder.imageSizeResolver;
this.spannableFactory = builder.spannableFactory; this.factory = builder.factory;
} }
@NonNull @NonNull
@ -81,7 +81,7 @@ public class SpannableConfiguration {
@NonNull @NonNull
public SpannableFactory factory() { public SpannableFactory factory() {
return spannableFactory; return factory;
} }
@SuppressWarnings("unused") @SuppressWarnings("unused")
@ -95,7 +95,7 @@ public class SpannableConfiguration {
private UrlProcessor urlProcessor; private UrlProcessor urlProcessor;
private SpannableHtmlParser htmlParser; private SpannableHtmlParser htmlParser;
private ImageSizeResolver imageSizeResolver; private ImageSizeResolver imageSizeResolver;
private SpannableFactory spannableFactory; private SpannableFactory factory;
Builder(@NonNull Context context) { Builder(@NonNull Context context) {
this.context = context; this.context = context;
@ -150,8 +150,8 @@ public class SpannableConfiguration {
* @since 1.1.0 * @since 1.1.0
*/ */
@NonNull @NonNull
public Builder spannableFactory(@NonNull SpannableFactory spannableFactory) { public Builder factory(@NonNull SpannableFactory factory) {
this.spannableFactory = spannableFactory; this.factory = factory;
return this; return this;
} }
@ -183,12 +183,18 @@ public class SpannableConfiguration {
} }
// @since 1.1.0 // @since 1.1.0
if (spannableFactory == null) { if (factory == null) {
spannableFactory = SpannableFactoryDef.create(); factory = SpannableFactoryDef.create();
} }
if (htmlParser == null) { if (htmlParser == null) {
htmlParser = SpannableHtmlParser.create(theme, asyncDrawableLoader, urlProcessor, linkResolver, imageSizeResolver); htmlParser = SpannableHtmlParser.create(
factory,
theme,
asyncDrawableLoader,
urlProcessor,
linkResolver,
imageSizeResolver);
} }
return new SpannableConfiguration(this); return new SpannableConfiguration(this);

View File

@ -70,4 +70,16 @@ public interface SpannableFactory {
@NonNull SpannableTheme theme, @NonNull SpannableTheme theme,
@NonNull String destination, @NonNull String destination,
@NonNull LinkSpan.Resolver resolver); @NonNull LinkSpan.Resolver resolver);
// Currently used by HTML parser
@Nullable
Object superScript(@NonNull SpannableTheme theme);
// Currently used by HTML parser
@Nullable
Object subScript(@NonNull SpannableTheme theme);
// Currently used by HTML parser
@Nullable
Object underline();
} }

View File

@ -3,6 +3,7 @@ package ru.noties.markwon;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.text.style.StrikethroughSpan; import android.text.style.StrikethroughSpan;
import android.text.style.UnderlineSpan;
import java.util.List; import java.util.List;
@ -19,6 +20,8 @@ import ru.noties.markwon.spans.LinkSpan;
import ru.noties.markwon.spans.OrderedListItemSpan; import ru.noties.markwon.spans.OrderedListItemSpan;
import ru.noties.markwon.spans.SpannableTheme; import ru.noties.markwon.spans.SpannableTheme;
import ru.noties.markwon.spans.StrongEmphasisSpan; import ru.noties.markwon.spans.StrongEmphasisSpan;
import ru.noties.markwon.spans.SubScriptSpan;
import ru.noties.markwon.spans.SuperScriptSpan;
import ru.noties.markwon.spans.TableRowSpan; import ru.noties.markwon.spans.TableRowSpan;
import ru.noties.markwon.spans.TaskListSpan; import ru.noties.markwon.spans.TaskListSpan;
import ru.noties.markwon.spans.ThematicBreakSpan; import ru.noties.markwon.spans.ThematicBreakSpan;
@ -118,4 +121,21 @@ public class SpannableFactoryDef implements SpannableFactory {
public Object link(@NonNull SpannableTheme theme, @NonNull String destination, @NonNull LinkSpan.Resolver resolver) { public Object link(@NonNull SpannableTheme theme, @NonNull String destination, @NonNull LinkSpan.Resolver resolver) {
return new LinkSpan(theme, destination, resolver); return new LinkSpan(theme, destination, resolver);
} }
@Nullable
@Override
public Object superScript(@NonNull SpannableTheme theme) {
return new SuperScriptSpan(theme);
}
@Override
public Object subScript(@NonNull SpannableTheme theme) {
return new SubScriptSpan(theme);
}
@Nullable
@Override
public Object underline() {
return new UnderlineSpan();
}
} }

View File

@ -4,7 +4,6 @@ import android.support.annotation.NonNull;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.text.Spanned; import android.text.Spanned;
import android.text.TextUtils; import android.text.TextUtils;
import android.text.style.StrikethroughSpan;
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.TableBody;
@ -44,20 +43,8 @@ import ru.noties.markwon.SpannableBuilder;
import ru.noties.markwon.SpannableConfiguration; import ru.noties.markwon.SpannableConfiguration;
import ru.noties.markwon.SpannableFactory; import ru.noties.markwon.SpannableFactory;
import ru.noties.markwon.renderer.html.SpannableHtmlParser; import ru.noties.markwon.renderer.html.SpannableHtmlParser;
import ru.noties.markwon.spans.AsyncDrawable;
import ru.noties.markwon.spans.AsyncDrawableSpan;
import ru.noties.markwon.spans.BlockQuoteSpan;
import ru.noties.markwon.spans.BulletListItemSpan;
import ru.noties.markwon.spans.CodeSpan;
import ru.noties.markwon.spans.EmphasisSpan;
import ru.noties.markwon.spans.HeadingSpan;
import ru.noties.markwon.spans.LinkSpan;
import ru.noties.markwon.spans.OrderedListItemSpan;
import ru.noties.markwon.spans.SpannableTheme; import ru.noties.markwon.spans.SpannableTheme;
import ru.noties.markwon.spans.StrongEmphasisSpan;
import ru.noties.markwon.spans.TableRowSpan; import ru.noties.markwon.spans.TableRowSpan;
import ru.noties.markwon.spans.TaskListSpan;
import ru.noties.markwon.spans.ThematicBreakSpan;
import ru.noties.markwon.tasklist.TaskListBlock; import ru.noties.markwon.tasklist.TaskListBlock;
import ru.noties.markwon.tasklist.TaskListItem; import ru.noties.markwon.tasklist.TaskListItem;
@ -467,9 +454,7 @@ public class SpannableMarkdownVisitor extends AbstractVisitor {
if (htmlInlineItems.size() > 0) { if (htmlInlineItems.size() > 0) {
final HtmlInlineItem item = htmlInlineItems.pop(); final HtmlInlineItem item = htmlInlineItems.pop();
final Object span = htmlParser.getSpanForTag(item.tag); final Object span = htmlParser.getSpanForTag(item.tag);
if (span != null) { setSpan(item.start, span);
setSpan(item.start, span);
}
} }
} else { } else {
@ -501,7 +486,7 @@ public class SpannableMarkdownVisitor extends AbstractVisitor {
final int length = builder.length(); final int length = builder.length();
if (span.getClass().isArray()) { if (span.getClass().isArray()) {
for (Object o: ((Object[]) span)) { for (Object o : ((Object[]) span)) {
builder.setSpan(o, start, length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); builder.setSpan(o, start, length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
} }
} else { } else {

View File

@ -2,12 +2,21 @@ package ru.noties.markwon.renderer.html;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import ru.noties.markwon.spans.StrongEmphasisSpan; import ru.noties.markwon.SpannableFactory;
class BoldProvider implements SpannableHtmlParser.SpanProvider { class BoldProvider implements SpannableHtmlParser.SpanProvider {
private final SpannableFactory factory;
/**
* @since 1.1.0
*/
BoldProvider(@NonNull SpannableFactory factory) {
this.factory = factory;
}
@Override @Override
public Object provide(@NonNull SpannableHtmlParser.Tag tag) { public Object provide(@NonNull SpannableHtmlParser.Tag tag) {
return new StrongEmphasisSpan(); return factory.strongEmphasis();
} }
} }

View File

@ -10,26 +10,29 @@ import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import ru.noties.markwon.SpannableFactory;
import ru.noties.markwon.UrlProcessor; import ru.noties.markwon.UrlProcessor;
import ru.noties.markwon.renderer.ImageSize; import ru.noties.markwon.renderer.ImageSize;
import ru.noties.markwon.renderer.ImageSizeResolver; import ru.noties.markwon.renderer.ImageSizeResolver;
import ru.noties.markwon.spans.AsyncDrawable; import ru.noties.markwon.spans.AsyncDrawable;
import ru.noties.markwon.spans.AsyncDrawableSpan;
import ru.noties.markwon.spans.SpannableTheme; import ru.noties.markwon.spans.SpannableTheme;
class ImageProviderImpl implements SpannableHtmlParser.ImageProvider { class ImageProviderImpl implements SpannableHtmlParser.ImageProvider {
private final SpannableFactory factory;
private final SpannableTheme theme; private final SpannableTheme theme;
private final AsyncDrawable.Loader loader; private final AsyncDrawable.Loader loader;
private final UrlProcessor urlProcessor; private final UrlProcessor urlProcessor;
private final ImageSizeResolver imageSizeResolver; private final ImageSizeResolver imageSizeResolver;
ImageProviderImpl( ImageProviderImpl(
@NonNull SpannableFactory factory,
@NonNull SpannableTheme theme, @NonNull SpannableTheme theme,
@NonNull AsyncDrawable.Loader loader, @NonNull AsyncDrawable.Loader loader,
@NonNull UrlProcessor urlProcessor, @NonNull UrlProcessor urlProcessor,
@NonNull ImageSizeResolver imageSizeResolver @NonNull ImageSizeResolver imageSizeResolver
) { ) {
this.factory = factory;
this.theme = theme; this.theme = theme;
this.loader = loader; this.loader = loader;
this.urlProcessor = urlProcessor; this.urlProcessor = urlProcessor;
@ -56,11 +59,26 @@ class ImageProviderImpl implements SpannableHtmlParser.ImageProvider {
replacement = "\uFFFC"; replacement = "\uFFFC";
} }
final AsyncDrawable drawable = new AsyncDrawable(destination, loader, imageSizeResolver, parseImageSize(attributes)); final Object span = factory.image(
final AsyncDrawableSpan span = new AsyncDrawableSpan(theme, drawable); theme,
destination,
loader,
imageSizeResolver,
parseImageSize(attributes),
false);
final SpannableString string = new SpannableString(replacement); final SpannableString string = new SpannableString(replacement);
string.setSpan(span, 0, string.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
if (span != null) {
final int length = string.length();
if (span.getClass().isArray()) {
for (Object o : ((Object[]) span)) {
string.setSpan(o, 0, length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
} else {
string.setSpan(span, 0, length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
spanned = string; spanned = string;
} else { } else {

View File

@ -2,12 +2,21 @@ package ru.noties.markwon.renderer.html;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import ru.noties.markwon.spans.EmphasisSpan; import ru.noties.markwon.SpannableFactory;
class ItalicsProvider implements SpannableHtmlParser.SpanProvider { class ItalicsProvider implements SpannableHtmlParser.SpanProvider {
private final SpannableFactory factory;
/**
* @since 1.1.0
*/
ItalicsProvider(@NonNull SpannableFactory factory) {
this.factory = factory;
}
@Override @Override
public Object provide(@NonNull SpannableHtmlParser.Tag tag) { public Object provide(@NonNull SpannableHtmlParser.Tag tag) {
return new EmphasisSpan(); return factory.emphasis();
} }
} }

View File

@ -5,20 +5,24 @@ import android.text.TextUtils;
import java.util.Map; import java.util.Map;
import ru.noties.markwon.SpannableFactory;
import ru.noties.markwon.UrlProcessor; import ru.noties.markwon.UrlProcessor;
import ru.noties.markwon.spans.LinkSpan; import ru.noties.markwon.spans.LinkSpan;
import ru.noties.markwon.spans.SpannableTheme; import ru.noties.markwon.spans.SpannableTheme;
class LinkProvider implements SpannableHtmlParser.SpanProvider { class LinkProvider implements SpannableHtmlParser.SpanProvider {
private final SpannableFactory factory;
private final SpannableTheme theme; private final SpannableTheme theme;
private final UrlProcessor urlProcessor; private final UrlProcessor urlProcessor;
private final LinkSpan.Resolver resolver; private final LinkSpan.Resolver resolver;
LinkProvider( LinkProvider(
@NonNull SpannableFactory factory,
@NonNull SpannableTheme theme, @NonNull SpannableTheme theme,
@NonNull UrlProcessor urlProcessor, @NonNull UrlProcessor urlProcessor,
@NonNull LinkSpan.Resolver resolver) { @NonNull LinkSpan.Resolver resolver) {
this.factory = factory;
this.theme = theme; this.theme = theme;
this.urlProcessor = urlProcessor; this.urlProcessor = urlProcessor;
this.resolver = resolver; this.resolver = resolver;
@ -34,7 +38,7 @@ class LinkProvider implements SpannableHtmlParser.SpanProvider {
if (!TextUtils.isEmpty(href)) { if (!TextUtils.isEmpty(href)) {
final String destination = urlProcessor.process(href); final String destination = urlProcessor.process(href);
span = new LinkSpan(theme, destination, resolver); span = factory.link(theme, destination, resolver);
} else { } else {
span = null; span = null;

View File

@ -11,6 +11,7 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
import ru.noties.markwon.LinkResolverDef; import ru.noties.markwon.LinkResolverDef;
import ru.noties.markwon.SpannableFactory;
import ru.noties.markwon.UrlProcessor; import ru.noties.markwon.UrlProcessor;
import ru.noties.markwon.UrlProcessorNoOp; import ru.noties.markwon.UrlProcessorNoOp;
import ru.noties.markwon.renderer.ImageSizeResolver; import ru.noties.markwon.renderer.ImageSizeResolver;
@ -22,53 +23,68 @@ import ru.noties.markwon.spans.SpannableTheme;
@SuppressWarnings("WeakerAccess") @SuppressWarnings("WeakerAccess")
public class SpannableHtmlParser { public class SpannableHtmlParser {
// creates default parser // // creates default parser
@NonNull // @NonNull
public static SpannableHtmlParser create( // public static SpannableHtmlParser create(
@NonNull SpannableTheme theme, // @NonNull SpannableTheme theme,
@NonNull AsyncDrawable.Loader loader // @NonNull AsyncDrawable.Loader loader
) { // ) {
return builderWithDefaults(theme, loader, null, null, null) // return builderWithDefaults(theme, loader, null, null, null)
.build(); // .build();
} // }
//
// /**
// * @since 1.0.1
// */
// @NonNull
// public static SpannableHtmlParser create(
// @NonNull SpannableTheme theme,
// @NonNull AsyncDrawable.Loader loader,
// @NonNull ImageSizeResolver imageSizeResolver
// ) {
// return builderWithDefaults(theme, loader, null, null, imageSizeResolver)
// .build();
// }
//
// @NonNull
// public static SpannableHtmlParser create(
// @NonNull SpannableTheme theme,
// @NonNull AsyncDrawable.Loader loader,
// @NonNull UrlProcessor urlProcessor,
// @NonNull LinkSpan.Resolver resolver
// ) {
// return builderWithDefaults(theme, loader, urlProcessor, resolver, null)
// .build();
// }
// /**
// * @since 1.0.1
// */
// @NonNull
// public static SpannableHtmlParser create(
// @NonNull SpannableTheme theme,
// @NonNull AsyncDrawable.Loader loader,
// @NonNull UrlProcessor urlProcessor,
// @NonNull LinkSpan.Resolver resolver,
// @NonNull ImageSizeResolver imageSizeResolver
// ) {
// return builderWithDefaults(theme, loader, urlProcessor, resolver, imageSizeResolver)
// .build();
// }
/** /**
* @since 1.0.1 * @since 1.1.0
*/
@NonNull
public static SpannableHtmlParser create(
@NonNull SpannableTheme theme,
@NonNull AsyncDrawable.Loader loader,
@NonNull ImageSizeResolver imageSizeResolver
) {
return builderWithDefaults(theme, loader, null, null, imageSizeResolver)
.build();
}
@NonNull
public static SpannableHtmlParser create(
@NonNull SpannableTheme theme,
@NonNull AsyncDrawable.Loader loader,
@NonNull UrlProcessor urlProcessor,
@NonNull LinkSpan.Resolver resolver
) {
return builderWithDefaults(theme, loader, urlProcessor, resolver, null)
.build();
}
/**
* @since 1.0.1
*/ */
@NonNull @NonNull
public static SpannableHtmlParser create( public static SpannableHtmlParser create(
@NonNull SpannableFactory factory,
@NonNull SpannableTheme theme, @NonNull SpannableTheme theme,
@NonNull AsyncDrawable.Loader loader, @NonNull AsyncDrawable.Loader loader,
@NonNull UrlProcessor urlProcessor, @NonNull UrlProcessor urlProcessor,
@NonNull LinkSpan.Resolver resolver, @NonNull LinkSpan.Resolver resolver,
@NonNull ImageSizeResolver imageSizeResolver @NonNull ImageSizeResolver imageSizeResolver
) { ) {
return builderWithDefaults(theme, loader, urlProcessor, resolver, imageSizeResolver) return builderWithDefaults(factory, theme, loader, urlProcessor, resolver, imageSizeResolver).build();
.build();
} }
@NonNull @NonNull
@ -76,16 +92,27 @@ public class SpannableHtmlParser {
return new Builder(); return new Builder();
} }
/**
* @since 1.1.0
*/
@NonNull @NonNull
public static Builder builderWithDefaults(@NonNull SpannableTheme theme) { public static Builder builderWithDefaults(@NonNull SpannableFactory factory, @NonNull SpannableTheme theme) {
return builderWithDefaults(theme, null, null, null, null); return builderWithDefaults(
factory,
theme,
null,
null,
null,
null);
} }
/** /**
* Updated in 1.0.1: added imageSizeResolverArgument * Updated in 1.0.1: added imageSizeResolverArgument
* Updated in 1.1.0: add SpannableFactory
*/ */
@NonNull @NonNull
public static Builder builderWithDefaults( public static Builder builderWithDefaults(
@NonNull SpannableFactory factory,
@NonNull SpannableTheme theme, @NonNull SpannableTheme theme,
@Nullable AsyncDrawable.Loader asyncDrawableLoader, @Nullable AsyncDrawable.Loader asyncDrawableLoader,
@Nullable UrlProcessor urlProcessor, @Nullable UrlProcessor urlProcessor,
@ -101,9 +128,9 @@ public class SpannableHtmlParser {
resolver = new LinkResolverDef(); resolver = new LinkResolverDef();
} }
final BoldProvider boldProvider = new BoldProvider(); final BoldProvider boldProvider = new BoldProvider(factory);
final ItalicsProvider italicsProvider = new ItalicsProvider(); final ItalicsProvider italicsProvider = new ItalicsProvider(factory);
final StrikeProvider strikeProvider = new StrikeProvider(); final StrikeProvider strikeProvider = new StrikeProvider(factory);
final ImageProvider imageProvider; final ImageProvider imageProvider;
if (asyncDrawableLoader != null) { if (asyncDrawableLoader != null) {
@ -112,7 +139,12 @@ public class SpannableHtmlParser {
imageSizeResolver = new ImageSizeResolverDef(); imageSizeResolver = new ImageSizeResolverDef();
} }
imageProvider = new ImageProviderImpl(theme, asyncDrawableLoader, urlProcessor, imageSizeResolver); imageProvider = new ImageProviderImpl(
factory,
theme,
asyncDrawableLoader,
urlProcessor,
imageSizeResolver);
} else { } else {
imageProvider = null; imageProvider = null;
} }
@ -124,13 +156,13 @@ public class SpannableHtmlParser {
.simpleTag("em", italicsProvider) .simpleTag("em", italicsProvider)
.simpleTag("cite", italicsProvider) .simpleTag("cite", italicsProvider)
.simpleTag("dfn", italicsProvider) .simpleTag("dfn", italicsProvider)
.simpleTag("sup", new SuperScriptProvider(theme)) .simpleTag("sup", new SuperScriptProvider(factory, theme))
.simpleTag("sub", new SubScriptProvider(theme)) .simpleTag("sub", new SubScriptProvider(factory, theme))
.simpleTag("u", new UnderlineProvider()) .simpleTag("u", new UnderlineProvider(factory))
.simpleTag("del", strikeProvider) .simpleTag("del", strikeProvider)
.simpleTag("s", strikeProvider) .simpleTag("s", strikeProvider)
.simpleTag("strike", strikeProvider) .simpleTag("strike", strikeProvider)
.simpleTag("a", new LinkProvider(theme, urlProcessor, resolver)) .simpleTag("a", new LinkProvider(factory, theme, urlProcessor, resolver))
.imageProvider(imageProvider); .imageProvider(imageProvider);
} }

View File

@ -1,11 +1,22 @@
package ru.noties.markwon.renderer.html; package ru.noties.markwon.renderer.html;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.text.style.StrikethroughSpan;
import ru.noties.markwon.SpannableFactory;
class StrikeProvider implements SpannableHtmlParser.SpanProvider { class StrikeProvider implements SpannableHtmlParser.SpanProvider {
private final SpannableFactory factory;
/**
* @since 1.1.0
*/
StrikeProvider(@NonNull SpannableFactory factory) {
this.factory = factory;
}
@Override @Override
public Object provide(@NonNull SpannableHtmlParser.Tag tag) { public Object provide(@NonNull SpannableHtmlParser.Tag tag) {
return new StrikethroughSpan(); return factory.strikethrough();
} }
} }

View File

@ -2,19 +2,21 @@ package ru.noties.markwon.renderer.html;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import ru.noties.markwon.SpannableFactory;
import ru.noties.markwon.spans.SpannableTheme; import ru.noties.markwon.spans.SpannableTheme;
import ru.noties.markwon.spans.SubScriptSpan;
class SubScriptProvider implements SpannableHtmlParser.SpanProvider { class SubScriptProvider implements SpannableHtmlParser.SpanProvider {
private final SpannableFactory factory;
private final SpannableTheme theme; private final SpannableTheme theme;
public SubScriptProvider(SpannableTheme theme) { SubScriptProvider(@NonNull SpannableFactory factory, @NonNull SpannableTheme theme) {
this.factory = factory;
this.theme = theme; this.theme = theme;
} }
@Override @Override
public Object provide(@NonNull SpannableHtmlParser.Tag tag) { public Object provide(@NonNull SpannableHtmlParser.Tag tag) {
return new SubScriptSpan(theme); return factory.subScript(theme);
} }
} }

View File

@ -2,19 +2,21 @@ package ru.noties.markwon.renderer.html;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import ru.noties.markwon.SpannableFactory;
import ru.noties.markwon.spans.SpannableTheme; import ru.noties.markwon.spans.SpannableTheme;
import ru.noties.markwon.spans.SuperScriptSpan;
class SuperScriptProvider implements SpannableHtmlParser.SpanProvider { class SuperScriptProvider implements SpannableHtmlParser.SpanProvider {
private final SpannableFactory factory;
private final SpannableTheme theme; private final SpannableTheme theme;
SuperScriptProvider(SpannableTheme theme) { SuperScriptProvider(@NonNull SpannableFactory factory, @NonNull SpannableTheme theme) {
this.factory = factory;
this.theme = theme; this.theme = theme;
} }
@Override @Override
public Object provide(@NonNull SpannableHtmlParser.Tag tag) { public Object provide(@NonNull SpannableHtmlParser.Tag tag) {
return new SuperScriptSpan(theme); return factory.superScript(theme);
} }
} }

View File

@ -1,12 +1,22 @@
package ru.noties.markwon.renderer.html; package ru.noties.markwon.renderer.html;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.text.style.UnderlineSpan;
import ru.noties.markwon.SpannableFactory;
class UnderlineProvider implements SpannableHtmlParser.SpanProvider { class UnderlineProvider implements SpannableHtmlParser.SpanProvider {
private final SpannableFactory factory;
/**
* @since 1.1.0
*/
UnderlineProvider(@NonNull SpannableFactory factory) {
this.factory = factory;
}
@Override @Override
public Object provide(@NonNull SpannableHtmlParser.Tag tag) { public Object provide(@NonNull SpannableHtmlParser.Tag tag) {
return new UnderlineSpan(); return factory.underline();
} }
} }