Switch to use SpannableFactory
This commit is contained in:
parent
146ba9c575
commit
9f532df752
@ -31,6 +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 SpannableConfiguration(@NonNull Builder builder) {
|
private SpannableConfiguration(@NonNull Builder builder) {
|
||||||
this.theme = builder.theme;
|
this.theme = builder.theme;
|
||||||
@ -40,6 +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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
@ -77,6 +79,11 @@ public class SpannableConfiguration {
|
|||||||
return imageSizeResolver;
|
return imageSizeResolver;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
public SpannableFactory factory() {
|
||||||
|
return spannableFactory;
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public static class Builder {
|
public static class Builder {
|
||||||
|
|
||||||
@ -88,6 +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;
|
||||||
|
|
||||||
Builder(@NonNull Context context) {
|
Builder(@NonNull Context context) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
@ -138,6 +146,15 @@ public class SpannableConfiguration {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 1.1.0
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
public Builder spannableFactory(@NonNull SpannableFactory spannableFactory) {
|
||||||
|
this.spannableFactory = spannableFactory;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
public SpannableConfiguration build() {
|
public SpannableConfiguration build() {
|
||||||
|
|
||||||
@ -165,6 +182,11 @@ public class SpannableConfiguration {
|
|||||||
imageSizeResolver = new ImageSizeResolverDef();
|
imageSizeResolver = new ImageSizeResolverDef();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @since 1.1.0
|
||||||
|
if (spannableFactory == null) {
|
||||||
|
spannableFactory = SpannableFactoryDef.create();
|
||||||
|
}
|
||||||
|
|
||||||
if (htmlParser == null) {
|
if (htmlParser == null) {
|
||||||
htmlParser = SpannableHtmlParser.create(theme, asyncDrawableLoader, urlProcessor, linkResolver, imageSizeResolver);
|
htmlParser = SpannableHtmlParser.create(theme, asyncDrawableLoader, urlProcessor, linkResolver, imageSizeResolver);
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,73 @@
|
|||||||
|
package ru.noties.markwon;
|
||||||
|
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import ru.noties.markwon.renderer.ImageSize;
|
||||||
|
import ru.noties.markwon.renderer.ImageSizeResolver;
|
||||||
|
import ru.noties.markwon.spans.AsyncDrawable;
|
||||||
|
import ru.noties.markwon.spans.LinkSpan;
|
||||||
|
import ru.noties.markwon.spans.SpannableTheme;
|
||||||
|
import ru.noties.markwon.spans.TableRowSpan;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Each method can return null or a Span object or an array of spans
|
||||||
|
*
|
||||||
|
* @since 1.1.0
|
||||||
|
*/
|
||||||
|
public interface SpannableFactory {
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
Object strongEmphasis();
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
Object emphasis();
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
Object blockQuote(@NonNull SpannableTheme theme);
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
Object code(@NonNull SpannableTheme theme, boolean multiline);
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
Object orderedListItem(@NonNull SpannableTheme theme, int startNumber);
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
Object bulletListItem(@NonNull SpannableTheme theme, int level);
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
Object thematicBreak(@NonNull SpannableTheme theme);
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
Object heading(@NonNull SpannableTheme theme, int level);
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
Object strikethrough();
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
Object taskListItem(@NonNull SpannableTheme theme, int blockIndent, boolean isDone);
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
Object tableRow(
|
||||||
|
@NonNull SpannableTheme theme,
|
||||||
|
@NonNull List<TableRowSpan.Cell> cells,
|
||||||
|
boolean isHeader,
|
||||||
|
boolean isOdd);
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
Object image(
|
||||||
|
@NonNull SpannableTheme theme,
|
||||||
|
@NonNull String destination,
|
||||||
|
@NonNull AsyncDrawable.Loader loader,
|
||||||
|
@NonNull ImageSizeResolver imageSizeResolver,
|
||||||
|
@Nullable ImageSize imageSize,
|
||||||
|
boolean replacementTextIsLink);
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
Object link(
|
||||||
|
@NonNull SpannableTheme theme,
|
||||||
|
@NonNull String destination,
|
||||||
|
@NonNull LinkSpan.Resolver resolver);
|
||||||
|
}
|
121
library/src/main/java/ru/noties/markwon/SpannableFactoryDef.java
Normal file
121
library/src/main/java/ru/noties/markwon/SpannableFactoryDef.java
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
package ru.noties.markwon;
|
||||||
|
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
|
import android.text.style.StrikethroughSpan;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import ru.noties.markwon.renderer.ImageSize;
|
||||||
|
import ru.noties.markwon.renderer.ImageSizeResolver;
|
||||||
|
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.StrongEmphasisSpan;
|
||||||
|
import ru.noties.markwon.spans.TableRowSpan;
|
||||||
|
import ru.noties.markwon.spans.TaskListSpan;
|
||||||
|
import ru.noties.markwon.spans.ThematicBreakSpan;
|
||||||
|
|
||||||
|
public class SpannableFactoryDef implements SpannableFactory {
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
public static SpannableFactoryDef create() {
|
||||||
|
return new SpannableFactoryDef();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public Object strongEmphasis() {
|
||||||
|
return new StrongEmphasisSpan();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public Object emphasis() {
|
||||||
|
return new EmphasisSpan();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public Object blockQuote(@NonNull SpannableTheme theme) {
|
||||||
|
return new BlockQuoteSpan(theme);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public Object code(@NonNull SpannableTheme theme, boolean multiline) {
|
||||||
|
return new CodeSpan(theme, multiline);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public Object orderedListItem(@NonNull SpannableTheme theme, int startNumber) {
|
||||||
|
// todo| in order to provide real RTL experience there must be a way to provide this string
|
||||||
|
return new OrderedListItemSpan(theme, String.valueOf(startNumber) + "." + '\u00a0');
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public Object bulletListItem(@NonNull SpannableTheme theme, int level) {
|
||||||
|
return new BulletListItemSpan(theme, level);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public Object thematicBreak(@NonNull SpannableTheme theme) {
|
||||||
|
return new ThematicBreakSpan(theme);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public Object heading(@NonNull SpannableTheme theme, int level) {
|
||||||
|
return new HeadingSpan(theme, level);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public Object strikethrough() {
|
||||||
|
return new StrikethroughSpan();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public Object taskListItem(@NonNull SpannableTheme theme, int blockIndent, boolean isDone) {
|
||||||
|
return new TaskListSpan(theme, blockIndent, isDone);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public Object tableRow(@NonNull SpannableTheme theme, @NonNull List<TableRowSpan.Cell> cells, boolean isHeader, boolean isOdd) {
|
||||||
|
return new TableRowSpan(theme, cells, isHeader, isOdd);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public Object image(@NonNull SpannableTheme theme, @NonNull String destination, @NonNull AsyncDrawable.Loader loader, @NonNull ImageSizeResolver imageSizeResolver, @Nullable ImageSize imageSize, boolean replacementTextIsLink) {
|
||||||
|
return new AsyncDrawableSpan(
|
||||||
|
theme,
|
||||||
|
new AsyncDrawable(
|
||||||
|
destination,
|
||||||
|
loader,
|
||||||
|
imageSizeResolver,
|
||||||
|
imageSize
|
||||||
|
),
|
||||||
|
AsyncDrawableSpan.ALIGN_BOTTOM,
|
||||||
|
replacementTextIsLink
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public Object link(@NonNull SpannableTheme theme, @NonNull String destination, @NonNull LinkSpan.Resolver resolver) {
|
||||||
|
return new LinkSpan(theme, destination, resolver);
|
||||||
|
}
|
||||||
|
}
|
@ -42,6 +42,7 @@ import java.util.List;
|
|||||||
|
|
||||||
import ru.noties.markwon.SpannableBuilder;
|
import ru.noties.markwon.SpannableBuilder;
|
||||||
import ru.noties.markwon.SpannableConfiguration;
|
import ru.noties.markwon.SpannableConfiguration;
|
||||||
|
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.AsyncDrawable;
|
||||||
import ru.noties.markwon.spans.AsyncDrawableSpan;
|
import ru.noties.markwon.spans.AsyncDrawableSpan;
|
||||||
@ -52,6 +53,7 @@ import ru.noties.markwon.spans.EmphasisSpan;
|
|||||||
import ru.noties.markwon.spans.HeadingSpan;
|
import ru.noties.markwon.spans.HeadingSpan;
|
||||||
import ru.noties.markwon.spans.LinkSpan;
|
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.StrongEmphasisSpan;
|
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.TaskListSpan;
|
||||||
@ -66,6 +68,9 @@ public class SpannableMarkdownVisitor extends AbstractVisitor {
|
|||||||
private final SpannableBuilder builder;
|
private final SpannableBuilder builder;
|
||||||
private final Deque<HtmlInlineItem> htmlInlineItems;
|
private final Deque<HtmlInlineItem> htmlInlineItems;
|
||||||
|
|
||||||
|
private final SpannableTheme theme;
|
||||||
|
private final SpannableFactory factory;
|
||||||
|
|
||||||
private int blockQuoteIndent;
|
private int blockQuoteIndent;
|
||||||
private int listLevel;
|
private int listLevel;
|
||||||
|
|
||||||
@ -80,6 +85,9 @@ public class SpannableMarkdownVisitor extends AbstractVisitor {
|
|||||||
this.configuration = configuration;
|
this.configuration = configuration;
|
||||||
this.builder = builder;
|
this.builder = builder;
|
||||||
this.htmlInlineItems = new ArrayDeque<>(2);
|
this.htmlInlineItems = new ArrayDeque<>(2);
|
||||||
|
|
||||||
|
this.theme = configuration.theme();
|
||||||
|
this.factory = configuration.factory();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -91,14 +99,14 @@ public class SpannableMarkdownVisitor extends AbstractVisitor {
|
|||||||
public void visit(StrongEmphasis strongEmphasis) {
|
public void visit(StrongEmphasis strongEmphasis) {
|
||||||
final int length = builder.length();
|
final int length = builder.length();
|
||||||
visitChildren(strongEmphasis);
|
visitChildren(strongEmphasis);
|
||||||
setSpan(length, new StrongEmphasisSpan());
|
setSpan(length, factory.strongEmphasis());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(Emphasis emphasis) {
|
public void visit(Emphasis emphasis) {
|
||||||
final int length = builder.length();
|
final int length = builder.length();
|
||||||
visitChildren(emphasis);
|
visitChildren(emphasis);
|
||||||
setSpan(length, new EmphasisSpan());
|
setSpan(length, factory.emphasis());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -115,7 +123,7 @@ public class SpannableMarkdownVisitor extends AbstractVisitor {
|
|||||||
|
|
||||||
visitChildren(blockQuote);
|
visitChildren(blockQuote);
|
||||||
|
|
||||||
setSpan(length, new BlockQuoteSpan(configuration.theme()));
|
setSpan(length, factory.blockQuote(theme));
|
||||||
|
|
||||||
blockQuoteIndent -= 1;
|
blockQuoteIndent -= 1;
|
||||||
|
|
||||||
@ -136,10 +144,7 @@ public class SpannableMarkdownVisitor extends AbstractVisitor {
|
|||||||
builder.append(code.getLiteral());
|
builder.append(code.getLiteral());
|
||||||
builder.append('\u00a0');
|
builder.append('\u00a0');
|
||||||
|
|
||||||
setSpan(length, new CodeSpan(
|
setSpan(length, factory.code(theme, false));
|
||||||
configuration.theme(),
|
|
||||||
false
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -174,10 +179,7 @@ public class SpannableMarkdownVisitor extends AbstractVisitor {
|
|||||||
);
|
);
|
||||||
builder.append('\u00a0').append('\n');
|
builder.append('\u00a0').append('\n');
|
||||||
|
|
||||||
setSpan(length, new CodeSpan(
|
setSpan(length, factory.code(theme, true));
|
||||||
configuration.theme(),
|
|
||||||
true
|
|
||||||
));
|
|
||||||
|
|
||||||
newLine();
|
newLine();
|
||||||
builder.append('\n');
|
builder.append('\n');
|
||||||
@ -217,11 +219,7 @@ public class SpannableMarkdownVisitor extends AbstractVisitor {
|
|||||||
|
|
||||||
visitChildren(listItem);
|
visitChildren(listItem);
|
||||||
|
|
||||||
// todo| in order to provide real RTL experience there must be a way to provide this string
|
setSpan(length, factory.orderedListItem(theme, start));
|
||||||
setSpan(length, new OrderedListItemSpan(
|
|
||||||
configuration.theme(),
|
|
||||||
String.valueOf(start) + "." + '\u00a0'
|
|
||||||
));
|
|
||||||
|
|
||||||
// after we have visited the children increment start number
|
// after we have visited the children increment start number
|
||||||
final OrderedList orderedList = (OrderedList) parent;
|
final OrderedList orderedList = (OrderedList) parent;
|
||||||
@ -231,10 +229,7 @@ public class SpannableMarkdownVisitor extends AbstractVisitor {
|
|||||||
|
|
||||||
visitChildren(listItem);
|
visitChildren(listItem);
|
||||||
|
|
||||||
setSpan(length, new BulletListItemSpan(
|
setSpan(length, factory.bulletListItem(theme, listLevel - 1));
|
||||||
configuration.theme(),
|
|
||||||
listLevel - 1
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
blockQuoteIndent -= 1;
|
blockQuoteIndent -= 1;
|
||||||
@ -250,7 +245,8 @@ public class SpannableMarkdownVisitor extends AbstractVisitor {
|
|||||||
|
|
||||||
final int length = builder.length();
|
final int length = builder.length();
|
||||||
builder.append(' '); // without space it won't render
|
builder.append(' '); // without space it won't render
|
||||||
setSpan(length, new ThematicBreakSpan(configuration.theme()));
|
|
||||||
|
setSpan(length, factory.thematicBreak(theme));
|
||||||
|
|
||||||
newLine();
|
newLine();
|
||||||
builder.append('\n');
|
builder.append('\n');
|
||||||
@ -263,7 +259,7 @@ public class SpannableMarkdownVisitor extends AbstractVisitor {
|
|||||||
|
|
||||||
final int length = builder.length();
|
final int length = builder.length();
|
||||||
visitChildren(heading);
|
visitChildren(heading);
|
||||||
setSpan(length, new HeadingSpan(configuration.theme(), heading.getLevel()));
|
setSpan(length, factory.heading(theme, heading.getLevel()));
|
||||||
|
|
||||||
newLine();
|
newLine();
|
||||||
|
|
||||||
@ -305,7 +301,7 @@ public class SpannableMarkdownVisitor extends AbstractVisitor {
|
|||||||
|
|
||||||
final int length = builder.length();
|
final int length = builder.length();
|
||||||
visitChildren(customNode);
|
visitChildren(customNode);
|
||||||
setSpan(length, new StrikethroughSpan());
|
setSpan(length, factory.strikethrough());
|
||||||
|
|
||||||
} else if (customNode instanceof TaskListItem) {
|
} else if (customNode instanceof TaskListItem) {
|
||||||
|
|
||||||
@ -319,11 +315,7 @@ public class SpannableMarkdownVisitor extends AbstractVisitor {
|
|||||||
|
|
||||||
visitChildren(customNode);
|
visitChildren(customNode);
|
||||||
|
|
||||||
setSpan(length, new TaskListSpan(
|
setSpan(length, factory.taskListItem(theme, blockQuoteIndent, listItem.done()));
|
||||||
configuration.theme(),
|
|
||||||
blockQuoteIndent,
|
|
||||||
listItem.done()
|
|
||||||
));
|
|
||||||
|
|
||||||
newLine();
|
newLine();
|
||||||
|
|
||||||
@ -356,12 +348,11 @@ public class SpannableMarkdownVisitor extends AbstractVisitor {
|
|||||||
// trimmed from the final result
|
// trimmed from the final result
|
||||||
builder.append('\u00a0');
|
builder.append('\u00a0');
|
||||||
|
|
||||||
final TableRowSpan span = new TableRowSpan(
|
final Object span = factory.tableRow(
|
||||||
configuration.theme(),
|
theme,
|
||||||
pendingTableRow,
|
pendingTableRow,
|
||||||
tableRowIsHeader,
|
tableRowIsHeader,
|
||||||
tableRows % 2 == 1
|
tableRows % 2 == 1);
|
||||||
);
|
|
||||||
|
|
||||||
tableRows = tableRowIsHeader
|
tableRows = tableRowIsHeader
|
||||||
? 0
|
? 0
|
||||||
@ -434,15 +425,12 @@ public class SpannableMarkdownVisitor extends AbstractVisitor {
|
|||||||
|
|
||||||
setSpan(
|
setSpan(
|
||||||
length,
|
length,
|
||||||
new AsyncDrawableSpan(
|
factory.image(
|
||||||
configuration.theme(),
|
theme,
|
||||||
new AsyncDrawable(
|
destination,
|
||||||
destination,
|
configuration.asyncDrawableLoader(),
|
||||||
configuration.asyncDrawableLoader(),
|
configuration.imageSizeResolver(),
|
||||||
configuration.imageSizeResolver(),
|
null,
|
||||||
null
|
|
||||||
),
|
|
||||||
AsyncDrawableSpan.ALIGN_BOTTOM,
|
|
||||||
link
|
link
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@ -504,11 +492,22 @@ public class SpannableMarkdownVisitor extends AbstractVisitor {
|
|||||||
final int length = builder.length();
|
final int length = builder.length();
|
||||||
visitChildren(link);
|
visitChildren(link);
|
||||||
final String destination = configuration.urlProcessor().process(link.getDestination());
|
final String destination = configuration.urlProcessor().process(link.getDestination());
|
||||||
setSpan(length, new LinkSpan(configuration.theme(), destination, configuration.linkResolver()));
|
setSpan(length, factory.link(theme, destination, configuration.linkResolver()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setSpan(int start, @NonNull Object span) {
|
private void setSpan(int start, @Nullable Object span) {
|
||||||
builder.setSpan(span, start, builder.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
if (span != null) {
|
||||||
|
|
||||||
|
final int length = builder.length();
|
||||||
|
|
||||||
|
if (span.getClass().isArray()) {
|
||||||
|
for (Object o: ((Object[]) span)) {
|
||||||
|
builder.setSpan(o, start, length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
builder.setSpan(span, start, length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void newLine() {
|
private void newLine() {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user