Merge with 2.0.2 changes
This commit is contained in:
commit
421fc95d6f
@ -61,14 +61,28 @@ public class BulletListItemSpan implements LeadingMarginSpan {
|
|||||||
|
|
||||||
final int marginLeft = (width - side) / 2;
|
final int marginLeft = (width - side) / 2;
|
||||||
|
|
||||||
|
// @since 2.0.2
|
||||||
|
// There is a bug in Android Nougat, when this span receives an `x` that
|
||||||
|
// doesn't correspond to what it should be (text is placed correctly though).
|
||||||
|
// Let's make this a general rule -> manually calculate difference between expected/actual
|
||||||
|
// and add this difference to resulting left/right values. If everything goes well
|
||||||
|
// we do not encounter a bug -> this `diff` value will be 0
|
||||||
|
final int diff;
|
||||||
|
if (dir < 0) {
|
||||||
|
// rtl
|
||||||
|
diff = x - (layout.getWidth() - (width * level));
|
||||||
|
} else {
|
||||||
|
diff = (width * level) - x;
|
||||||
|
}
|
||||||
|
|
||||||
// in order to support RTL
|
// in order to support RTL
|
||||||
final int l;
|
final int l;
|
||||||
final int r;
|
final int r;
|
||||||
{
|
{
|
||||||
final int left = x + (dir * marginLeft);
|
final int left = x + (dir * marginLeft);
|
||||||
final int right = left + (dir * side);
|
final int right = left + (dir * side);
|
||||||
l = Math.min(left, right);
|
l = Math.min(left, right) + (dir * diff);
|
||||||
r = Math.max(left, right);
|
r = Math.max(left, right) + (dir * diff);
|
||||||
}
|
}
|
||||||
|
|
||||||
final int t = baseline + (int) ((paint.descent() + paint.ascent()) / 2.F + .5F) - (side / 2);
|
final int t = baseline + (int) ((paint.descent() + paint.ascent()) / 2.F + .5F) - (side / 2);
|
||||||
|
@ -15,6 +15,15 @@ android {
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
api project(':markwon-core')
|
api project(':markwon-core')
|
||||||
|
|
||||||
|
deps['test'].with {
|
||||||
|
|
||||||
|
testImplementation project(':markwon-test-span')
|
||||||
|
|
||||||
|
testImplementation it['junit']
|
||||||
|
testImplementation it['robolectric']
|
||||||
|
testImplementation it['commons-io']
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
registerArtifact(this)
|
registerArtifact(this)
|
@ -23,7 +23,7 @@ import java.util.regex.Pattern;
|
|||||||
@SuppressWarnings("WeakerAccess")
|
@SuppressWarnings("WeakerAccess")
|
||||||
class TaskListBlockParser extends AbstractBlockParser {
|
class TaskListBlockParser extends AbstractBlockParser {
|
||||||
|
|
||||||
private static final Pattern PATTERN = Pattern.compile("\\s*-\\s+\\[(x|X|\\s)\\]\\s+(.*)");
|
private static final Pattern PATTERN = Pattern.compile("\\s*([-*+]|\\d{1,9}[.)])\\s+\\[(x|X|\\s)]\\s+(.*)");
|
||||||
|
|
||||||
private final TaskListBlock block = new TaskListBlock();
|
private final TaskListBlock block = new TaskListBlock();
|
||||||
|
|
||||||
@ -88,9 +88,9 @@ class TaskListBlockParser extends AbstractBlockParser {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
listItem = new TaskListItem()
|
listItem = new TaskListItem()
|
||||||
.done(isDone(matcher.group(1)))
|
.done(isDone(matcher.group(2)))
|
||||||
.indent(item.indent / 2);
|
.indent(item.indent / 2);
|
||||||
inlineParser.parse(matcher.group(2), listItem);
|
inlineParser.parse(matcher.group(3), listItem);
|
||||||
block.appendChild(listItem);
|
block.appendChild(listItem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,101 @@
|
|||||||
|
package ru.noties.markwon.ext.tasklist;
|
||||||
|
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
|
||||||
|
import org.apache.commons.io.IOUtils;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.robolectric.RobolectricTestRunner;
|
||||||
|
import org.robolectric.RuntimeEnvironment;
|
||||||
|
import org.robolectric.annotation.Config;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
|
import ru.noties.markwon.AbstractMarkwonPlugin;
|
||||||
|
import ru.noties.markwon.Markwon;
|
||||||
|
import ru.noties.markwon.MarkwonConfiguration;
|
||||||
|
import ru.noties.markwon.MarkwonSpansFactory;
|
||||||
|
import ru.noties.markwon.RenderProps;
|
||||||
|
import ru.noties.markwon.SpanFactory;
|
||||||
|
import ru.noties.markwon.test.TestSpan;
|
||||||
|
import ru.noties.markwon.test.TestSpanMatcher;
|
||||||
|
|
||||||
|
import static ru.noties.markwon.test.TestSpan.args;
|
||||||
|
import static ru.noties.markwon.test.TestSpan.document;
|
||||||
|
import static ru.noties.markwon.test.TestSpan.span;
|
||||||
|
import static ru.noties.markwon.test.TestSpan.text;
|
||||||
|
|
||||||
|
@RunWith(RobolectricTestRunner.class)
|
||||||
|
@Config(manifest = Config.NONE)
|
||||||
|
public class TaskListTest {
|
||||||
|
|
||||||
|
private static final String SPAN = "task-list";
|
||||||
|
private static final String IS_DONE = "is-done";
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test() {
|
||||||
|
|
||||||
|
final TestSpan.Document document = document(
|
||||||
|
span(SPAN, args(IS_DONE, false), text("First")),
|
||||||
|
newLine(),
|
||||||
|
span(SPAN, args(IS_DONE, true), text("Second")),
|
||||||
|
newLine(),
|
||||||
|
span(SPAN, args(IS_DONE, true), text("Third")),
|
||||||
|
newLine(),
|
||||||
|
span(SPAN, args(IS_DONE, false), text("First star")),
|
||||||
|
newLine(),
|
||||||
|
span(SPAN, args(IS_DONE, true), text("Second star")),
|
||||||
|
newLine(),
|
||||||
|
span(SPAN, args(IS_DONE, true), text("Third star")),
|
||||||
|
newLine(),
|
||||||
|
span(SPAN, args(IS_DONE, false), text("First plus")),
|
||||||
|
newLine(),
|
||||||
|
span(SPAN, args(IS_DONE, true), text("Second plus")),
|
||||||
|
newLine(),
|
||||||
|
span(SPAN, args(IS_DONE, true), text("Third plus")),
|
||||||
|
newLine(),
|
||||||
|
span(SPAN, args(IS_DONE, true), text("Number with dot")),
|
||||||
|
newLine(),
|
||||||
|
span(SPAN, args(IS_DONE, false), text("Number"))
|
||||||
|
);
|
||||||
|
|
||||||
|
TestSpanMatcher.matches(
|
||||||
|
markwon().toMarkdown(read("task-lists.md")),
|
||||||
|
document
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
private static Markwon markwon() {
|
||||||
|
return Markwon.builder(RuntimeEnvironment.application)
|
||||||
|
.usePlugin(TaskListPlugin.create(RuntimeEnvironment.application))
|
||||||
|
.usePlugin(new AbstractMarkwonPlugin() {
|
||||||
|
@Override
|
||||||
|
public void configureSpansFactory(@NonNull MarkwonSpansFactory.Builder builder) {
|
||||||
|
builder.setFactory(TaskListItem.class, new SpanFactory() {
|
||||||
|
@Override
|
||||||
|
public Object getSpans(@NonNull MarkwonConfiguration configuration, @NonNull RenderProps props) {
|
||||||
|
return span(SPAN, args(IS_DONE, TaskListProps.DONE.require(props)));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("SameParameterValue")
|
||||||
|
@NonNull
|
||||||
|
private static String read(@NonNull String name) {
|
||||||
|
try {
|
||||||
|
return IOUtils.resourceToString("tests/" + name, StandardCharsets.UTF_8, TaskListDrawable.class.getClassLoader());
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
private static TestSpan.Text newLine() {
|
||||||
|
return text("\n");
|
||||||
|
}
|
||||||
|
}
|
11
markwon-ext-tasklist/src/test/resources/tests/task-lists.md
Normal file
11
markwon-ext-tasklist/src/test/resources/tests/task-lists.md
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
- [ ] First
|
||||||
|
- [x] Second
|
||||||
|
- [X] Third
|
||||||
|
* [ ] First star
|
||||||
|
* [x] Second star
|
||||||
|
* [X] Third star
|
||||||
|
+ [ ] First plus
|
||||||
|
+ [x] Second plus
|
||||||
|
+ [X] Third plus
|
||||||
|
1. [x] Number with dot
|
||||||
|
3) [ ] Number
|
@ -3,8 +3,9 @@ package ru.noties.markwon.test;
|
|||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
import android.text.Spanned;
|
import android.text.Spanned;
|
||||||
|
|
||||||
import junit.framework.Assert;
|
|
||||||
import junit.framework.ComparisonFailure;
|
import org.junit.Assert;
|
||||||
|
import org.junit.ComparisonFailure;
|
||||||
|
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
@ -106,8 +107,8 @@ public abstract class TestSpanMatcher {
|
|||||||
}
|
}
|
||||||
|
|
||||||
throw new AssertionError(
|
throw new AssertionError(
|
||||||
String.format(Locale.US, "Expected span{%s} at {start: %d, end: %d}, found: %s",
|
String.format(Locale.US, "Expected span{%s} at {start: %d, end: %d}, found: %s, text: \"%s\"",
|
||||||
expectedSpan, start, end, actualSpan));
|
expectedSpan, start, end, actualSpan, spanned.subSequence(start, end)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user