Merge f711d6d702aa85b9d5804e7d758558183521f938 into 2ea148c30a07f91ffa37c0aa36af1cf2670441af

This commit is contained in:
张宇 2023-06-14 12:31:54 +00:00 committed by GitHub
commit de61c5e756
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 146 additions and 6 deletions

View File

@ -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);
}
}
} }

View File

@ -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;

View File

@ -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());
}
}
}