Working with latex plugin
This commit is contained in:
parent
d78b278b86
commit
7af0ead3a3
@ -4,6 +4,8 @@
|
||||
|
||||
[](https://github.com/noties/Markwon/actions)
|
||||
|
||||

|
||||
|
||||
**Markwon** is a markdown library for Android. It parses markdown
|
||||
following [commonmark-spec] with the help of amazing [commonmark-java]
|
||||
library and renders result as _Android-native_ Spannables. **No HTML**
|
||||
|
@ -1,5 +1,9 @@
|
||||
package io.noties.markwon.ext.latex;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import org.commonmark.internal.util.Parsing;
|
||||
import org.commonmark.node.Block;
|
||||
import org.commonmark.parser.block.AbstractBlockParser;
|
||||
@ -11,11 +15,21 @@ import org.commonmark.parser.block.ParserState;
|
||||
|
||||
public class JLatexMathBlockParser extends AbstractBlockParser {
|
||||
|
||||
private static final char DOLLAR = '$';
|
||||
private static final char SPACE = ' ';
|
||||
|
||||
private final JLatexMathBlock block = new JLatexMathBlock();
|
||||
|
||||
private final StringBuilder builder = new StringBuilder();
|
||||
|
||||
private boolean isClosed;
|
||||
// private boolean isClosed;
|
||||
|
||||
private final int signs;
|
||||
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
JLatexMathBlockParser(int signs) {
|
||||
this.signs = signs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Block getBlock() {
|
||||
@ -24,9 +38,22 @@ public class JLatexMathBlockParser extends AbstractBlockParser {
|
||||
|
||||
@Override
|
||||
public BlockContinue tryContinue(ParserState parserState) {
|
||||
final int nextNonSpaceIndex = parserState.getNextNonSpaceIndex();
|
||||
final CharSequence line = parserState.getLine();
|
||||
final int length = line.length();
|
||||
|
||||
if (isClosed) {
|
||||
return BlockContinue.finished();
|
||||
// check for closing
|
||||
if (parserState.getIndent() < Parsing.CODE_BLOCK_INDENT) {
|
||||
Log.e("LTX", String.format("signs: %d, skip dollar: %s", signs, Parsing.skip(DOLLAR, line, nextNonSpaceIndex, length)));
|
||||
// if (Parsing.skip(DOLLAR, line, nextNonSpaceIndex, length) == signs) {
|
||||
if (consume(DOLLAR, line, nextNonSpaceIndex, length) == signs) {
|
||||
// okay, we have our number of signs
|
||||
// let's consume spaces until the end
|
||||
Log.e("LTX", String.format("length; %d, skip spaces: %s", length, Parsing.skip(SPACE, line, nextNonSpaceIndex + signs, length)));
|
||||
if (Parsing.skip(SPACE, line, nextNonSpaceIndex + signs, length) == length) {
|
||||
return BlockContinue.finished();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return BlockContinue.atIndex(parserState.getIndex());
|
||||
@ -34,21 +61,24 @@ public class JLatexMathBlockParser extends AbstractBlockParser {
|
||||
|
||||
@Override
|
||||
public void addLine(CharSequence line) {
|
||||
|
||||
if (builder.length() > 0) {
|
||||
builder.append('\n');
|
||||
}
|
||||
|
||||
//
|
||||
// if (builder.length() > 0) {
|
||||
// builder.append('\n');
|
||||
// }
|
||||
//
|
||||
// builder.append(line);
|
||||
//
|
||||
// final int length = builder.length();
|
||||
// if (length > 1) {
|
||||
// isClosed = '$' == builder.charAt(length - 1)
|
||||
// && '$' == builder.charAt(length - 2);
|
||||
// if (isClosed) {
|
||||
// builder.replace(length - 2, length, "");
|
||||
// }
|
||||
// }
|
||||
Log.e("LTX", "addLine: " + line);
|
||||
builder.append(line);
|
||||
|
||||
final int length = builder.length();
|
||||
if (length > 1) {
|
||||
isClosed = '$' == builder.charAt(length - 1)
|
||||
&& '$' == builder.charAt(length - 2);
|
||||
if (isClosed) {
|
||||
builder.replace(length - 2, length, "");
|
||||
}
|
||||
}
|
||||
builder.append('\n');
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -58,37 +88,111 @@ public class JLatexMathBlockParser extends AbstractBlockParser {
|
||||
|
||||
public static class Factory extends AbstractBlockParserFactory {
|
||||
|
||||
// private static final Pattern RE = Pattern.compile("(\\${2,}) *$");
|
||||
|
||||
@Override
|
||||
public BlockStart tryStart(ParserState state, MatchedBlockParser matchedBlockParser) {
|
||||
|
||||
// let's define the spec:
|
||||
// * 0-3 spaces before are allowed (Parsing.CODE_BLOCK_INDENT = 4)
|
||||
// * 2+ subsequent `$` signs
|
||||
// * any optional amount of spaces
|
||||
// * new line
|
||||
// * block is closed when the same amount of opening signs is met
|
||||
|
||||
final int indent = state.getIndent();
|
||||
|
||||
// check if it's an indented code block
|
||||
if (indent < Parsing.CODE_BLOCK_INDENT) {
|
||||
final int nextNonSpaceIndex = state.getNextNonSpaceIndex();
|
||||
final CharSequence line = state.getLine();
|
||||
final int length = line.length();
|
||||
// we are looking for 2 `$$` subsequent signs
|
||||
// and immediate new-line or arbitrary number of white spaces (we check for the first one)
|
||||
// so, nextNonSpaceIndex + 2 >= length and both symbols are `$`s
|
||||
final int diff = length - (nextNonSpaceIndex + 2);
|
||||
if (diff >= 0) {
|
||||
// check for both `$`
|
||||
if (line.charAt(nextNonSpaceIndex) == '$'
|
||||
&& line.charAt(nextNonSpaceIndex + 1) == '$') {
|
||||
|
||||
if (diff > 0) {
|
||||
if (!Character.isWhitespace(line.charAt(nextNonSpaceIndex + 2))) {
|
||||
return BlockStart.none();
|
||||
}
|
||||
// consume all until new-line or first not-white-space char
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
if (indent >= Parsing.CODE_BLOCK_INDENT) {
|
||||
return BlockStart.none();
|
||||
}
|
||||
|
||||
return BlockStart.none();
|
||||
final int nextNonSpaceIndex = state.getNextNonSpaceIndex();
|
||||
final CharSequence line = state.getLine();
|
||||
final int length = line.length();
|
||||
|
||||
// final int signs = Parsing.skip(DOLLAR, line, nextNonSpaceIndex, length) - 1;
|
||||
final int signs = consume(DOLLAR, line, nextNonSpaceIndex, length);
|
||||
|
||||
// 2 is minimum
|
||||
if (signs < 2) {
|
||||
return BlockStart.none();
|
||||
}
|
||||
|
||||
// consume spaces until the end of the line, if any other content is found -> NONE
|
||||
if (Parsing.skip(SPACE, line, nextNonSpaceIndex + signs, length) != length) {
|
||||
return BlockStart.none();
|
||||
}
|
||||
|
||||
Log.e("LTX", String.format("signs: %s, next: %d, length: %d, line: '%s'", signs, nextNonSpaceIndex, length, line));
|
||||
|
||||
return BlockStart.of(new JLatexMathBlockParser(signs))
|
||||
.atIndex(length + 1);
|
||||
|
||||
|
||||
// // check if it's an indented code block
|
||||
// if (indent < Parsing.CODE_BLOCK_INDENT) {
|
||||
//
|
||||
// final int nextNonSpaceIndex = state.getNextNonSpaceIndex();
|
||||
// final CharSequence line = state.getLine();
|
||||
// final int length = line.length();
|
||||
//
|
||||
// final int signs = Parsing.skip('$', line, nextNonSpaceIndex, length);
|
||||
//
|
||||
// // 2 is minimum
|
||||
// if (signs < 2) {
|
||||
// return BlockStart.none();
|
||||
// }
|
||||
//
|
||||
// // consume spaces until the end of the line, if any other content is found -> NONE
|
||||
// if (Parsing.skip(' ', line, nextNonSpaceIndex + signs, length) != length) {
|
||||
// return BlockStart.none();
|
||||
// }
|
||||
//
|
||||
//// // consume spaces until the end of the line, if any other content is found -> NONE
|
||||
//// if ((nextNonSpaceIndex + signs) < length) {
|
||||
//// // check if more content is available
|
||||
//// if (Parsing.skip(' ', line,nextNonSpaceIndex + signs, length) != length) {
|
||||
//// return BlockStart.none();
|
||||
//// }
|
||||
//// }
|
||||
//
|
||||
//// final Matcher matcher = RE.matcher(line);
|
||||
//// matcher.region(nextNonSpaceIndex, length);
|
||||
//
|
||||
//// Log.e("LATEX", String.format("nonSpace: %d, length: %s, line: '%s'", nextNonSpaceIndex, length, line));
|
||||
//
|
||||
// // we are looking for 2 `$$` subsequent signs
|
||||
// // and immediate new-line or arbitrary number of white spaces (we check for the first one)
|
||||
// // so, nextNonSpaceIndex + 2 >= length and both symbols are `$`s
|
||||
// final int diff = length - (nextNonSpaceIndex + 2);
|
||||
// if (diff >= 0) {
|
||||
// // check for both `$`
|
||||
// if (line.charAt(nextNonSpaceIndex) == '$'
|
||||
// && line.charAt(nextNonSpaceIndex + 1) == '$') {
|
||||
//
|
||||
// if (diff > 0) {
|
||||
// if (!Character.isWhitespace(line.charAt(nextNonSpaceIndex + 2))) {
|
||||
// return BlockStart.none();
|
||||
// }
|
||||
// return BlockStart.of(new JLatexMathBlockParser()).atIndex(nextNonSpaceIndex + 3);
|
||||
// }
|
||||
//
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return BlockStart.none();
|
||||
}
|
||||
}
|
||||
|
||||
private static int consume(char c, @NonNull CharSequence line, int start, int end) {
|
||||
for (int i = start; i < end; i++) {
|
||||
if (c != line.charAt(i)) {
|
||||
return i - start;
|
||||
}
|
||||
}
|
||||
// all consumed
|
||||
return end - start;
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
package io.noties.markwon.ext.latex;
|
||||
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Handler;
|
||||
@ -9,6 +10,7 @@ import android.text.Spanned;
|
||||
import android.util.Log;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.IntRange;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.Px;
|
||||
@ -26,10 +28,12 @@ import java.util.concurrent.Future;
|
||||
import io.noties.markwon.AbstractMarkwonPlugin;
|
||||
import io.noties.markwon.MarkwonConfiguration;
|
||||
import io.noties.markwon.MarkwonVisitor;
|
||||
import io.noties.markwon.core.MarkwonTheme;
|
||||
import io.noties.markwon.image.AsyncDrawable;
|
||||
import io.noties.markwon.image.AsyncDrawableLoader;
|
||||
import io.noties.markwon.image.AsyncDrawableScheduler;
|
||||
import io.noties.markwon.image.AsyncDrawableSpan;
|
||||
import io.noties.markwon.image.ImageSize;
|
||||
import io.noties.markwon.image.ImageSizeResolver;
|
||||
import io.noties.markwon.image.ImageSizeResolverDef;
|
||||
import io.noties.markwon.inlineparser.MarkwonInlineParser;
|
||||
@ -129,7 +133,8 @@ public class JLatexMathPlugin extends AbstractMarkwonPlugin {
|
||||
// if it's $$\n -> block
|
||||
// if it's $$\\dhdsfjh$$ -> inline
|
||||
|
||||
// builder.customBlockParserFactory(new JLatexMathBlockParser.Factory());
|
||||
builder.customBlockParserFactory(new JLatexMathBlockParser.Factory());
|
||||
|
||||
final InlineParserFactory factory = MarkwonInlineParser.factoryBuilder()
|
||||
.addInlineProcessor(new JLatexMathInlineProcessor())
|
||||
.build();
|
||||
@ -142,6 +147,8 @@ public class JLatexMathPlugin extends AbstractMarkwonPlugin {
|
||||
@Override
|
||||
public void visit(@NonNull MarkwonVisitor visitor, @NonNull JLatexMathBlock jLatexMathBlock) {
|
||||
|
||||
visitor.ensureNewLine();
|
||||
|
||||
final String latex = jLatexMathBlock.latex();
|
||||
|
||||
final int length = visitor.length();
|
||||
@ -155,15 +162,21 @@ public class JLatexMathPlugin extends AbstractMarkwonPlugin {
|
||||
|
||||
final AsyncDrawableSpan span = new AsyncDrawableSpan(
|
||||
configuration.theme(),
|
||||
new AsyncDrawable(
|
||||
new JLatextAsyncDrawable(
|
||||
latex,
|
||||
jLatextAsyncDrawableLoader,
|
||||
jLatexImageSizeResolver,
|
||||
null),
|
||||
null,
|
||||
true),
|
||||
AsyncDrawableSpan.ALIGN_CENTER,
|
||||
false);
|
||||
|
||||
visitor.setSpans(length, span);
|
||||
|
||||
if (visitor.hasNext(jLatexMathBlock)) {
|
||||
visitor.ensureNewLine();
|
||||
visitor.forceNewLine();
|
||||
}
|
||||
}
|
||||
});
|
||||
builder.on(JLatexMathNode.class, new MarkwonVisitor.NodeVisitor<JLatexMathNode>() {
|
||||
@ -180,13 +193,14 @@ public class JLatexMathPlugin extends AbstractMarkwonPlugin {
|
||||
|
||||
final MarkwonConfiguration configuration = visitor.configuration();
|
||||
|
||||
final AsyncDrawableSpan span = new AsyncDrawableSpan(
|
||||
final AsyncDrawableSpan span = new JLatexAsyncDrawableSpan(
|
||||
configuration.theme(),
|
||||
new AsyncDrawable(
|
||||
new JLatextAsyncDrawable(
|
||||
latex,
|
||||
jLatextAsyncDrawableLoader,
|
||||
new ImageSizeResolverDef(),
|
||||
null),
|
||||
null,
|
||||
false),
|
||||
AsyncDrawableSpan.ALIGN_CENTER,
|
||||
false);
|
||||
|
||||
@ -195,77 +209,6 @@ public class JLatexMathPlugin extends AbstractMarkwonPlugin {
|
||||
});
|
||||
}
|
||||
|
||||
// private static class LatexInlineProcessor extends InlineProcessor {
|
||||
//
|
||||
// @Override
|
||||
// public char specialCharacter() {
|
||||
// return '$';
|
||||
// }
|
||||
//
|
||||
// @Nullable
|
||||
// @Override
|
||||
// protected Node parse() {
|
||||
//
|
||||
// final int start = index;
|
||||
//
|
||||
// index += 1;
|
||||
// if (peek() != '$') {
|
||||
// index = start;
|
||||
// return null;
|
||||
// }
|
||||
//
|
||||
// // must be not $
|
||||
// index += 1;
|
||||
// if (peek() == '$') {
|
||||
// return text("$");
|
||||
// }
|
||||
//
|
||||
// // find next '$$', but not broken with 2(or more) new lines
|
||||
//
|
||||
// boolean dollar = false;
|
||||
// boolean newLine = false;
|
||||
// boolean found = false;
|
||||
//
|
||||
// index += 1;
|
||||
// final int length = input.length();
|
||||
//
|
||||
// while (index < length) {
|
||||
// final char c = peek();
|
||||
// if (c == '\n') {
|
||||
// if (newLine) {
|
||||
// // second new line
|
||||
// break;
|
||||
// }
|
||||
// newLine = true;
|
||||
// dollar = false; // cannot be on another line
|
||||
// } else {
|
||||
// newLine = false;
|
||||
// if (c == '$') {
|
||||
// if (dollar) {
|
||||
// found = true;
|
||||
// // advance
|
||||
// index += 1;
|
||||
// break;
|
||||
// }
|
||||
// dollar = true;
|
||||
// } else {
|
||||
// dollar = false;
|
||||
// }
|
||||
// }
|
||||
// index += 1;
|
||||
// }
|
||||
//
|
||||
// if (found) {
|
||||
// final JLatexMathBlock block = new JLatexMathBlock();
|
||||
// block.latex(input.substring(start + 2, index - 2));
|
||||
// index += 1;
|
||||
// return block;
|
||||
// }
|
||||
//
|
||||
// return null;
|
||||
// }
|
||||
// }
|
||||
|
||||
@Override
|
||||
public void beforeSetText(@NonNull TextView textView, @NonNull Spanned markdown) {
|
||||
AsyncDrawableScheduler.unschedule(textView);
|
||||
@ -401,20 +344,53 @@ public class JLatexMathPlugin extends AbstractMarkwonPlugin {
|
||||
// @since 4.0.1 (background provider can be null)
|
||||
final BackgroundProvider backgroundProvider = config.backgroundProvider;
|
||||
|
||||
final JLatexMathDrawable jLatexMathDrawable;
|
||||
|
||||
final JLatextAsyncDrawable jLatextAsyncDrawable = (JLatextAsyncDrawable) drawable;
|
||||
if (jLatextAsyncDrawable.isBlock) {
|
||||
// create JLatexMathDrawable
|
||||
//noinspection ConstantConditions
|
||||
jLatexMathDrawable =
|
||||
JLatexMathDrawable.builder(drawable.getDestination())
|
||||
.textSize(config.textSize)
|
||||
.background(backgroundProvider != null ? backgroundProvider.provide() : null)
|
||||
.align(config.align)
|
||||
.fitCanvas(config.fitCanvas)
|
||||
.padding(
|
||||
config.paddingHorizontal,
|
||||
config.paddingVertical,
|
||||
config.paddingHorizontal,
|
||||
config.paddingVertical)
|
||||
.build();
|
||||
} else {
|
||||
jLatexMathDrawable =
|
||||
JLatexMathDrawable.builder(drawable.getDestination())
|
||||
.textSize(config.textSize)
|
||||
// .background(backgroundProvider != null ? backgroundProvider.provide() : null)
|
||||
// .align(config.align)
|
||||
// .fitCanvas(config.fitCanvas)
|
||||
// .padding(
|
||||
// config.paddingHorizontal,
|
||||
// config.paddingVertical,
|
||||
// config.paddingHorizontal,
|
||||
// config.paddingVertical)
|
||||
.build();
|
||||
}
|
||||
|
||||
// create JLatexMathDrawable
|
||||
//noinspection ConstantConditions
|
||||
final JLatexMathDrawable jLatexMathDrawable =
|
||||
JLatexMathDrawable.builder(drawable.getDestination())
|
||||
.textSize(config.textSize)
|
||||
.background(backgroundProvider != null ? backgroundProvider.provide() : null)
|
||||
.align(config.align)
|
||||
.fitCanvas(false /*config.fitCanvas*/)
|
||||
.padding(
|
||||
config.paddingHorizontal,
|
||||
config.paddingVertical,
|
||||
config.paddingHorizontal,
|
||||
config.paddingVertical)
|
||||
.build();
|
||||
// //noinspection ConstantConditions
|
||||
// final JLatexMathDrawable jLatexMathDrawable =
|
||||
// JLatexMathDrawable.builder(drawable.getDestination())
|
||||
// .textSize(config.textSize)
|
||||
// .background(backgroundProvider != null ? backgroundProvider.provide() : null)
|
||||
// .align(config.align)
|
||||
// .fitCanvas(config.fitCanvas)
|
||||
// .padding(
|
||||
// config.paddingHorizontal,
|
||||
// config.paddingVertical,
|
||||
// config.paddingHorizontal,
|
||||
// config.paddingVertical)
|
||||
// .build();
|
||||
|
||||
// we must post to handler, but also have a way to identify the drawable
|
||||
// for which we are posting (in case of cancellation)
|
||||
@ -496,4 +472,66 @@ public class JLatexMathPlugin extends AbstractMarkwonPlugin {
|
||||
return imageBounds;
|
||||
}
|
||||
}
|
||||
|
||||
private static class JLatextAsyncDrawable extends AsyncDrawable {
|
||||
|
||||
private final boolean isBlock;
|
||||
|
||||
public JLatextAsyncDrawable(
|
||||
@NonNull String destination,
|
||||
@NonNull AsyncDrawableLoader loader,
|
||||
@NonNull ImageSizeResolver imageSizeResolver,
|
||||
@Nullable ImageSize imageSize,
|
||||
boolean isBlock
|
||||
) {
|
||||
super(destination, loader, imageSizeResolver, imageSize);
|
||||
this.isBlock = isBlock;
|
||||
}
|
||||
}
|
||||
|
||||
private static class JLatexAsyncDrawableSpan extends AsyncDrawableSpan {
|
||||
|
||||
private final AsyncDrawable drawable;
|
||||
|
||||
public JLatexAsyncDrawableSpan(@NonNull MarkwonTheme theme, @NonNull AsyncDrawable drawable, int alignment, boolean replacementTextIsLink) {
|
||||
super(theme, drawable, alignment, replacementTextIsLink);
|
||||
this.drawable = drawable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSize(
|
||||
@NonNull Paint paint,
|
||||
CharSequence text,
|
||||
@IntRange(from = 0) int start,
|
||||
@IntRange(from = 0) int end,
|
||||
@Nullable Paint.FontMetricsInt fm) {
|
||||
|
||||
// if we have no async drawable result - we will just render text
|
||||
|
||||
final int size;
|
||||
|
||||
if (drawable.hasResult()) {
|
||||
|
||||
final Rect rect = drawable.getBounds();
|
||||
|
||||
if (fm != null) {
|
||||
final int half = rect.bottom / 2;
|
||||
fm.ascent = -half;
|
||||
fm.descent = half;
|
||||
|
||||
fm.top = fm.ascent;
|
||||
fm.bottom = 0;
|
||||
}
|
||||
|
||||
size = rect.right;
|
||||
|
||||
} else {
|
||||
|
||||
// NB, no specific text handling (no new lines, etc)
|
||||
size = (int) (paint.measureText(text, start, end) + .5F);
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,28 @@
|
||||
package io.noties.markwon.ext.latex;
|
||||
|
||||
import android.graphics.Rect;
|
||||
|
||||
/**
|
||||
* @since 4.3.0-SNAPSHOT
|
||||
*/
|
||||
public class JLatexMathTheme {
|
||||
|
||||
private float textSize;
|
||||
private float inlineTextSize;
|
||||
private float blockTextSize;
|
||||
|
||||
// TODO: move to a class
|
||||
private JLatexMathPlugin.BackgroundProvider backgroundProvider;
|
||||
private JLatexMathPlugin.BackgroundProvider inlineBackgroundProvider;
|
||||
private JLatexMathPlugin.BackgroundProvider blockBackgroundProvider;
|
||||
|
||||
private boolean blockFitCanvas;
|
||||
// horizontal alignment (when there is additional horizontal space)
|
||||
private int blockAlign;
|
||||
|
||||
private Rect padding;
|
||||
private Rect inlinePadding;
|
||||
private Rect blockPadding;
|
||||
|
||||
|
||||
}
|
@ -4,14 +4,19 @@ import android.app.Activity;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import org.commonmark.node.Node;
|
||||
|
||||
import io.noties.markwon.AbstractMarkwonPlugin;
|
||||
import io.noties.markwon.Markwon;
|
||||
import io.noties.markwon.ext.latex.JLatexMathPlugin;
|
||||
import io.noties.markwon.sample.R;
|
||||
import io.noties.markwon.utils.DumpNodes;
|
||||
import ru.noties.jlatexmath.JLatexMathDrawable;
|
||||
|
||||
public class LatexActivity extends Activity {
|
||||
@ -44,27 +49,33 @@ public class LatexActivity extends Activity {
|
||||
// latex += "\\end{array}";
|
||||
|
||||
final String markdown = "# Example of LaTeX\n\nhello there: $$"
|
||||
+ latex + "$$\n\n something like **this**";
|
||||
+ latex + "$$ so nice, really?\n\n $$ \n" + latex + "\n$$\n\n $$ \n" + latex + "\n$$";
|
||||
|
||||
final Markwon markwon = Markwon.builder(this)
|
||||
// .usePlugin(JLatexMathPlugin.create(textView.getTextSize(), new JLatexMathPlugin.BuilderConfigure() {
|
||||
// @Override
|
||||
// public void configureBuilder(@NonNull JLatexMathPlugin.Builder builder) {
|
||||
// builder
|
||||
// .backgroundProvider(new JLatexMathPlugin.BackgroundProvider() {
|
||||
// @NonNull
|
||||
// @Override
|
||||
// public Drawable provide() {
|
||||
// return new ColorDrawable(0x40ff0000);
|
||||
// }
|
||||
// })
|
||||
// .fitCanvas(true)
|
||||
// .align(JLatexMathDrawable.ALIGN_LEFT)
|
||||
// .padding(48)
|
||||
// ;
|
||||
// }
|
||||
// }))
|
||||
.usePlugin(JLatexMathPlugin.create(textView.getTextSize()))
|
||||
.usePlugin(JLatexMathPlugin.create(textView.getTextSize(), new JLatexMathPlugin.BuilderConfigure() {
|
||||
@Override
|
||||
public void configureBuilder(@NonNull JLatexMathPlugin.Builder builder) {
|
||||
builder
|
||||
.backgroundProvider(new JLatexMathPlugin.BackgroundProvider() {
|
||||
@NonNull
|
||||
@Override
|
||||
public Drawable provide() {
|
||||
return new ColorDrawable(0x40ff0000);
|
||||
}
|
||||
})
|
||||
.fitCanvas(true)
|
||||
.align(JLatexMathDrawable.ALIGN_CENTER)
|
||||
.padding(48)
|
||||
;
|
||||
}
|
||||
}))
|
||||
// .usePlugin(JLatexMathPlugin.create(textView.getTextSize()))
|
||||
.usePlugin(new AbstractMarkwonPlugin() {
|
||||
@Override
|
||||
public void beforeRender(@NonNull Node node) {
|
||||
Log.e("LTX", DumpNodes.dump(node));
|
||||
}
|
||||
})
|
||||
.build();
|
||||
//
|
||||
// if (true) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user