Returned tables

This commit is contained in:
Dimitry Ivanov 2017-11-02 18:50:36 +03:00
parent 0588fd588d
commit e37d6e1729
3 changed files with 73 additions and 30 deletions

View File

@ -17,7 +17,6 @@
android:layout_margin="16dip" android:layout_margin="16dip"
android:lineSpacingExtra="2dip" android:lineSpacingExtra="2dip"
android:textSize="16sp" android:textSize="16sp"
android:textDirection="rtl"
tools:context="ru.noties.markwon.MainActivity" tools:context="ru.noties.markwon.MainActivity"
tools:text="yo\nman" /> tools:text="yo\nman" />

View File

@ -7,6 +7,7 @@ import android.text.Spanned;
import java.util.ArrayDeque; import java.util.ArrayDeque;
import java.util.Deque; import java.util.Deque;
import java.util.Iterator;
/** /**
* This class is used to _revert_ order of applied spans. Original SpannableStringBuilder * This class is used to _revert_ order of applied spans. Original SpannableStringBuilder
@ -14,6 +15,7 @@ import java.util.Deque;
* will be drawn first, which leads to subtle bugs (spans receive wrong `x` values when * will be drawn first, which leads to subtle bugs (spans receive wrong `x` values when
* requested to draw itself) * requested to draw itself)
*/ */
@SuppressWarnings({"WeakerAccess", "unused"})
public class SpannableBuilder { public class SpannableBuilder {
// do not implement CharSequence (or any of Spanned interfaces) // do not implement CharSequence (or any of Spanned interfaces)
@ -24,25 +26,12 @@ public class SpannableBuilder {
private final Deque<Span> spans = new ArrayDeque<>(8); private final Deque<Span> spans = new ArrayDeque<>(8);
public SpannableBuilder() { public SpannableBuilder() {
this(null); this("");
} }
public SpannableBuilder(@Nullable CharSequence cs) { public SpannableBuilder(@NonNull CharSequence cs) {
this.builder = new SpannableStringBuilderImpl(cs.toString());
final CharSequence text; copySpans(cs);
if (cs != null) {
text = cs;
} else {
text = null;
}
if (text == null) {
this.builder = new SpannableStringBuilderImpl();
} else {
this.builder = new SpannableStringBuilderImpl(text.toString());
copySpans(text);
}
} }
/** /**
@ -117,6 +106,59 @@ public class SpannableBuilder {
return builder.charAt(length() - 1); return builder.charAt(length() - 1);
} }
@NonNull
public CharSequence remove(int start, int end) {
// okay: here is what we will try to do:
final SpannableStringBuilderImpl impl = new SpannableStringBuilderImpl(builder.subSequence(start, end));
final Iterator<Span> iterator = spans.iterator();
Span span;
while (iterator.hasNext() && ((span = iterator.next())) != null) {
if (span.start >= start && span.end <= end) {
impl.setSpan(span.what, span.start - start, span.end - start, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
iterator.remove();
}
}
// SHIFT EXISTING!
if (spans.size() > 0) {
for (Span s : spans) {
// if end < start -> not affected
if (s.end < start) {
continue;
}
// if end between start & end (which is really bad one) -> make end=start
if (s.end >= start && s.end <= end) {
s.end = start;
continue;
}
// if start between start&end -> make start=end
if (s.start >= start && s.start <= end) {
s.start = start;
// shift end by difference
s.end = s.end - (end - start);
continue;
}
// if after, just shift by difference
final int diff = end - start;
s.start = s.start - diff;
s.end = s.end - diff;
}
}
return impl;
}
@Override @Override
@NonNull @NonNull
public String toString() { public String toString() {
@ -128,7 +170,15 @@ public class SpannableBuilder {
// as we keep track of them independently). Must warn user to NOT apply inputFilters // as we keep track of them independently). Must warn user to NOT apply inputFilters
@NonNull @NonNull
public CharSequence text() { public CharSequence text() {
// if called once, it will apply spans, which will modify our state
applySpans(); applySpans();
// we could return here for example new SpannableStringBuilder(builder)
// but, if returned value will be used in other SpannableBuilder,
// we won't be able to detect in what order to store the spans
return builder; return builder;
} }
@ -173,8 +223,8 @@ public class SpannableBuilder {
private static class Span { private static class Span {
final Object what; final Object what;
final int start; int start;
final int end; int end;
final int flags; final int flags;
Span(@NonNull Object what, int start, int end, int flags) { Span(@NonNull Object what, int start, int end, int flags) {

View File

@ -61,7 +61,6 @@ import ru.noties.markwon.tasklist.TaskListItem;
public class SpannableMarkdownVisitor extends AbstractVisitor { public class SpannableMarkdownVisitor extends AbstractVisitor {
private final SpannableConfiguration configuration; private final SpannableConfiguration configuration;
// private final SpannableStringBuilder builder;
private final SpannableBuilder builder; private final SpannableBuilder builder;
private final Deque<HtmlInlineItem> htmlInlineItems; private final Deque<HtmlInlineItem> htmlInlineItems;
@ -321,10 +320,6 @@ public class SpannableMarkdownVisitor extends AbstractVisitor {
private boolean handleTableNodes(CustomNode node) { private boolean handleTableNodes(CustomNode node) {
if (true) {
return false;
}
final boolean handled; final boolean handled;
if (node instanceof TableBody) { if (node instanceof TableBody) {
@ -367,11 +362,10 @@ public class SpannableMarkdownVisitor extends AbstractVisitor {
pendingTableRow = new ArrayList<>(2); pendingTableRow = new ArrayList<>(2);
} }
// pendingTableRow.add(new TableRowSpan.Cell( pendingTableRow.add(new TableRowSpan.Cell(
// tableCellAlignment(cell.getAlignment()), tableCellAlignment(cell.getAlignment()),
// builder.subSequence(length, builder.length()) builder.remove(length, builder.length())
// )); ));
// builder.replace(length, builder.length(), "");
tableRowIsHeader = cell.isHeader(); tableRowIsHeader = cell.isHeader();