Latex, introduce theme and render-mode
This commit is contained in:
parent
8d483fe49d
commit
c7494a9225
@ -20,7 +20,7 @@ public class LinkResolverDef implements LinkResolver {
|
||||
try {
|
||||
context.startActivity(intent);
|
||||
} catch (ActivityNotFoundException e) {
|
||||
Log.w("LinkResolverDef", "Actvity was not found for intent, " + intent.toString());
|
||||
Log.w("LinkResolverDef", "Actvity was not found for the link: '" + link + "'");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -120,6 +120,7 @@ public class JLatexMathBlockParser extends AbstractBlockParser {
|
||||
}
|
||||
|
||||
// consume spaces until the end of the line, if any other content is found -> NONE
|
||||
// TODO: here we can check mode in which we operate (legacy or not)
|
||||
if (Parsing.skip(SPACE, line, nextNonSpaceIndex + signs, length) != length) {
|
||||
return BlockStart.none();
|
||||
}
|
||||
|
@ -42,8 +42,33 @@ import ru.noties.jlatexmath.JLatexMathDrawable;
|
||||
/**
|
||||
* @since 3.0.0
|
||||
*/
|
||||
public class JLatexMathPlugin extends AbstractMarkwonPlugin {
|
||||
public class JLatexMathPlugin extends AbstractMarkwonPlugin {
|
||||
|
||||
/**
|
||||
* @since 4.3.0-SNAPSHOT
|
||||
*/
|
||||
public enum RenderMode {
|
||||
/**
|
||||
* <em>LEGACY</em> mode mimics pre {@code 4.3.0-SNAPSHOT} behavior by rendering LaTeX blocks only.
|
||||
* In this mode LaTeX is started by `$$` (that must be exactly at the start of a line) and
|
||||
* ended at whatever line that is ended with `$$` characters exactly.
|
||||
*/
|
||||
LEGACY,
|
||||
|
||||
/**
|
||||
* Starting with {@code 4.3.0-SNAPSHOT} it is possible to have LaTeX inlines (which flows inside
|
||||
* a text paragraph without breaking it). Inline LaTeX starts and ends with `$$` symbols. For example:
|
||||
* {@code
|
||||
* **bold $$\\begin{array}\\end{array}$$ bold-end**, and whatever more
|
||||
* }
|
||||
* LaTeX block starts on a new line started by 0-3 spaces and 2 (or more) {@code $} signs
|
||||
* followed by a new-line (with any amount of space characters in-between). And ends on a new-line
|
||||
* starting with 0-3 spaces followed by number of {@code $} signs that was used to <em>start the block</em>.
|
||||
*/
|
||||
BLOCKS_AND_INLINES
|
||||
}
|
||||
|
||||
// TODO: inlines are not moved to a new line when exceed available width.. (api 23, emulator)
|
||||
public interface BuilderConfigure {
|
||||
void configureBuilder(@NonNull Builder builder);
|
||||
}
|
||||
@ -338,6 +363,7 @@ public class JLatexMathPlugin extends AbstractMarkwonPlugin {
|
||||
|
||||
final JLatexMathDrawable jLatexMathDrawable;
|
||||
|
||||
// TODO: obtain real values from theme (for blocks and inlines)
|
||||
final JLatextAsyncDrawable jLatextAsyncDrawable = (JLatextAsyncDrawable) drawable;
|
||||
if (jLatextAsyncDrawable.isBlock) {
|
||||
// create JLatexMathDrawable
|
||||
|
@ -1,6 +1,5 @@
|
||||
package io.noties.markwon.ext.latex;
|
||||
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.drawable.Drawable;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
@ -16,12 +15,22 @@ public abstract class JLatexMathTheme {
|
||||
|
||||
@NonNull
|
||||
public static JLatexMathTheme create(@Px float textSize) {
|
||||
return null;
|
||||
return builder(textSize).build();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static JLatexMathTheme builer() {
|
||||
return null;
|
||||
public static JLatexMathTheme create(@Px float inlineTextSize, @Px float blockTextSize) {
|
||||
return builder(inlineTextSize, blockTextSize).build();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static JLatexMathTheme.Builder builder(@Px float textSize) {
|
||||
return new JLatexMathTheme.Builder(textSize, 0F, 0F);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static JLatexMathTheme.Builder builder(@Px float inlineTextSize, @Px float blockTextSize) {
|
||||
return new Builder(0F, inlineTextSize, blockTextSize);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -73,7 +82,7 @@ public abstract class JLatexMathTheme {
|
||||
|
||||
/**
|
||||
* @return text size in pixels for <strong>inline LaTeX</strong>
|
||||
* @see #blockTexxtSize()
|
||||
* @see #blockTextSize()
|
||||
*/
|
||||
@Px
|
||||
public abstract float inlineTextSize();
|
||||
@ -83,7 +92,7 @@ public abstract class JLatexMathTheme {
|
||||
* @see #inlineTextSize()
|
||||
*/
|
||||
@Px
|
||||
public abstract float blockTexxtSize();
|
||||
public abstract float blockTextSize();
|
||||
|
||||
@Nullable
|
||||
public abstract BackgroundProvider inlineBackgroundProvider();
|
||||
@ -111,9 +120,9 @@ public abstract class JLatexMathTheme {
|
||||
|
||||
|
||||
public static class Builder {
|
||||
private float textSize;
|
||||
private float inlineTextSize;
|
||||
private float blockTextSize;
|
||||
private final float textSize;
|
||||
private final float inlineTextSize;
|
||||
private final float blockTextSize;
|
||||
|
||||
private BackgroundProvider backgroundProvider;
|
||||
private BackgroundProvider inlineBackgroundProvider;
|
||||
@ -121,10 +130,168 @@ public abstract class JLatexMathTheme {
|
||||
|
||||
private boolean blockFitCanvas;
|
||||
// horizontal alignment (when there is additional horizontal space)
|
||||
private int blockAlign;
|
||||
private int blockHorizontalAlignment;
|
||||
|
||||
private Padding padding;
|
||||
private Padding inlinePadding;
|
||||
private Padding blockPadding;
|
||||
|
||||
Builder(float textSize, float inlineTextSize, float blockTextSize) {
|
||||
this.textSize = textSize;
|
||||
this.inlineTextSize = inlineTextSize;
|
||||
this.blockTextSize = blockTextSize;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public Builder backgroundProvider(@Nullable BackgroundProvider backgroundProvider) {
|
||||
this.backgroundProvider = backgroundProvider;
|
||||
this.inlineBackgroundProvider = backgroundProvider;
|
||||
this.blockBackgroundProvider = backgroundProvider;
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public Builder inlineBackgroundProvider(@Nullable BackgroundProvider inlineBackgroundProvider) {
|
||||
this.inlineBackgroundProvider = inlineBackgroundProvider;
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public Builder blockBackgroundProvider(@Nullable BackgroundProvider blockBackgroundProvider) {
|
||||
this.blockBackgroundProvider = blockBackgroundProvider;
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public Builder blockFitCanvas(boolean blockFitCanvas) {
|
||||
this.blockFitCanvas = blockFitCanvas;
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public Builder blockHorizontalAlignment(@JLatexMathDrawable.Align int blockHorizontalAlignment) {
|
||||
this.blockHorizontalAlignment = blockHorizontalAlignment;
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public Builder padding(@Nullable Padding padding) {
|
||||
this.padding = padding;
|
||||
this.inlinePadding = padding;
|
||||
this.blockPadding = padding;
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public Builder inlinePadding(@Nullable Padding inlinePadding) {
|
||||
this.inlinePadding = inlinePadding;
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public Builder blockPadding(@Nullable Padding blockPadding) {
|
||||
this.blockPadding = blockPadding;
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public JLatexMathTheme build() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
static class Impl extends JLatexMathTheme {
|
||||
|
||||
private final float textSize;
|
||||
private final float inlineTextSize;
|
||||
private final float blockTextSize;
|
||||
|
||||
private final BackgroundProvider backgroundProvider;
|
||||
private final BackgroundProvider inlineBackgroundProvider;
|
||||
private final BackgroundProvider blockBackgroundProvider;
|
||||
|
||||
private final boolean blockFitCanvas;
|
||||
// horizontal alignment (when there is additional horizontal space)
|
||||
private int blockHorizontalAlignment;
|
||||
|
||||
private final Padding padding;
|
||||
private final Padding inlinePadding;
|
||||
private final Padding blockPadding;
|
||||
|
||||
Impl(@NonNull Builder builder) {
|
||||
this.textSize = builder.textSize;
|
||||
this.inlineTextSize = builder.inlineTextSize;
|
||||
this.blockTextSize = builder.blockTextSize;
|
||||
this.backgroundProvider = builder.backgroundProvider;
|
||||
this.inlineBackgroundProvider = builder.inlineBackgroundProvider;
|
||||
this.blockBackgroundProvider = builder.blockBackgroundProvider;
|
||||
this.blockFitCanvas = builder.blockFitCanvas;
|
||||
this.blockHorizontalAlignment = builder.blockHorizontalAlignment;
|
||||
this.padding = builder.padding;
|
||||
this.inlinePadding = builder.inlinePadding;
|
||||
this.blockPadding = builder.blockPadding;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float inlineTextSize() {
|
||||
if (inlineTextSize > 0F) {
|
||||
return inlineTextSize;
|
||||
}
|
||||
return textSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float blockTextSize() {
|
||||
if (blockTextSize > 0F) {
|
||||
return blockTextSize;
|
||||
}
|
||||
return textSize;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public BackgroundProvider inlineBackgroundProvider() {
|
||||
if (inlineBackgroundProvider != null) {
|
||||
return inlineBackgroundProvider;
|
||||
}
|
||||
return backgroundProvider;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public BackgroundProvider blockBackgroundProvider() {
|
||||
if (blockBackgroundProvider != null) {
|
||||
return blockBackgroundProvider;
|
||||
}
|
||||
return backgroundProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean blockFitCanvas() {
|
||||
return blockFitCanvas;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int blockHorizontalAlignment() {
|
||||
return blockHorizontalAlignment;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Padding inlinePadding() {
|
||||
if (inlinePadding != null) {
|
||||
return inlinePadding;
|
||||
}
|
||||
return padding;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Padding blockPadding() {
|
||||
if (blockPadding != null) {
|
||||
return blockPadding;
|
||||
}
|
||||
return padding;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,34 @@
|
||||
package io.noties.markwon.sample;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
public abstract class ActivityWithMenuOptions extends Activity {
|
||||
|
||||
@NonNull
|
||||
public abstract MenuOptions menuOptions();
|
||||
|
||||
private MenuOptions menuOptions;
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
menuOptions = menuOptions();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
return menuOptions.onCreateOptionsMenu(menu);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
return menuOptions.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
package io.noties.markwon.sample;
|
||||
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class MenuOptions {
|
||||
|
||||
@NonNull
|
||||
public static MenuOptions create() {
|
||||
return new MenuOptions();
|
||||
}
|
||||
|
||||
// to preserve order use LinkedHashMap
|
||||
private final Map<String, Runnable> actions = new LinkedHashMap<>();
|
||||
|
||||
@NonNull
|
||||
public MenuOptions add(@NonNull String title, @NonNull Runnable action) {
|
||||
actions.put(title, action);
|
||||
return this;
|
||||
}
|
||||
|
||||
boolean onCreateOptionsMenu(Menu menu) {
|
||||
if (!actions.isEmpty()) {
|
||||
for (String key : actions.keySet()) {
|
||||
menu.add(key);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean onOptionsItemSelected(MenuItem item) {
|
||||
final String title = String.valueOf(item.getTitle());
|
||||
final Runnable action = actions.get(title);
|
||||
if (action != null) {
|
||||
action.run();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
@ -1,6 +1,5 @@
|
||||
package io.noties.markwon.sample.editor;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
import android.text.Editable;
|
||||
import android.text.SpannableStringBuilder;
|
||||
@ -42,12 +41,26 @@ import io.noties.markwon.inlineparser.EntityInlineProcessor;
|
||||
import io.noties.markwon.inlineparser.HtmlInlineProcessor;
|
||||
import io.noties.markwon.inlineparser.MarkwonInlineParser;
|
||||
import io.noties.markwon.linkify.LinkifyPlugin;
|
||||
import io.noties.markwon.sample.ActivityWithMenuOptions;
|
||||
import io.noties.markwon.sample.MenuOptions;
|
||||
import io.noties.markwon.sample.R;
|
||||
|
||||
public class EditorActivity extends Activity {
|
||||
public class EditorActivity extends ActivityWithMenuOptions {
|
||||
|
||||
private EditText editText;
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public MenuOptions menuOptions() {
|
||||
return MenuOptions.create()
|
||||
.add("simpleProcess", this::simple_process)
|
||||
.add("simplePreRender", this::simple_pre_render)
|
||||
.add("customPunctuationSpan", this::custom_punctuation_span)
|
||||
.add("additionalEditSpan", this::additional_edit_span)
|
||||
.add("additionalPlugins", this::additional_plugins)
|
||||
.add("multipleEditSpans", this::multiple_edit_spans);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
@ -56,16 +69,6 @@ public class EditorActivity extends Activity {
|
||||
this.editText = findViewById(R.id.edit_text);
|
||||
initBottomBar();
|
||||
|
||||
// simple_process();
|
||||
|
||||
// simple_pre_render();
|
||||
|
||||
// custom_punctuation_span();
|
||||
|
||||
// additional_edit_span();
|
||||
|
||||
// additional_plugins();
|
||||
|
||||
multiple_edit_spans();
|
||||
}
|
||||
|
||||
|
@ -40,24 +40,28 @@ class LinkEditHandler extends AbstractEditHandler<LinkSpan> {
|
||||
final EditLinkSpan editLinkSpan = persistedSpans.get(EditLinkSpan.class);
|
||||
editLinkSpan.link = span.getLink();
|
||||
|
||||
final int s;
|
||||
final int e;
|
||||
// First first __letter__ to find link content (scheme start in URL, receiver in email address)
|
||||
// NB! do not use phone number auto-link (via LinkifyPlugin) as we cannot guarantee proper link
|
||||
// display. For example, we _could_ also look for a digit, but:
|
||||
// * if phone number start with special symbol, we won't have it (`+`, `(`)
|
||||
// * it might interfere with an ordered-list
|
||||
int start = -1;
|
||||
|
||||
// markdown link vs. autolink
|
||||
if ('[' == input.charAt(spanStart)) {
|
||||
s = spanStart + 1;
|
||||
e = spanStart + 1 + spanTextLength;
|
||||
} else {
|
||||
s = spanStart;
|
||||
e = spanStart + spanTextLength;
|
||||
for (int i = spanStart, length = input.length(); i < length; i++) {
|
||||
if (Character.isLetter(input.charAt(i))) {
|
||||
start = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
editable.setSpan(
|
||||
editLinkSpan,
|
||||
s,
|
||||
e,
|
||||
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
|
||||
);
|
||||
if (start > -1) {
|
||||
editable.setSpan(
|
||||
editLinkSpan,
|
||||
start,
|
||||
start + spanTextLength,
|
||||
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
|
@ -1,57 +1,100 @@
|
||||
package io.noties.markwon.sample.latex;
|
||||
|
||||
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.ext.latex.JLatexMathTheme;
|
||||
import io.noties.markwon.sample.ActivityWithMenuOptions;
|
||||
import io.noties.markwon.sample.MenuOptions;
|
||||
import io.noties.markwon.sample.R;
|
||||
import io.noties.markwon.utils.DumpNodes;
|
||||
import ru.noties.jlatexmath.JLatexMathDrawable;
|
||||
|
||||
public class LatexActivity extends Activity {
|
||||
public class LatexActivity extends ActivityWithMenuOptions {
|
||||
|
||||
private TextView textView;
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public MenuOptions menuOptions() {
|
||||
return MenuOptions.create()
|
||||
.add("array", this::array)
|
||||
.add("longDivision", this::longDivision)
|
||||
.add("bangle", this::bangle)
|
||||
.add("boxes", this::boxes)
|
||||
.add("insideBlockQuote", this::insideBlockQuote);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
setContentView(R.layout.activity_text_view);
|
||||
|
||||
final TextView textView = findViewById(R.id.text_view);
|
||||
textView = findViewById(R.id.text_view);
|
||||
|
||||
// String latex = "\\begin{array}{l}";
|
||||
// latex += "\\forall\\varepsilon\\in\\mathbb{R}_+^*\\ \\exists\\eta>0\\ |x-x_0|\\leq\\eta\\Longrightarrow|f(x)-f(x_0)|\\leq\\varepsilon\\\\";
|
||||
// latex += "\\det\\begin{bmatrix}a_{11}&a_{12}&\\cdots&a_{1n}\\\\a_{21}&\\ddots&&\\vdots\\\\\\vdots&&\\ddots&\\vdots\\\\a_{n1}&\\cdots&\\cdots&a_{nn}\\end{bmatrix}\\overset{\\mathrm{def}}{=}\\sum_{\\sigma\\in\\mathfrak{S}_n}\\varepsilon(\\sigma)\\prod_{k=1}^n a_{k\\sigma(k)}\\\\";
|
||||
// latex += "\\sideset{_\\alpha^\\beta}{_\\gamma^\\delta}{\\begin{pmatrix}a&b\\\\c&d\\end{pmatrix}}\\\\";
|
||||
// latex += "\\int_0^\\infty{x^{2n} e^{-a x^2}\\,dx} = \\frac{2n-1}{2a} \\int_0^\\infty{x^{2(n-1)} e^{-a x^2}\\,dx} = \\frac{(2n-1)!!}{2^{n+1}} \\sqrt{\\frac{\\pi}{a^{2n+1}}}\\\\";
|
||||
// latex += "\\int_a^b{f(x)\\,dx} = (b - a) \\sum\\limits_{n = 1}^\\infty {\\sum\\limits_{m = 1}^{2^n - 1} {\\left( { - 1} \\right)^{m + 1} } } 2^{ - n} f(a + m\\left( {b - a} \\right)2^{-n} )\\\\";
|
||||
// latex += "\\int_{-\\pi}^{\\pi} \\sin(\\alpha x) \\sin^n(\\beta x) dx = \\textstyle{\\left \\{ \\begin{array}{cc} (-1)^{(n+1)/2} (-1)^m \\frac{2 \\pi}{2^n} \\binom{n}{m} & n \\mbox{ odd},\\ \\alpha = \\beta (2m-n) \\\\ 0 & \\mbox{otherwise} \\\\ \\end{array} \\right .}\\\\";
|
||||
// latex += "L = \\int_a^b \\sqrt{ \\left|\\sum_{i,j=1}^ng_{ij}(\\gamma(t))\\left(\\frac{d}{dt}x^i\\circ\\gamma(t)\\right)\\left(\\frac{d}{dt}x^j\\circ\\gamma(t)\\right)\\right|}\\,dt\\\\";
|
||||
// latex += "\\begin{array}{rl} s &= \\int_a^b\\left\\|\\frac{d}{dt}\\vec{r}\\,(u(t),v(t))\\right\\|\\,dt \\\\ &= \\int_a^b \\sqrt{u'(t)^2\\,\\vec{r}_u\\cdot\\vec{r}_u + 2u'(t)v'(t)\\, \\vec{r}_u\\cdot\\vec{r}_v+ v'(t)^2\\,\\vec{r}_v\\cdot\\vec{r}_v}\\,\\,\\, dt. \\end{array}\\\\";
|
||||
// latex += "\\end{array}";
|
||||
// array();
|
||||
longDivision();
|
||||
}
|
||||
|
||||
private void array() {
|
||||
String latex = "\\begin{array}{l}";
|
||||
latex += "\\forall\\varepsilon\\in\\mathbb{R}_+^*\\ \\exists\\eta>0\\ |x-x_0|\\leq\\eta\\Longrightarrow|f(x)-f(x_0)|\\leq\\varepsilon\\\\";
|
||||
latex += "\\det\\begin{bmatrix}a_{11}&a_{12}&\\cdots&a_{1n}\\\\a_{21}&\\ddots&&\\vdots\\\\\\vdots&&\\ddots&\\vdots\\\\a_{n1}&\\cdots&\\cdots&a_{nn}\\end{bmatrix}\\overset{\\mathrm{def}}{=}\\sum_{\\sigma\\in\\mathfrak{S}_n}\\varepsilon(\\sigma)\\prod_{k=1}^n a_{k\\sigma(k)}\\\\";
|
||||
latex += "\\sideset{_\\alpha^\\beta}{_\\gamma^\\delta}{\\begin{pmatrix}a&b\\\\c&d\\end{pmatrix}}\\\\";
|
||||
latex += "\\int_0^\\infty{x^{2n} e^{-a x^2}\\,dx} = \\frac{2n-1}{2a} \\int_0^\\infty{x^{2(n-1)} e^{-a x^2}\\,dx} = \\frac{(2n-1)!!}{2^{n+1}} \\sqrt{\\frac{\\pi}{a^{2n+1}}}\\\\";
|
||||
latex += "\\int_a^b{f(x)\\,dx} = (b - a) \\sum\\limits_{n = 1}^\\infty {\\sum\\limits_{m = 1}^{2^n - 1} {\\left( { - 1} \\right)^{m + 1} } } 2^{ - n} f(a + m\\left( {b - a} \\right)2^{-n} )\\\\";
|
||||
latex += "\\int_{-\\pi}^{\\pi} \\sin(\\alpha x) \\sin^n(\\beta x) dx = \\textstyle{\\left \\{ \\begin{array}{cc} (-1)^{(n+1)/2} (-1)^m \\frac{2 \\pi}{2^n} \\binom{n}{m} & n \\mbox{ odd},\\ \\alpha = \\beta (2m-n) \\\\ 0 & \\mbox{otherwise} \\\\ \\end{array} \\right .}\\\\";
|
||||
latex += "L = \\int_a^b \\sqrt{ \\left|\\sum_{i,j=1}^ng_{ij}(\\gamma(t))\\left(\\frac{d}{dt}x^i\\circ\\gamma(t)\\right)\\left(\\frac{d}{dt}x^j\\circ\\gamma(t)\\right)\\right|}\\,dt\\\\";
|
||||
latex += "\\begin{array}{rl} s &= \\int_a^b\\left\\|\\frac{d}{dt}\\vec{r}\\,(u(t),v(t))\\right\\|\\,dt \\\\ &= \\int_a^b \\sqrt{u'(t)^2\\,\\vec{r}_u\\cdot\\vec{r}_u + 2u'(t)v'(t)\\, \\vec{r}_u\\cdot\\vec{r}_v+ v'(t)^2\\,\\vec{r}_v\\cdot\\vec{r}_v}\\,\\,\\, dt. \\end{array}\\\\";
|
||||
latex += "\\end{array}";
|
||||
|
||||
render(wrapLatexInSampleMarkdown(latex));
|
||||
}
|
||||
|
||||
private void longDivision() {
|
||||
String latex = "\\text{A long division \\longdiv{12345}{13}";
|
||||
// String latex = "{a \\bangle b} {c \\brace d} {e \\brack f} {g \\choose h}";
|
||||
render(wrapLatexInSampleMarkdown(latex));
|
||||
}
|
||||
|
||||
// String latex = "\\begin{array}{cc}";
|
||||
// latex += "\\fbox{\\text{A framed box with \\textdbend}}&\\shadowbox{\\text{A shadowed box}}\\cr";
|
||||
// latex += "\\doublebox{\\text{A double framed box}}&\\ovalbox{\\text{An oval framed box}}\\cr";
|
||||
// latex += "\\end{array}";
|
||||
private void bangle() {
|
||||
String latex = "{a \\bangle b} {c \\brace d} {e \\brack f} {g \\choose h}";
|
||||
render(wrapLatexInSampleMarkdown(latex));
|
||||
}
|
||||
|
||||
final String markdown = "# Example of LaTeX\n\nhello there: $$"
|
||||
+ latex + "$$ so nice, really?\n\n $$ \n" + latex + "\n$$\n\n $$ \n" + latex + "\n$$";
|
||||
private void boxes() {
|
||||
String latex = "\\begin{array}{cc}";
|
||||
latex += "\\fbox{\\text{A framed box with \\textdbend}}&\\shadowbox{\\text{A shadowed box}}\\cr";
|
||||
latex += "\\doublebox{\\text{A double framed box}}&\\ovalbox{\\text{An oval framed box}}\\cr";
|
||||
latex += "\\end{array}";
|
||||
render(wrapLatexInSampleMarkdown(latex));
|
||||
}
|
||||
|
||||
private void insideBlockQuote() {
|
||||
String latex = "W=W_1+W_2=F_1X_1-F_2X_2";
|
||||
final String md = "" +
|
||||
"# LaTeX inside a blockquote\n" +
|
||||
"> $$" + latex + "$$\n";
|
||||
render(md);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private static String wrapLatexInSampleMarkdown(@NonNull String latex) {
|
||||
return "" +
|
||||
"# Example of LaTeX\n\n" +
|
||||
"(inline): $$" + latex + "$$ so nice, really? Now, (block):\n\n" +
|
||||
"$$\n" +
|
||||
"" + latex + "\n" +
|
||||
"$$\n\n" +
|
||||
"the end";
|
||||
}
|
||||
|
||||
private void render(@NonNull String markdown) {
|
||||
final Markwon markwon = Markwon.builder(this)
|
||||
.usePlugin(JLatexMathPlugin.create(textView.getTextSize(), new JLatexMathPlugin.BuilderConfigure() {
|
||||
@Override
|
||||
@ -70,37 +113,7 @@ public class LatexActivity extends Activity {
|
||||
;
|
||||
}
|
||||
}))
|
||||
// .usePlugin(JLatexMathPlugin.create(textView.getTextSize()))
|
||||
.usePlugin(new AbstractMarkwonPlugin() {
|
||||
@Override
|
||||
public void beforeRender(@NonNull Node node) {
|
||||
Log.e("LTX", DumpNodes.dump(node));
|
||||
}
|
||||
})
|
||||
.build();
|
||||
//
|
||||
// if (true) {
|
||||
//// final String l = "$$\n" +
|
||||
//// " P(X=r)=\\frac{\\lambda^r e^{-\\lambda}}{r!}\n" +
|
||||
//// "$$\n" +
|
||||
//// "\n" +
|
||||
//// "$$\n" +
|
||||
//// " P(X<r)=P(X<r-1)\n" +
|
||||
//// "$$\n" +
|
||||
//// "\n" +
|
||||
//// "$$\n" +
|
||||
//// " P(X>r)=1-P(X<r=1)\n" +
|
||||
//// "$$\n" +
|
||||
//// "\n" +
|
||||
//// "$$\n" +
|
||||
//// " \\text{Variance} = \\lambda\n" +
|
||||
//// "$$";
|
||||
// final String l = "$$ \n" +
|
||||
// " \\sigma_T^2 = \\frac{1-p}{p^2}\n" +
|
||||
// "$$";
|
||||
// markwon.setMarkdown(textView, l);
|
||||
// return;
|
||||
// }
|
||||
|
||||
markwon.setMarkdown(textView, markdown);
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package io.noties.markwon.sample.tasklist;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Bundle;
|
||||
import android.text.Spanned;
|
||||
import android.text.TextPaint;
|
||||
@ -10,6 +11,9 @@ import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import io.noties.debug.Debug;
|
||||
import io.noties.markwon.AbstractMarkwonPlugin;
|
||||
@ -19,12 +23,34 @@ import io.noties.markwon.SpanFactory;
|
||||
import io.noties.markwon.ext.tasklist.TaskListItem;
|
||||
import io.noties.markwon.ext.tasklist.TaskListPlugin;
|
||||
import io.noties.markwon.ext.tasklist.TaskListSpan;
|
||||
import io.noties.markwon.sample.ActivityWithMenuOptions;
|
||||
import io.noties.markwon.sample.MenuOptions;
|
||||
import io.noties.markwon.sample.R;
|
||||
|
||||
public class TaskListActivity extends Activity {
|
||||
public class TaskListActivity extends ActivityWithMenuOptions {
|
||||
|
||||
private static final String MD = "" +
|
||||
"- [ ] Not done here!\n" +
|
||||
"- [x] and done\n" +
|
||||
"- [X] and again!\n" +
|
||||
"* [ ] **and** syntax _included_ `code`\n" +
|
||||
"- [ ] [link](#)\n" +
|
||||
"- [ ] [a check box](https://goog.le)\n" +
|
||||
"- [x] [test]()\n" +
|
||||
"- [List](https://goog.le) 3";
|
||||
|
||||
private TextView textView;
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public MenuOptions menuOptions() {
|
||||
return MenuOptions.create()
|
||||
.add("regular", this::regular)
|
||||
.add("customColors", this::customColors)
|
||||
.add("customDrawableResources", this::customDrawableResources)
|
||||
.add("mutate", this::mutate);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
@ -32,7 +58,44 @@ public class TaskListActivity extends Activity {
|
||||
|
||||
textView = findViewById(R.id.text_view);
|
||||
|
||||
mutate();
|
||||
// mutate();
|
||||
regular();
|
||||
}
|
||||
|
||||
private void regular() {
|
||||
// default theme
|
||||
|
||||
final Markwon markwon = Markwon.builder(this)
|
||||
.usePlugin(TaskListPlugin.create(this))
|
||||
.build();
|
||||
|
||||
markwon.setMarkdown(textView, MD);
|
||||
}
|
||||
|
||||
private void customColors() {
|
||||
|
||||
final int checkedFillColor = Color.RED;
|
||||
final int normalOutlineColor = Color.GREEN;
|
||||
final int checkMarkColor = Color.BLUE;
|
||||
|
||||
final Markwon markwon = Markwon.builder(this)
|
||||
.usePlugin(TaskListPlugin.create(checkedFillColor, normalOutlineColor, checkMarkColor))
|
||||
.build();
|
||||
|
||||
markwon.setMarkdown(textView, MD);
|
||||
}
|
||||
|
||||
private void customDrawableResources() {
|
||||
// drawable **must** be stateful
|
||||
|
||||
final Drawable drawable = Objects.requireNonNull(
|
||||
ContextCompat.getDrawable(this, R.drawable.custom_task_list));
|
||||
|
||||
final Markwon markwon = Markwon.builder(this)
|
||||
.usePlugin(TaskListPlugin.create(drawable))
|
||||
.build();
|
||||
|
||||
markwon.setMarkdown(textView, MD);
|
||||
}
|
||||
|
||||
private void mutate() {
|
||||
@ -56,6 +119,7 @@ public class TaskListActivity extends Activity {
|
||||
return null;
|
||||
}
|
||||
|
||||
// NB, toggle click will intercept possible links inside task-list-item
|
||||
return new Object[]{
|
||||
span,
|
||||
new TaskListToggleSpan(span)
|
||||
@ -65,13 +129,7 @@ public class TaskListActivity extends Activity {
|
||||
})
|
||||
.build();
|
||||
|
||||
final String md = "" +
|
||||
"- [ ] Not done here!\n" +
|
||||
"- [x] and done\n" +
|
||||
"- [X] and again!\n" +
|
||||
"* [ ] **and** syntax _included_ `code`";
|
||||
|
||||
markwon.setMarkdown(textView, md);
|
||||
markwon.setMarkdown(textView, MD);
|
||||
}
|
||||
|
||||
private static class TaskListToggleSpan extends ClickableSpan {
|
||||
|
5
sample/src/main/res/drawable/custom_task_list.xml
Normal file
5
sample/src/main/res/drawable/custom_task_list.xml
Normal file
@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:state_checked="true" android:drawable="@drawable/ic_android_black_24dp" />
|
||||
<item android:drawable="@drawable/ic_home_black_36dp" />
|
||||
</selector>
|
Loading…
x
Reference in New Issue
Block a user