Merge f711d6d702aa85b9d5804e7d758558183521f938 into 2ea148c30a07f91ffa37c0aa36af1cf2670441af
This commit is contained in:
commit
de61c5e756
@ -1,11 +1,11 @@
|
|||||||
package io.noties.markwon.ext.latex;
|
package io.noties.markwon.ext.latex;
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
|
|
||||||
import org.commonmark.node.Node;
|
import org.commonmark.node.Node;
|
||||||
|
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.annotation.VisibleForTesting;
|
||||||
import io.noties.markwon.inlineparser.InlineProcessor;
|
import io.noties.markwon.inlineparser.InlineProcessor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -13,7 +13,24 @@ import io.noties.markwon.inlineparser.InlineProcessor;
|
|||||||
*/
|
*/
|
||||||
class JLatexMathInlineProcessor extends InlineProcessor {
|
class JLatexMathInlineProcessor extends InlineProcessor {
|
||||||
|
|
||||||
private static final Pattern RE = Pattern.compile("(\\${2})([\\s\\S]+?)\\1");
|
private static final Pattern singleOrDoubleDollar =
|
||||||
|
Pattern.compile("(\\${2})([\\s\\S]+?)(\\${2})|(\\$)([\\s\\S]+?)(\\$)");
|
||||||
|
private static final Pattern doubleDollar =
|
||||||
|
Pattern.compile("(\\${2})([\\s\\S]+?)\\1");
|
||||||
|
|
||||||
|
private final boolean allowSingle$;
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
final Pattern pattern;
|
||||||
|
|
||||||
|
JLatexMathInlineProcessor() {
|
||||||
|
this(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
JLatexMathInlineProcessor(boolean allowSingle$) {
|
||||||
|
this.allowSingle$ = allowSingle$;
|
||||||
|
this.pattern = allowSingle$ ? singleOrDoubleDollar : doubleDollar;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public char specialCharacter() {
|
public char specialCharacter() {
|
||||||
@ -24,13 +41,25 @@ class JLatexMathInlineProcessor extends InlineProcessor {
|
|||||||
@Override
|
@Override
|
||||||
protected Node parse() {
|
protected Node parse() {
|
||||||
|
|
||||||
final String latex = match(RE);
|
final String latex = match(pattern);
|
||||||
if (latex == null) {
|
if (latex == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
final JLatexMathNode node = new JLatexMathNode();
|
final JLatexMathNode node = new JLatexMathNode();
|
||||||
node.latex(latex.substring(2, latex.length() - 2));
|
node.latex(trimDollar(latex));
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("DuplicateExpressions")
|
||||||
|
@VisibleForTesting
|
||||||
|
String trimDollar(String latex) {
|
||||||
|
if (allowSingle$) {
|
||||||
|
return latex.startsWith("$$") && latex.endsWith("$$")
|
||||||
|
? latex.substring(2, latex.length() - 2)
|
||||||
|
: latex.substring(1, latex.length() - 1);
|
||||||
|
} else {
|
||||||
|
return latex.substring(2, latex.length() - 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -119,6 +119,7 @@ public class JLatexMathPlugin extends AbstractMarkwonPlugin {
|
|||||||
final boolean blocksEnabled;
|
final boolean blocksEnabled;
|
||||||
final boolean blocksLegacy;
|
final boolean blocksLegacy;
|
||||||
final boolean inlinesEnabled;
|
final boolean inlinesEnabled;
|
||||||
|
final boolean allowInlineSingle$;
|
||||||
|
|
||||||
// @since 4.3.0
|
// @since 4.3.0
|
||||||
final ErrorHandler errorHandler;
|
final ErrorHandler errorHandler;
|
||||||
@ -130,6 +131,7 @@ public class JLatexMathPlugin extends AbstractMarkwonPlugin {
|
|||||||
this.blocksEnabled = builder.blocksEnabled;
|
this.blocksEnabled = builder.blocksEnabled;
|
||||||
this.blocksLegacy = builder.blocksLegacy;
|
this.blocksLegacy = builder.blocksLegacy;
|
||||||
this.inlinesEnabled = builder.inlinesEnabled;
|
this.inlinesEnabled = builder.inlinesEnabled;
|
||||||
|
this.allowInlineSingle$ = builder.allowInlineSingle$;
|
||||||
this.errorHandler = builder.errorHandler;
|
this.errorHandler = builder.errorHandler;
|
||||||
// @since 4.0.0
|
// @since 4.0.0
|
||||||
ExecutorService executorService = builder.executorService;
|
ExecutorService executorService = builder.executorService;
|
||||||
@ -160,7 +162,7 @@ public class JLatexMathPlugin extends AbstractMarkwonPlugin {
|
|||||||
if (config.inlinesEnabled) {
|
if (config.inlinesEnabled) {
|
||||||
registry.require(MarkwonInlineParserPlugin.class)
|
registry.require(MarkwonInlineParserPlugin.class)
|
||||||
.factoryBuilder()
|
.factoryBuilder()
|
||||||
.addInlineProcessor(new JLatexMathInlineProcessor());
|
.addInlineProcessor(new JLatexMathInlineProcessor(config.allowInlineSingle$));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -285,6 +287,7 @@ public class JLatexMathPlugin extends AbstractMarkwonPlugin {
|
|||||||
private boolean blocksEnabled = true;
|
private boolean blocksEnabled = true;
|
||||||
private boolean blocksLegacy;
|
private boolean blocksLegacy;
|
||||||
private boolean inlinesEnabled;
|
private boolean inlinesEnabled;
|
||||||
|
private boolean allowInlineSingle$;
|
||||||
|
|
||||||
// @since 4.3.0
|
// @since 4.3.0
|
||||||
private ErrorHandler errorHandler;
|
private ErrorHandler errorHandler;
|
||||||
@ -331,6 +334,16 @@ public class JLatexMathPlugin extends AbstractMarkwonPlugin {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param inlineSingleDollar indicates if $xxx$ is valid.
|
||||||
|
* @since 4.7.0
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
public Builder allowInlinesSingleDollar(boolean inlineSingleDollar){
|
||||||
|
this.allowInlineSingle$ = inlineSingleDollar;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
public Builder errorHandler(@Nullable ErrorHandler errorHandler) {
|
public Builder errorHandler(@Nullable ErrorHandler errorHandler) {
|
||||||
this.errorHandler = errorHandler;
|
this.errorHandler = errorHandler;
|
||||||
|
@ -0,0 +1,98 @@
|
|||||||
|
package io.noties.markwon.ext.latex;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.junit.runners.Parameterized;
|
||||||
|
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author YvesCheung
|
||||||
|
* 2023/6/14
|
||||||
|
*/
|
||||||
|
@RunWith(Parameterized.class)
|
||||||
|
public class JLatexMathInlineParserTest {
|
||||||
|
|
||||||
|
@Parameterized.Parameters
|
||||||
|
public static Object[][] data() {
|
||||||
|
return new Object[][]{
|
||||||
|
{true, "$ a $", "$ a $", " a "},
|
||||||
|
{false, "$ a $", "", ""},
|
||||||
|
|
||||||
|
{true, "ashdksa $ a $sfalhs", "$ a $", " a "},
|
||||||
|
{false, "ashdksa $ a $sfalhs", "", ""},
|
||||||
|
|
||||||
|
{true, "c sajdl asjkdhk $abc$\n sahdila", "$abc$", "abc"},
|
||||||
|
{false, "c sajdl asjkdhk $abc$\n sahdila", "", ""},
|
||||||
|
|
||||||
|
{true, "c sajdl asjkdhk \n$abcd $ sahdila", "$abcd $", "abcd "},
|
||||||
|
{false, "c sajdl asjkdhk \n$abcd $ sahdila", "", ""},
|
||||||
|
|
||||||
|
{true, "$$abc$$", "$$abc$$", "abc"},
|
||||||
|
{false, "$$abc$$", "$$abc$$", "abc"},
|
||||||
|
|
||||||
|
{true, "$$abc$", "$$abc$", "$abc"},
|
||||||
|
{false, "$$abc$", "", ""},
|
||||||
|
|
||||||
|
{true, "lllll bbb xxx $dhaksdhk\n asd ${b}", "$dhaksdhk\n asd $", "dhaksdhk\n asd "},
|
||||||
|
{false, "lllll bbb xxx $dhaksdhk\n asd ${b}", "", ""},
|
||||||
|
|
||||||
|
{true, "aaa yyy $$bb $ dddd$", "$$bb $", "$bb "},
|
||||||
|
{false, "aaa yyy $$bb $ dddd$", "", ""},
|
||||||
|
|
||||||
|
{true, "aaa $sagdkg$$ Hello", "$sagdkg$", "sagdkg"},
|
||||||
|
{false, "aaa $sagdkg$$ Hello", "", ""},
|
||||||
|
|
||||||
|
{true, "lllll bbb xxx dhaksdhk\n asd ${b}", "", ""},
|
||||||
|
{false, "lllll bbb xxx dhaksdhk\n asd ${b}", "", ""},
|
||||||
|
|
||||||
|
{true, "asdhfalkhasl suaflhslia lasdjikaih sahk", "", ""},
|
||||||
|
{false, "asdhfalkhasl suaflhslia lasdjikaih sahk", "", ""},
|
||||||
|
|
||||||
|
{true, "lllll bbb $xxx dhaksdhk\n asd", "", ""},
|
||||||
|
{false, "lllll bbb $xxx dhaksdhk\n asd", "", ""}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Parameterized.Parameter(0)
|
||||||
|
public boolean allowSingle$;
|
||||||
|
|
||||||
|
@Parameterized.Parameter(1)
|
||||||
|
public String input;
|
||||||
|
|
||||||
|
@Parameterized.Parameter(2)
|
||||||
|
public String output;
|
||||||
|
|
||||||
|
@Parameterized.Parameter(3)
|
||||||
|
public String trimOutput;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void match() {
|
||||||
|
JLatexMathInlineProcessor processor = new JLatexMathInlineProcessor(allowSingle$);
|
||||||
|
Matcher matcher = processor.pattern.matcher(input);
|
||||||
|
if (output == null || "".equals(output)) {
|
||||||
|
Assert.assertFalse(matcher.find());
|
||||||
|
} else {
|
||||||
|
Assert.assertTrue(matcher.find());
|
||||||
|
String actual = matcher.group();
|
||||||
|
Assert.assertEquals(output, actual);
|
||||||
|
Assert.assertEquals(trimOutput, processor.trimDollar(actual));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void not_match() {
|
||||||
|
String[][] testCase = new String[][]{
|
||||||
|
new String[]{"lllll bbb xxx dhaksdhk\n asd ${b}"},
|
||||||
|
new String[]{"asdhfalkhasl suaflhslia lasdjikaih sahk"},
|
||||||
|
new String[]{"lllll bbb $xxx dhaksdhk\n asd"},
|
||||||
|
};
|
||||||
|
for (String[] c : testCase) {
|
||||||
|
String input = c[0];
|
||||||
|
JLatexMathInlineProcessor processor = new JLatexMathInlineProcessor(true);
|
||||||
|
Matcher matcher = processor.pattern.matcher(input);
|
||||||
|
Assert.assertFalse(matcher.find());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user