136 lines
4.0 KiB
Java
136 lines
4.0 KiB
Java
package ru.noties.markwon;
|
|
|
|
import android.content.Context;
|
|
import android.net.Uri;
|
|
import android.os.Handler;
|
|
import android.os.SystemClock;
|
|
import android.support.annotation.NonNull;
|
|
import android.support.annotation.Nullable;
|
|
|
|
import java.util.concurrent.ExecutorService;
|
|
import java.util.concurrent.Future;
|
|
|
|
import javax.inject.Inject;
|
|
|
|
import ru.noties.debug.Debug;
|
|
import ru.noties.markwon.spans.AsyncDrawable;
|
|
import ru.noties.markwon.spans.SpannableTheme;
|
|
import ru.noties.markwon.syntax.Prism4jSyntaxHighlight;
|
|
import ru.noties.markwon.syntax.Prism4jTheme;
|
|
import ru.noties.markwon.syntax.Prism4jThemeDarkula;
|
|
import ru.noties.markwon.syntax.Prism4jThemeDefault;
|
|
import ru.noties.prism4j.Prism4j;
|
|
|
|
@ActivityScope
|
|
public class MarkdownRenderer {
|
|
|
|
interface MarkdownReadyListener {
|
|
void onMarkdownReady(CharSequence markdown);
|
|
}
|
|
|
|
@Inject
|
|
AsyncDrawable.Loader loader;
|
|
|
|
@Inject
|
|
ExecutorService service;
|
|
|
|
@Inject
|
|
Handler handler;
|
|
|
|
@Inject
|
|
Prism4j prism4j;
|
|
|
|
@Inject
|
|
Prism4jThemeDefault prism4jThemeDefault;
|
|
|
|
@Inject
|
|
Prism4jThemeDarkula prism4JThemeDarkula;
|
|
|
|
private Future<?> task;
|
|
|
|
@Inject
|
|
MarkdownRenderer() {
|
|
}
|
|
|
|
public void render(
|
|
@NonNull final Context context,
|
|
final boolean isLightTheme,
|
|
@Nullable final Uri uri,
|
|
@NonNull final String markdown,
|
|
@NonNull final MarkdownReadyListener listener) {
|
|
|
|
// todo: create prism4j theme factory (accepting light/dark argument)
|
|
|
|
cancel();
|
|
|
|
task = service.submit(new Runnable() {
|
|
@Override
|
|
public void run() {
|
|
|
|
final UrlProcessor urlProcessor;
|
|
if (uri == null) {
|
|
urlProcessor = new UrlProcessorInitialReadme();
|
|
} else {
|
|
urlProcessor = new UrlProcessorRelativeToAbsolute(uri.toString());
|
|
}
|
|
|
|
final Prism4jTheme prism4jTheme = isLightTheme
|
|
? prism4jThemeDefault
|
|
: prism4JThemeDarkula;
|
|
|
|
final int background = isLightTheme
|
|
? prism4jTheme.background()
|
|
: 0x0Fffffff;
|
|
|
|
final GifPlaceholder gifPlaceholder = new GifPlaceholder(
|
|
context.getResources().getDrawable(R.drawable.ic_play_circle_filled_18dp_white),
|
|
0x20000000
|
|
);
|
|
|
|
final SpannableConfiguration configuration = SpannableConfiguration.builder(context)
|
|
.asyncDrawableLoader(loader)
|
|
.urlProcessor(urlProcessor)
|
|
.syntaxHighlight(Prism4jSyntaxHighlight.create(prism4j, prism4jTheme))
|
|
.theme(SpannableTheme.builderWithDefaults(context)
|
|
.codeBackgroundColor(background)
|
|
.codeTextColor(prism4jTheme.textColor())
|
|
.build())
|
|
.factory(new GifAwareSpannableFactory(gifPlaceholder))
|
|
.trimWhiteSpaceEnd(false)
|
|
.build();
|
|
|
|
final long start = SystemClock.uptimeMillis();
|
|
|
|
final CharSequence text = Markwon.markdown(configuration, markdown);
|
|
|
|
final long end = SystemClock.uptimeMillis();
|
|
|
|
Debug.i("markdown rendered: %d ms", end - start);
|
|
|
|
if (!isCancelled()) {
|
|
handler.post(new Runnable() {
|
|
@Override
|
|
public void run() {
|
|
if (!isCancelled()) {
|
|
listener.onMarkdownReady(text);
|
|
task = null;
|
|
}
|
|
}
|
|
});
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
public void cancel() {
|
|
if (task != null) {
|
|
task.cancel(true);
|
|
task = null;
|
|
}
|
|
}
|
|
|
|
private boolean isCancelled() {
|
|
return task == null || task.isCancelled();
|
|
}
|
|
}
|