diff --git a/app/src/main/java/com/fastaccess/provider/markdown/MarkDownProvider.java b/app/src/main/java/com/fastaccess/provider/markdown/MarkDownProvider.java index 00354337..221a7355 100644 --- a/app/src/main/java/com/fastaccess/provider/markdown/MarkDownProvider.java +++ b/app/src/main/java/com/fastaccess/provider/markdown/MarkDownProvider.java @@ -3,17 +3,12 @@ package com.fastaccess.provider.markdown; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.text.Html; -import android.util.Log; import android.webkit.MimeTypeMap; -import android.widget.CheckBox; import android.widget.EditText; import android.widget.TextView; import com.annimon.stream.IntStream; import com.fastaccess.helper.InputHelper; -import com.fastaccess.helper.ViewHelper; -import com.fastaccess.provider.timeline.handler.DrawableGetter; -import com.zzhoujay.markdown.MarkDown; import org.commonmark.node.Node; import org.commonmark.parser.Parser; diff --git a/app/src/main/java/com/zzhoujay/markdown/MarkDown.java b/app/src/main/java/com/zzhoujay/markdown/MarkDown.java deleted file mode 100755 index b82305b4..00000000 --- a/app/src/main/java/com/zzhoujay/markdown/MarkDown.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.zzhoujay.markdown; - -import android.text.Html; -import android.text.Spannable; -import android.text.Spanned; -import android.text.style.CharacterStyle; -import android.widget.TextView; - -import com.zzhoujay.markdown.parser.StyleBuilderImpl; - -import java.io.IOException; - -/** - * Created by zhou on 16-6-25. - * Markdown解析器 - */ -public class MarkDown { - - public static Spanned fromMarkdown(String source, Html.ImageGetter imageGetter, TextView textView) { - MarkDownParser parser = new MarkDownParser(source, new StyleBuilderImpl(textView, imageGetter)); - try { - return parser.parse(); - } catch (IOException e) { - e.printStackTrace(); - } - return null; - } - - public static Spanned fromMarkdown(String source, TextView textView, int codeColor, int headerColor, Html.ImageGetter imageGetter) { - MarkDownParser parser = new MarkDownParser(source, new StyleBuilderImpl(textView, codeColor, headerColor, imageGetter)); - try { - return parser.parse(); - } catch (IOException e) { - e.printStackTrace(); - } - return null; - } -} diff --git a/app/src/main/java/com/zzhoujay/markdown/MarkDownParser.java b/app/src/main/java/com/zzhoujay/markdown/MarkDownParser.java deleted file mode 100755 index c60b1d4c..00000000 --- a/app/src/main/java/com/zzhoujay/markdown/MarkDownParser.java +++ /dev/null @@ -1,309 +0,0 @@ -package com.zzhoujay.markdown; - -import android.text.Spannable; -import android.text.SpannableString; -import android.text.SpannableStringBuilder; -import android.text.Spanned; - -import com.zzhoujay.markdown.parser.Line; -import com.zzhoujay.markdown.parser.LineQueue; -import com.zzhoujay.markdown.parser.QueueConsumer; -import com.zzhoujay.markdown.parser.StyleBuilder; -import com.zzhoujay.markdown.parser.Tag; -import com.zzhoujay.markdown.parser.TagHandler; -import com.zzhoujay.markdown.parser.TagHandlerImpl; -import com.zzhoujay.markdown.style.ScaleHeightSpan; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.StringReader; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/** - * Created by zhou on 16-6-25. - */ -class MarkDownParser { - - - private BufferedReader reader; - private TagHandler tagHandler; - - MarkDownParser(BufferedReader reader, StyleBuilder styleBuilder) { - this.reader = reader; - tagHandler = new TagHandlerImpl(styleBuilder); - } - - MarkDownParser(InputStream inputStream, StyleBuilder styleBuilder) { - this(new BufferedReader(new InputStreamReader(inputStream)), styleBuilder); - } - - MarkDownParser(String text, StyleBuilder styleBuilder) { - this(new BufferedReader(new StringReader(text)), styleBuilder); - } - - - public Spannable parse() throws IOException { - LineQueue queue = collect(); - return parse(queue); - } - - /** - * 收集 String -> LineQueue - * - * @return LineQueue - * @throws IOException - */ - private LineQueue collect() throws IOException { - String line; - Line root = null; - LineQueue queue = null; - while ((line = reader.readLine()) != null) { - if (!(tagHandler.imageId(line) || tagHandler.linkId(line))) { - Line l = new Line(line); - if (root == null) { - root = l; - queue = new LineQueue(root); - } else { - queue.append(l); - } - } - } - return queue; - } - - /** - * 解析LineQueue - * - * @param queue - * LineQueue - * @return Spanned - */ - private Spannable parse(final LineQueue queue) { - tagHandler.setQueueProvider(new QueueConsumer.QueueProvider() { - @Override - public LineQueue getQueue() { - return queue; - } - }); - removeCurrBlankLine(queue); - boolean notBlock;// 当前Line不是CodeBlock - do { - - notBlock = queue.prevLine() != null && (queue.prevLine().getType() == Line.LINE_TYPE_OL - || queue.prevLine().getType() == Line.LINE_TYPE_UL || queue.prevLine().getType() == Line.LINE_TYPE_CHECKED - || queue.prevLine().getType() == Line.LINE_TYPE_UN_CHECKED) - && (tagHandler.find(Tag.UL, queue.currLine()) || tagHandler.find(Tag.OL, queue.currLine()) - || tagHandler.find(Tag.TODO_CHECKED, queue.currLine()) || tagHandler.find(Tag.TODO_UNCHECKED, queue.currLine())); - if (!notBlock && (tagHandler.codeBlock1(queue.currLine()) || tagHandler.codeBlock2(queue.currLine()))) { - continue; - } - boolean isNewLine = tagHandler.find(Tag.NEW_LINE, queue.currLine()) || tagHandler.find(Tag.GAP, queue.currLine()) - || tagHandler.find(Tag.H, queue.currLine()); - if (isNewLine) { - if (queue.nextLine() != null) handleQuotaRelevant(queue, true); - removeNextBlankLine(queue); - } else { - while (queue.nextLine() != null && !removeNextBlankLine(queue)) { - if (tagHandler.find(Tag.CODE_BLOCK_1, queue.nextLine()) || tagHandler.find(Tag.CODE_BLOCK_2, queue.nextLine()) || - tagHandler.find(Tag.GAP, queue.nextLine()) || tagHandler.find(Tag.UL, queue.nextLine()) || - tagHandler.find(Tag.OL, queue.nextLine()) || tagHandler.find(Tag.H, queue.nextLine()) - || tagHandler.find(Tag.TODO_CHECKED, queue.nextLine()) || tagHandler.find(Tag.TODO_UNCHECKED, queue.nextLine())) { - break; - } - if (handleQuotaRelevant(queue, false)) break; - } - removeNextBlankLine(queue); - } - // 解析style - if (tagHandler.gap(queue.currLine()) || tagHandler.quota(queue.currLine()) || tagHandler.ol(queue.currLine()) || - tagHandler.ul(queue.currLine()) || tagHandler.h(queue.currLine())) { - continue; - } - queue.currLine().setStyle(SpannableStringBuilder.valueOf(queue.currLine().getSource())); - tagHandler.inline(queue.currLine()); - } while (queue.next()); - return merge(queue); - } - - /** - * 处理Quota嵌套相关问题 - * - * @param queue - * LineQueue - * @param onlyH - * 只处理Title相关的问题 - * @return true:已处理 - */ - private boolean handleQuotaRelevant(LineQueue queue, boolean onlyH) { - int nextQuotaCount = tagHandler.findCount(Tag.QUOTA, queue.nextLine(), 1); - int currQuotaCount = tagHandler.findCount(Tag.QUOTA, queue.currLine(), 1); - if (nextQuotaCount > 0 && nextQuotaCount > currQuotaCount) { - return true; - } else { - String source = queue.nextLine().getSource(); - if (nextQuotaCount > 0) { - source = source.replaceFirst("^\\s{0,3}(>\\s+){" + nextQuotaCount + "}", ""); - } - if (currQuotaCount == nextQuotaCount) { - if (findH1_2(queue, currQuotaCount, source)) return true; - if (findH2_2(queue, currQuotaCount, source)) return true; - } - if (onlyH) { - return false; - } - if (tagHandler.find(Tag.UL, source) || tagHandler.find(Tag.OL, source) - || tagHandler.find(Tag.TODO_CHECKED, source) - || tagHandler.find(Tag.TODO_UNCHECKED, source) - || tagHandler.find(Tag.H, source)) { - return true; - } else { - queue.currLine().setSource(queue.currLine().getSource() + ' ' + source); - queue.removeNextLine(); - } - } - return false; - } - - private boolean findH2_2(LineQueue queue, int currQuotaCount, String source) { - if (tagHandler.find(Tag.H2_2, source)) { - String currLineSource = queue.currLine().getSource(); - Matcher m = Pattern.compile("^\\s{0,3}(>\\s+?){" + currQuotaCount + "}(.*)").matcher(queue.currLine().getSource()); - String newCurrLineSource; - if (m.find()) { - int start = m.start(2); - int end = m.end(2); - newCurrLineSource = currLineSource.substring(0, start) + "## " + currLineSource.subSequence(start, end); - } else { - newCurrLineSource = "## " + currLineSource; - } - queue.currLine().setSource(newCurrLineSource); - queue.removeNextLine(); - return true; - } - return false; - } - - private boolean findH1_2(LineQueue queue, int currQuotaCount, String source) { - if (tagHandler.find(Tag.H1_2, source)) { - String currLineSource = queue.currLine().getSource(); - Matcher m = Pattern.compile("^\\s{0,3}(>\\s+?){" + currQuotaCount + "}(.*)").matcher(currLineSource); - String newCurrLineSource; - if (m.find()) { - int start = m.start(2); - int end = m.end(2); - newCurrLineSource = currLineSource.substring(0, start) + "# " + currLineSource.subSequence(start, end); - } else { - newCurrLineSource = "# " + currLineSource; - } - queue.currLine().setSource(newCurrLineSource); - queue.removeNextLine(); - return true; - } - return false; - } - - /** - * 合并LineQueue -> Spanned - * - * @param queue - * LineQueue - * @return Spanned - */ - private Spannable merge(LineQueue queue) { - queue.reset(); - SpannableStringBuilder builder = new SpannableStringBuilder(); - do { - Line curr = queue.currLine(); - Line next = queue.nextLine(); - builder.append(curr.getStyle()); - if (next == null) { - break; - } - builder.append('\n'); - switch (curr.getType()) { - case Line.LINE_TYPE_QUOTA: - if (next.getType() != Line.LINE_TYPE_QUOTA) { - builder.append('\n'); - } - break; - case Line.LINE_TYPE_UL: - if (next.getType() == Line.LINE_TYPE_UL) - builder.append(listMarginBottom()); - builder.append('\n'); - break; - case Line.LINE_TYPE_OL: - if (next.getType() == Line.LINE_TYPE_OL) { - builder.append(listMarginBottom()); - } - builder.append('\n'); - break; - case Line.LINE_TYPE_CHECKED: - if (next.getType() == Line.LINE_TYPE_OL) { - builder.append(listMarginBottom()); - } - builder.append('\n'); - break; - case Line.LINE_TYPE_UN_CHECKED: - if (next.getType() == Line.LINE_TYPE_OL) { - builder.append(listMarginBottom()); - } - builder.append('\n'); - break; - default: - builder.append('\n'); - } - } while (queue.next()); - return builder; - } - - /** - * 从下个Line开始移除空Line - * - * @param queue - * LineQueue - * @return 是否移除了 - */ - private boolean removeNextBlankLine(LineQueue queue) { - boolean flag = false; - while (queue.nextLine() != null) { - if (tagHandler.find(Tag.BLANK, queue.nextLine())) { - queue.removeNextLine(); - flag = true; - } else { - break; - } - } - return flag; - } - - /** - * 从当前行开始移除空Line - * - * @param queue - * LineQueue - * @return true:移除了Line - */ - private boolean removeCurrBlankLine(LineQueue queue) { - boolean flag = false; - while (queue.currLine() != null) { - if (tagHandler.find(Tag.BLANK, queue.currLine())) { - queue.removeCurrLine(); - flag = true; - } else { - break; - } - } - return flag; - } - - - private SpannableString listMarginBottom() { - SpannableString ss = new SpannableString(" "); - ss.setSpan(new ScaleHeightSpan(0.4f), 0, ss.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); - return ss; - } - -} diff --git a/app/src/main/java/com/zzhoujay/markdown/parser/Line.java b/app/src/main/java/com/zzhoujay/markdown/parser/Line.java deleted file mode 100755 index 87c32521..00000000 --- a/app/src/main/java/com/zzhoujay/markdown/parser/Line.java +++ /dev/null @@ -1,412 +0,0 @@ -package com.zzhoujay.markdown.parser; - -import android.text.SpannableStringBuilder; - -/** - * Created by zhou on 16-6-28. - * 代表每一行文本 - */ -public class Line { - - public static final int LINE_NORMAL = 0; // 普通文本 - public static final int LINE_TYPE_QUOTA = 1; // 引用 - public static final int LINE_TYPE_UL = 2; // 无序列表 - public static final int LINE_TYPE_OL = 3; // 有序列表 - public static final int LINE_TYPE_H1 = 4; // H1 - public static final int LINE_TYPE_H2 = 5; // H2 - public static final int LINE_TYPE_H3 = 6; // H3 - public static final int LINE_TYPE_H4 = 7; // H4 - public static final int LINE_TYPE_H5 = 8; // H5 - public static final int LINE_TYPE_H6 = 9; // H6 - public static final int LINE_TYPE_CODE_BLOCK_2 = 10; - public static final int LINE_TYPE_CODE_BLOCK_1 = 11; - public static final int LINE_TYPE_GAP = 12; - public static final int LINE_TYPE_CHECKED = 13; - public static final int LINE_TYPE_UN_CHECKED = 14; - public static final int HANDLE_BY_ROOT = 1; - - private Line prev; // 前一个节点 - private Line next; // 下一个节点 - private Line parent; // 父节点 - private Line child; // 子节点 - - private String source; // 源文本 - private CharSequence style; // 样式 - private int type; // 种类 - private int count; // 数量 - private int attr; // 属性 - private int handle; // 0 - private int data; - - - public Line(String source) { - this.source = source; - count = 1; - type = LINE_NORMAL; - } - - private Line(Line line) { - this.source = line.source; - this.count = line.count; - this.attr = line.attr; - if (line.style != null) { - this.style = new SpannableStringBuilder(line.style); - } - this.type = line.type; - } - - public void setSource(String source) { - this.source = source; - } - - public String getSource() { - return source; - } - - public void setStyle(CharSequence style) { - this.style = style; - } - - public CharSequence getStyle() { - return style; - } - - public void setType(int type) { - this.type = type; - } - - public int getType() { - return type; - } - - public void setCount(int count) { - this.count = count; - } - - public int getCount() { - return count; - } - - public int getHandle() { - return handle; - } - - public void setHandle(int handle) { - this.handle = handle; - } - - public int getData() { - return data; - } - - public void setData(int data) { - this.data = data; - } - - public void setAttr(int attr) { - this.attr = attr; - } - - public int getAttr() { - return attr; - } - - public Line get() { - return this; - } - - public Line nextLine() { - return next; - } - - public Line prevLine() { - return prev; - } - - public Line childLine() { - return child; - } - - public Line parentLine() { - return parent; - } - - /** - * 添加为下一个节点 - * - * @param line - * Line - * @return Line - */ - public Line addNext(Line line) { - if (line == null) { - next = null; - } else { - if (line.next != null) { - line.next.prev = null; - } - line.next = next; - if (next != null) { - next.prev = line; - } - if (line.prev != null) { - line.prev.next = null; - } - line.prev = this; - next = line; - if (child != null) { - child.addNext(line.child); - } - } - return line; - } - - /** - * 添加为上一个节点 - * - * @param line - * Line - * @return Line - */ - public Line addPrev(Line line) { - if (line == null) { - prev = null; - } else { - if (line.prev != null) { - line.prev.next = null; - } - line.prev = prev; - if (prev != null) { - prev.next = line; - } - if (line.next != null) { - line.next.prev = null; - } - line.next = this; - prev = line; - if (child != null) { - child.addPrev(line.child); - } - } - return line; - } - - public Line add(Line line) { - return addNext(line); - } - - /** - * 删除当前节点,包括其子节点包(会导致链表断开) - */ - private void delete() { - if (child != null) { - child.delete(); - } - if (prev != null) { - prev.next = null; - } - prev = null; - if (next != null) { - next.prev = null; - } - next = null; - } - - /** - * 移除当前节点,重新连上前后两个节点,包括其子节点(不会导致链表断开) - */ - private void reduce() { - if (child != null) { - child.reduce(); - } - if (prev != null) { - prev.next = next; - } - if (next != null) { - next.prev = prev; - } - next = null; - prev = null; - } - - /** - * 移除当前节点并且不会导致主链表断开 - */ - public void remove() { - if (parent == null) { - reduce(); - } else { - delete(); - } - } - - /** - * 移除下一个节点 - * - * @return this - */ - public Line removeNext() { - if (next != null) { - next.remove(); - } - return this; - } - - /** - * 移除上一行 - * - * @return this - */ - public Line removePrev() { - if (prev != null) { - prev.remove(); - } - return this; - } - - /** - * 添加子节点,并将子节点和前后节点的子节点建立连接 - * - * @param line - * child - */ - public void addChild(Line line) { - if (child != null) { - child.parent = null; - } - child = line; - if (line.parent != null) { - line.parent.child = null; - } - line.parent = this; - attachChildToNext(); - attachChildToPrev(); - } - - /** - * 将子节点和下一个节点之间建立连接 - */ - public void attachChildToNext() { - if (child != null && next != null) { - if (child.next != null) { - child.next.prev = null; - } - child.next = next.child; - if (next.child != null) { - if (next.child.prev != null) { - next.child.prev.next = null; - } - next.child.prev = child; - } - child.attachChildToNext(); - } - } - - /** - * 将子节点和上一个节点之间建立连接 - */ - public void attachChildToPrev() { - if (child != null && prev != null) { - if (child.prev != null) { - child.prev.next = null; - } - child.prev = prev.child; - if (prev.child != null) { - if (prev.child.next != null) { - prev.child.next.prev = null; - } - prev.child.next = child; - } - child.attachChildToPrev(); - } - } - - /** - * 将自身作为子节点添加到某个节点 - * - * @param line - * parent - */ - public void attachToParent(Line line) { - line.addChild(this); - } - - /** - * 从父节点上解绑 - */ - public void unAttachFromParent() { - if (parent != null) { - delete(); - parent.child = null; - } - parent = null; - } - - /** - * 创建一个子节点 - * - * @param src - * 子节点的source - * @return 子节点 - */ - public Line createChild(String src) { - Line c = new Line(src); - addChild(c); - return c; - } - - /** - * 将自身及父节点copy为下一个节点 - * - * @return copy产生的对象 - */ - public Line copyToNext() { - Line p = null; - if (parent != null) { - p = parent.copyToNext(); - } - Line line = new Line(this); - if (p == null) { - line.next = next; - if (next != null) { - next.prev = line; - } - line.prev = this; - next = line; - } else { - p.addChild(line); - } - return line; - } - - /** - * 将自身及父节点copy为上一个节点 - * - * @return copy产生的对象 - */ - public Line copyToPrev() { - Line p = null; - if (parent != null) { - p = parent.copyToPrev(); - } - Line line = new Line(this); - if (p == null) { - line.prev = prev; - if (prev != null) { - prev.next = line; - } - line.next = this; - prev = this; - } else { - p.addChild(line); - } - return line; - } - - - @Override - public String toString() { - return source; - } - -} diff --git a/app/src/main/java/com/zzhoujay/markdown/parser/LineQueue.java b/app/src/main/java/com/zzhoujay/markdown/parser/LineQueue.java deleted file mode 100755 index 3fcdc037..00000000 --- a/app/src/main/java/com/zzhoujay/markdown/parser/LineQueue.java +++ /dev/null @@ -1,134 +0,0 @@ -package com.zzhoujay.markdown.parser; - -/** - * Created by zhou on 16-7-2. - */ -public class LineQueue { - - private Line root; // 根节点 - private Line curr; // 当前节点 - private Line last; // 尾节点 - - public LineQueue(Line root) { - this.root = root; - curr = root; - last = root; - while (last.nextLine() != null) { - last = last.nextLine(); - } - } - - private LineQueue(LineQueue queue, Line curr) { - this.root = queue.root; - this.last = queue.last; - this.curr = curr; - } - - public Line nextLine() { - return curr.nextLine(); - } - - public Line prevLine() { - return curr.prevLine(); - } - - public Line currLine() { - return curr; - } - - public boolean next() { - if (curr.nextLine() == null) { - return false; - } - curr = curr.nextLine(); - return true; - } - - public boolean prev() { - if (curr.prevLine() == null) { - return false; - } - curr = currLine().prevLine(); - return true; - } - - public boolean end() { - return curr.nextLine() == null; - } - - public boolean start() { - return curr == root; - } - - public void append(Line line) { - last.add(line); - last = line; - } - - public void insert(Line line) { - if (curr == last) { - append(line); - } else { - curr.addNext(line); - } - } - - public Line removeCurrLine() { - Line tmp; - if (curr == last) { - tmp = last.prevLine(); - } else { - tmp = curr.nextLine(); - if (curr == root) { - root = tmp; - } - } - curr.remove(); - Line r = curr; - curr = tmp; - return r; - } - - public void removeNextLine() { - curr.removeNext(); - } - - public void removePrevLine() { - if (root == curr.prevLine()) { - root = curr; - } - curr.removePrev(); - } - - public LineQueue copy() { - return new LineQueue(this, curr); - } - - public LineQueue copyNext() { - if (end()) { - return null; - } - return new LineQueue(this, curr.nextLine()); - } - - - public void reset() { - curr = root; - } - - @Override - public String toString() { - Line t = root; - StringBuilder sb = new StringBuilder(); - int len = 0; - while (t != null) { - sb.append(t.toString()).append(","); - t = t.nextLine(); - len++; - } - return "{" + sb.toString() + "}"; - - } - - -} diff --git a/app/src/main/java/com/zzhoujay/markdown/parser/QueueConsumer.java b/app/src/main/java/com/zzhoujay/markdown/parser/QueueConsumer.java deleted file mode 100755 index f4d208ab..00000000 --- a/app/src/main/java/com/zzhoujay/markdown/parser/QueueConsumer.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.zzhoujay.markdown.parser; - -/** - * Created by zhou on 16-7-22. - * LineQueue的消费者 - */ -public interface QueueConsumer { - - - void setQueueProvider(QueueProvider provider); - - /** - * LineQueue提供器 - */ - interface QueueProvider { - LineQueue getQueue(); - } -} diff --git a/app/src/main/java/com/zzhoujay/markdown/parser/StyleBuilder.java b/app/src/main/java/com/zzhoujay/markdown/parser/StyleBuilder.java deleted file mode 100755 index f2155014..00000000 --- a/app/src/main/java/com/zzhoujay/markdown/parser/StyleBuilder.java +++ /dev/null @@ -1,59 +0,0 @@ -package com.zzhoujay.markdown.parser; - -import android.text.SpannableStringBuilder; - -/** - * Created by zhou on 16-6-28. - * markdown各种样式的构建器 - */ -public interface StyleBuilder { - - SpannableStringBuilder em(CharSequence charSequence); - - SpannableStringBuilder italic(CharSequence charSequence); - - SpannableStringBuilder emItalic(CharSequence charSequence); - - SpannableStringBuilder delete(CharSequence charSequence); - - SpannableStringBuilder email(CharSequence charSequence); - - SpannableStringBuilder link(CharSequence title, String link, String hint); - - SpannableStringBuilder image(CharSequence title, String url, String hint); - - SpannableStringBuilder code(CharSequence charSequence); - - SpannableStringBuilder h1(CharSequence charSequence); - - SpannableStringBuilder h2(CharSequence charSequence); - - SpannableStringBuilder h3(CharSequence charSequence); - - SpannableStringBuilder h4(CharSequence charSequence); - - SpannableStringBuilder h5(CharSequence charSequence); - - SpannableStringBuilder h6(CharSequence charSequence); - - SpannableStringBuilder quota(CharSequence charSequence); - - SpannableStringBuilder ul(CharSequence charSequence, int level); - - SpannableStringBuilder ol(CharSequence charSequence, int level, int index); - - SpannableStringBuilder ul2(CharSequence charSequence, int quotaLevel, int bulletLevel); - - SpannableStringBuilder ol2(CharSequence charSequence, int quotaLevel, int bulletLevel, int index); - - SpannableStringBuilder codeBlock(CharSequence... charSequence); - - SpannableStringBuilder codeBlock(String code); - - SpannableStringBuilder gap(); - - SpannableStringBuilder checked(CharSequence charSequence); - - SpannableStringBuilder unChecked(CharSequence charSequence); - -} diff --git a/app/src/main/java/com/zzhoujay/markdown/parser/StyleBuilderImpl.java b/app/src/main/java/com/zzhoujay/markdown/parser/StyleBuilderImpl.java deleted file mode 100755 index 9f14058f..00000000 --- a/app/src/main/java/com/zzhoujay/markdown/parser/StyleBuilderImpl.java +++ /dev/null @@ -1,282 +0,0 @@ -package com.zzhoujay.markdown.parser; - -import android.graphics.Color; -import android.graphics.Typeface; -import android.graphics.drawable.ColorDrawable; -import android.graphics.drawable.Drawable; -import android.text.Html; -import android.text.SpannableStringBuilder; -import android.text.Spanned; -import android.text.style.BackgroundColorSpan; -import android.text.style.BulletSpan; -import android.text.style.ForegroundColorSpan; -import android.text.style.ImageSpan; -import android.text.style.QuoteSpan; -import android.text.style.StrikethroughSpan; -import android.text.style.TypefaceSpan; -import android.util.Log; -import android.widget.TextView; - -import com.zzhoujay.markdown.style.CodeBlockSpan; -import com.zzhoujay.markdown.style.EmailSpan; -import com.zzhoujay.markdown.style.FontSpan; -import com.zzhoujay.markdown.style.LinkSpan; -import com.zzhoujay.markdown.style.MarkDownBulletSpan; -import com.zzhoujay.markdown.style.MarkDownQuoteSpan; -import com.zzhoujay.markdown.style.QuotaBulletSpan; -import com.zzhoujay.markdown.style.UnderLineSpan; - -import java.lang.ref.WeakReference; - -/** - * Created by zhou on 16-6-28. - * StyleBuilderImpl - */ -public class StyleBuilderImpl implements StyleBuilder { - - private int h1_color = Color.parseColor("#333333"); - private static final int h6_color = Color.parseColor("#777777"); - private static final int quota_color = Color.parseColor("#DDDDDD"); - private int code_color = Color.parseColor("#F0F0F0"); - private static final int link_color = Color.parseColor("#4078C0"); - private static final int h_under_line_color = Color.parseColor("#eeeeee"); - - private static final float scale_h1 = 2.25f; - private static final float scale_h2 = 1.75f; - private static final float scale_h3 = 1.5f; - private static final float scale_h4 = 1.25f; - private static final float scale_h5 = 1, scale_h6 = 1; - private static final float scale_normal = 1; - - private WeakReference textViewWeakReference; - private Html.ImageGetter imageGetter; - - public StyleBuilderImpl(TextView textView, int codeColor, int h1_color, Html.ImageGetter imageGetter) { - this.textViewWeakReference = new WeakReference<>(textView); - this.code_color = codeColor; - this.h1_color = h1_color; - this.imageGetter = imageGetter; - } - - public StyleBuilderImpl(TextView textView, Html.ImageGetter imageGetter) { - this.textViewWeakReference = new WeakReference<>(textView); - this.imageGetter = imageGetter; - } - - @Override - public SpannableStringBuilder em(CharSequence charSequence) { - SpannableStringBuilder builder = SpannableStringBuilder.valueOf(charSequence); - FontSpan fontSpan = new FontSpan(scale_normal, Typeface.BOLD, h1_color); - builder.setSpan(fontSpan, 0, charSequence.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); - return builder; - } - - @Override - public SpannableStringBuilder italic(CharSequence charSequence) { - SpannableStringBuilder builder = SpannableStringBuilder.valueOf(charSequence); - FontSpan fontSpan = new FontSpan(scale_normal, Typeface.ITALIC, h1_color); - builder.setSpan(fontSpan, 0, charSequence.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); - return builder; - } - - @Override - public SpannableStringBuilder emItalic(CharSequence charSequence) { - SpannableStringBuilder builder = SpannableStringBuilder.valueOf(charSequence); - FontSpan fontSpan = new FontSpan(scale_normal, Typeface.BOLD_ITALIC, h1_color); - builder.setSpan(fontSpan, 0, charSequence.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); - return builder; - } - - @Override - public SpannableStringBuilder delete(CharSequence charSequence) { - SpannableStringBuilder builder = SpannableStringBuilder.valueOf(charSequence); - StrikethroughSpan span = new StrikethroughSpan(); - ForegroundColorSpan colorSpan = new ForegroundColorSpan(h1_color); - builder.setSpan(colorSpan, 0, charSequence.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); - builder.setSpan(span, 0, charSequence.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); - return builder; - } - - @Override - public SpannableStringBuilder email(CharSequence charSequence) { - SpannableStringBuilder builder = SpannableStringBuilder.valueOf(charSequence); - EmailSpan emailSpan = new EmailSpan(charSequence.toString(), link_color); - builder.setSpan(emailSpan, 0, charSequence.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); - return builder; - } - - @Override - public SpannableStringBuilder code(CharSequence charSequence) { - SpannableStringBuilder builder = SpannableStringBuilder.valueOf(charSequence); - builder.setSpan(new BackgroundColorSpan(code_color), 0, charSequence.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); - builder.setSpan(new TypefaceSpan("monospace"), 0, charSequence.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); - return builder; - } - - @Override - public SpannableStringBuilder h1(CharSequence charSequence) { - return hWithUnderLine(charSequence, scale_h1); - } - - @Override - public SpannableStringBuilder h2(CharSequence charSequence) { - return hWithUnderLine(charSequence, scale_h2); - } - - @Override - public SpannableStringBuilder h3(CharSequence charSequence) { - return h(charSequence, scale_h3, h1_color); - } - - @Override - public SpannableStringBuilder h4(CharSequence charSequence) { - return h(charSequence, scale_h4, h1_color); - } - - @Override - public SpannableStringBuilder h5(CharSequence charSequence) { - return h(charSequence, scale_h5, h1_color); - } - - @Override - public SpannableStringBuilder h6(CharSequence charSequence) { - return h(charSequence, scale_h6, h6_color); - } - - @Override - public SpannableStringBuilder quota(CharSequence charSequence) { - SpannableStringBuilder spannableStringBuilder = SpannableStringBuilder.valueOf(charSequence); - QuoteSpan span = new MarkDownQuoteSpan(quota_color); - spannableStringBuilder.setSpan(span, 0, spannableStringBuilder.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); - return spannableStringBuilder; - } - - @Override - public SpannableStringBuilder ul(CharSequence charSequence, int level) { - SpannableStringBuilder spannableStringBuilder = SpannableStringBuilder.valueOf(charSequence); - BulletSpan bulletSpan = new MarkDownBulletSpan(level, h1_color, 0); - spannableStringBuilder.setSpan(bulletSpan, 0, spannableStringBuilder.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); - return spannableStringBuilder; - } - - @Override - public SpannableStringBuilder ol(CharSequence charSequence, int level, int index) { - SpannableStringBuilder spannableStringBuilder = SpannableStringBuilder.valueOf(charSequence); - BulletSpan bulletSpan = new MarkDownBulletSpan(level, h1_color, index, textViewWeakReference.get()); - spannableStringBuilder.setSpan(bulletSpan, 0, spannableStringBuilder.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); - return spannableStringBuilder; - } - - @Override - public SpannableStringBuilder ul2(CharSequence charSequence, int quotaLevel, int bulletLevel) { - SpannableStringBuilder spannableStringBuilder = SpannableStringBuilder.valueOf(charSequence); - QuotaBulletSpan bulletSpan = new QuotaBulletSpan(quotaLevel, bulletLevel, quota_color, h1_color, 0, textViewWeakReference.get()); - spannableStringBuilder.setSpan(bulletSpan, 0, spannableStringBuilder.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); - return spannableStringBuilder; - } - - @Override - public SpannableStringBuilder ol2(CharSequence charSequence, int quotaLevel, int bulletLevel, int index) { - SpannableStringBuilder spannableStringBuilder = SpannableStringBuilder.valueOf(charSequence); - QuotaBulletSpan bulletSpan = new QuotaBulletSpan(quotaLevel, bulletLevel, quota_color, h1_color, index, textViewWeakReference.get()); - spannableStringBuilder.setSpan(bulletSpan, 0, spannableStringBuilder.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); - return spannableStringBuilder; - } - - @Override - public SpannableStringBuilder codeBlock(CharSequence... charSequence) { - SpannableStringBuilder builder = SpannableStringBuilder.valueOf("$"); - CodeBlockSpan codeBlockSpan = new CodeBlockSpan(getTextViewRealWidth(), code_color, charSequence); - builder.setSpan(codeBlockSpan, 0, builder.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); - builder.setSpan(new TypefaceSpan("monospace"), 0, builder.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); - return builder; - } - - @Override - public SpannableStringBuilder codeBlock(String code) { - return codeBlock((CharSequence[]) code.split("\n")); - } - - @Override - public SpannableStringBuilder link(CharSequence title, String link, String hint) { - SpannableStringBuilder builder = SpannableStringBuilder.valueOf(title); - LinkSpan linkSpan = new LinkSpan(link, link_color); - builder.setSpan(linkSpan, 0, title.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); - return builder; - } - - @Override - public SpannableStringBuilder image(CharSequence title, String url, String hint) { - if (title == null || title.length() == 0) { - title = "$"; - } - SpannableStringBuilder builder = SpannableStringBuilder.valueOf(title); - Drawable drawable = null; - if (imageGetter != null) { - drawable = imageGetter.getDrawable(url); - } - if (drawable == null) { - drawable = new ColorDrawable(Color.TRANSPARENT); -// builder.delete(0, builder.length()); -// return builder; - } - ImageSpan imageSpan = new ImageSpan(drawable, url); - builder.setSpan(imageSpan, 0, builder.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); - return builder; - } - - @SuppressWarnings("WeakerAccess") - protected SpannableStringBuilder h(CharSequence charSequence, float s, int color) { - SpannableStringBuilder spannableStringBuilder = SpannableStringBuilder.valueOf(charSequence); - FontSpan fontSpan = new FontSpan(s, Typeface.BOLD, color); - spannableStringBuilder.setSpan(fontSpan, 0, spannableStringBuilder.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); - return spannableStringBuilder; - } - - private SpannableStringBuilder hWithUnderLine(CharSequence charSequence, float s) { - SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder(charSequence); - int start = 0; - FontSpan fontSpan = new FontSpan(s, Typeface.BOLD, h1_color); - spannableStringBuilder.setSpan(fontSpan, 0, spannableStringBuilder.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); - Drawable underLine = new ColorDrawable(h_under_line_color); - UnderLineSpan underLineSpan = new UnderLineSpan(underLine, getTextViewRealWidth(), 5); - spannableStringBuilder.append('\n'); - start += charSequence.length() + 1; - spannableStringBuilder.append("$"); - spannableStringBuilder.setSpan(underLineSpan, start, spannableStringBuilder.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); - return spannableStringBuilder; - } - - private int getTextViewRealWidth() { - TextView textView = textViewWeakReference.get(); - if (textView != null) { - return textView.getWidth() - textView.getPaddingRight() - textView.getPaddingLeft(); - } - return 0; - } - - @Override - public SpannableStringBuilder gap() { - SpannableStringBuilder builder = new SpannableStringBuilder("$"); - Drawable underLine = new ColorDrawable(h_under_line_color); - UnderLineSpan underLineSpan = new UnderLineSpan(underLine, getTextViewRealWidth(), 10); - builder.setSpan(underLineSpan, 0, builder.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); - return builder; - } - - @Override public SpannableStringBuilder checked(CharSequence charSequence) { - Log.e("checked()", "" + charSequence); - SpannableStringBuilder builder = new SpannableStringBuilder(); - return builder.append("☑") - .append("\t") - .append(charSequence); - } - - @Override public SpannableStringBuilder unChecked(CharSequence charSequence) { - Log.e("unChecked()", "" + charSequence); - SpannableStringBuilder builder = new SpannableStringBuilder(); - return builder.append("☐") - .append("\t") - .append(charSequence); - } -} diff --git a/app/src/main/java/com/zzhoujay/markdown/parser/Tag.java b/app/src/main/java/com/zzhoujay/markdown/parser/Tag.java deleted file mode 100755 index ce0da9e5..00000000 --- a/app/src/main/java/com/zzhoujay/markdown/parser/Tag.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.zzhoujay.markdown.parser; - -/** - * Created by zhou on 16-7-10. - */ -public class Tag { - - public static final int NORMAL = 0; - public static final int CODE_BLOCK_1 = 1; - public static final int CODE_BLOCK_2 = 2; - public static final int H1 = 3; - public static final int H2 = 4; - public static final int H3 = 24; - public static final int H4 = 5; - public static final int H5 = 6; - public static final int H6 = 7; - public static final int QUOTA = 8; - public static final int UL = 9; - public static final int OL = 10; - public static final int EM = 11; - public static final int ITALIC = 12; - public static final int EM_ITALIC = 13; - public static final int EMAIL = 14; - public static final int AUTO_LINK = 15; - public static final int DELETE = 16; - public static final int LINK = 17; - public static final int LINK2 = 18; - public static final int LINK_ID = 19; - public static final int IMAGE = 20; - public static final int IMAGE2 = 21; - public static final int IMAGE_ID = 22; - public static final int H = 23; - public static final int BLANK = 25; - public static final int NEW_LINE = 26; - public static final int GAP = 27; - public static final int H1_2 = 28; - public static final int H2_2 = 29; - public static final int CODE = 30; - public static final int TODO_CHECKED = 31; - public static final int TODO_UNCHECKED = 32; -} diff --git a/app/src/main/java/com/zzhoujay/markdown/parser/TagFinder.java b/app/src/main/java/com/zzhoujay/markdown/parser/TagFinder.java deleted file mode 100755 index abb0a154..00000000 --- a/app/src/main/java/com/zzhoujay/markdown/parser/TagFinder.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.zzhoujay.markdown.parser; - -/** - * Created by zhou on 16-7-10. - * TagFinder - */ -public interface TagFinder { - - /** - * 检查对应tag是否存在 - * - * @param tag Tag Id - * @param line line - * @return true:存在,false不存在 - */ - boolean find(int tag, Line line); - - /** - * 检查对应tag是否存在 - * - * @param tag Tag Id - * @param line line - * @return true:存在,false不存在 - */ - boolean find(int tag, String line); - - /** - * 检查对应tag的个数 - * - * @param tag tag id - * @param line line - * @param group group - * @return 对应tag的次数 - */ - int findCount(int tag, Line line, int group); - - /** - * 检查对应tag的个数 - * - * @param tag tag id - * @param line line - * @param group group - * @return 对应tag的次数 - */ - int findCount(int tag, String line, int group); - -} diff --git a/app/src/main/java/com/zzhoujay/markdown/parser/TagGetter.java b/app/src/main/java/com/zzhoujay/markdown/parser/TagGetter.java deleted file mode 100755 index 9c65b6e2..00000000 --- a/app/src/main/java/com/zzhoujay/markdown/parser/TagGetter.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.zzhoujay.markdown.parser; - -/** - * 获取Tag内容 - */ -public interface TagGetter { - - /** - * 获取Line特定Tag的内容 - * - * @param tag tag - * @param line Line - * @param group group - * @return content - */ - CharSequence get(int tag, Line line, int group); - - /** - * 获取line特定Tag的内容 - * - * @param tag tag - * @param line line - * @param group group - * @return content - */ - CharSequence get(int tag, CharSequence line, int group); -} diff --git a/app/src/main/java/com/zzhoujay/markdown/parser/TagHandler.java b/app/src/main/java/com/zzhoujay/markdown/parser/TagHandler.java deleted file mode 100755 index 6faf0737..00000000 --- a/app/src/main/java/com/zzhoujay/markdown/parser/TagHandler.java +++ /dev/null @@ -1,67 +0,0 @@ -package com.zzhoujay.markdown.parser; - -/** - * Created by zhou on 16-7-10. - * TagHandler - */ -public interface TagHandler extends TagFinder, QueueConsumer, TagGetter { - - boolean h(Line line); - - boolean h1(Line line); - - boolean h2(Line line); - - boolean h3(Line line); - - boolean h4(Line line); - - boolean h5(Line line); - - boolean h6(Line line); - - boolean quota(Line line); - - boolean ul(Line line); - - boolean ol(Line line); - - boolean todoChecked(Line line); - - boolean todoUnChecked(Line line); - - boolean gap(Line line); - - boolean em(Line line); - - boolean italic(Line line); - - boolean emItalic(Line line); - - boolean code(Line line); - - boolean email(Line line); - - boolean delete(Line line); - - boolean autoLink(Line line); - - boolean link(Line line); - - boolean link2(Line line); - - boolean linkId(String line); - - boolean image(Line line); - - boolean image2(Line line); - - boolean imageId(String line); - - boolean inline(Line line); - - boolean codeBlock1(Line line); - - boolean codeBlock2(Line line); - -} diff --git a/app/src/main/java/com/zzhoujay/markdown/parser/TagHandlerImpl.java b/app/src/main/java/com/zzhoujay/markdown/parser/TagHandlerImpl.java deleted file mode 100755 index 632ff256..00000000 --- a/app/src/main/java/com/zzhoujay/markdown/parser/TagHandlerImpl.java +++ /dev/null @@ -1,952 +0,0 @@ -package com.zzhoujay.markdown.parser; - -import android.text.SpannableStringBuilder; -import android.util.Pair; -import android.util.SparseArray; - -import com.zzhoujay.markdown.style.CodeSpan; - -import java.util.HashMap; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/** - * Created by zhou on 16-7-10. - * TagHandlerImpl - */ -public class TagHandlerImpl implements TagHandler { - - private static final Matcher matcherH1_2 = Pattern.compile("^\\s*=+\\s*$").matcher(""); - private static final Matcher matcherH2_2 = Pattern.compile("^\\s*-+\\s*$").matcher(""); - - private static final Matcher matcherH = Pattern.compile("^\\s*#{1,6}\\s*([^#]*)(\\s*#)?").matcher(""); - private static final Matcher matcherH1 = Pattern.compile("^\\s*#\\s*([^#]*)(\\s*#)?").matcher(""); - private static final Matcher matcherH2 = Pattern.compile("^\\s*#{2}\\s*([^#]*)(\\s*#)?").matcher(""); - private static final Matcher matcherH3 = Pattern.compile("^\\s*#{3}\\s*([^#]*)(\\s*#)?").matcher(""); - private static final Matcher matcherH4 = Pattern.compile("^\\s*#{4}\\s*([^#]*)(\\s*#)?").matcher(""); - private static final Matcher matcherH5 = Pattern.compile("^\\s*#{5}\\s*([^#]*)(\\s*#)?").matcher(""); - private static final Matcher matcherH6 = Pattern.compile("^\\s*#{6}\\s*([^#]*)(\\s*#)?").matcher(""); - - private static final Matcher matcherQuota = Pattern.compile("^\\s{0,3}>\\s(.*)").matcher(""); - private static final Matcher matcherUl = Pattern.compile("^\\s*[*+-]\\s+(.*)").matcher(""); - private static final Matcher matcherOl = Pattern.compile("^\\s*\\d+\\.\\s+(.*)").matcher(""); - private static final Matcher matcherUnChecked = Pattern.compile("-\\s\\[ ]+(.*)").matcher(""); - private static final Matcher matcherChecked = Pattern.compile("-\\s\\[x]+(.*)").matcher(""); - private static final Matcher matcherItalic = Pattern.compile("[^*_]*(([*_])([^*_].*?)\\2)").matcher(""); - private static final Matcher matcherEm = Pattern.compile("[^*_]*(([*_])\\2([^*_].*?)\\2\\2)").matcher(""); - private static final Matcher matcherEmItalic = Pattern.compile("[^*_]*(([*_])\\2\\2([^*_].*?)\\2\\2\\2)").matcher(""); - private static final Matcher matcherDelete = Pattern.compile("[^~]*((~{2,4})([^~].*?)\\2)").matcher(""); - private static final Matcher matcherCode = Pattern.compile("[^`]*((`+)([^`].*?)\\2)").matcher(""); - - private static final Matcher matcherLink = Pattern.compile(".*?(\\[\\s*(.*?)\\s*]\\(\\s*(\\S*?)(\\s+(['\"])(.*?)\\5)?\\s*?\\))").matcher(""); - private static final Matcher matcherImage = Pattern.compile(".*?(!\\[\\s*(.*?)\\s*]\\(\\s*(\\S*?)(\\s+(['\"])(.*?)\\5)?\\s*?\\))").matcher(""); - private static final Matcher matcherLink2 = Pattern.compile(".*?(\\[\\s*(.*?)\\s*]\\s*\\[\\s*(.*?)\\s*])").matcher(""); - private static final Matcher matcherLinkId = Pattern.compile("^\\s*\\[\\s*(.*?)\\s*]:\\s*(\\S+?)(\\s+(['\"])(.*?)\\4)?\\s*$").matcher(""); - private static final Matcher matcherImage2 = Pattern.compile(".*?(!\\[\\s*(.*?)\\s*]\\s*\\[\\s*(.*?)\\s*])").matcher(""); - private static final Matcher matcherImageId = Pattern.compile("^\\s*!\\[\\s*(.*?)\\s*]:\\s*(\\S+?)(\\s+(['\"])(.*?)\\4)?\\s*$").matcher(""); - - private static final Matcher matcherEmail = Pattern.compile(".*?(<(\\S+@\\S+\\.\\S+)>).*?").matcher(""); - private static final Matcher matcherAutoLink = Pattern.compile("((https|http|ftp|rtsp|mms)?://)[^\\s]+").matcher(""); - - private static final Matcher matcherEndSpace = Pattern.compile("(.*?) {2} *$").matcher(""); - private static final Matcher matcherInlineSpace = Pattern.compile("\\S*(\\s+)\\S+").matcher(""); - - private static final Matcher matcherCodeBlock = Pattern.compile("^( {4}|\\t)(.*)").matcher(""); - private static final Matcher matcherCodeBlock2 = Pattern.compile("^\\s*```").matcher(""); - - private static final Matcher matcherBlankLine = Pattern.compile("^\\s*$").matcher(""); - - private static final Matcher matcherGap = Pattern.compile("^\\s*([-*]\\s*){3,}$").matcher(""); - - private static final SparseArray matchers = new SparseArray<>();// matcher缓冲区 - - static { - matchers.put(Tag.CODE_BLOCK_1, matcherCodeBlock); - matchers.put(Tag.CODE_BLOCK_2, matcherCodeBlock2); - matchers.put(Tag.H1, matcherH1); - matchers.put(Tag.H2, matcherH2); - matchers.put(Tag.H3, matcherH3); - matchers.put(Tag.H4, matcherH4); - matchers.put(Tag.H5, matcherH5); - matchers.put(Tag.H6, matcherH6); - matchers.put(Tag.H, matcherH); - matchers.put(Tag.TODO_CHECKED, matcherChecked); - matchers.put(Tag.TODO_UNCHECKED, matcherUnChecked); - matchers.put(Tag.QUOTA, matcherQuota); - matchers.put(Tag.UL, matcherUl); - matchers.put(Tag.OL, matcherOl); - matchers.put(Tag.EM, matcherEm); - matchers.put(Tag.ITALIC, matcherItalic); - matchers.put(Tag.EM_ITALIC, matcherEmItalic); - matchers.put(Tag.EMAIL, matcherEmail); - matchers.put(Tag.AUTO_LINK, matcherAutoLink); - matchers.put(Tag.DELETE, matcherDelete); - matchers.put(Tag.LINK, matcherLink); - matchers.put(Tag.LINK2, matcherLink2); - matchers.put(Tag.LINK_ID, matcherLinkId); - matchers.put(Tag.IMAGE, matcherImage); - matchers.put(Tag.IMAGE2, matcherImage2); - matchers.put(Tag.IMAGE_ID, matcherImageId); - matchers.put(Tag.BLANK, matcherBlankLine); - matchers.put(Tag.NEW_LINE, matcherEndSpace); - matchers.put(Tag.GAP, matcherGap); - matchers.put(Tag.H1_2, matcherH1_2); - matchers.put(Tag.H2_2, matcherH2_2); - matchers.put(Tag.CODE, matcherCode); - } - - private StyleBuilder styleBuilder; - private QueueProvider queueProvider; - private HashMap> idLinkLinks; - private HashMap> idImageUrl; - - - public TagHandlerImpl(StyleBuilder styleBuilder) { - this.styleBuilder = styleBuilder; - idImageUrl = new HashMap<>(); - idLinkLinks = new HashMap<>(); - } - - @Override - public boolean h(Line line) { - return h6(line) || h5(line) || h4(line) || h3(line) || h2(line) || h1(line); - } - - @Override - public boolean h1(Line line) { - Matcher matcher = obtain(Tag.H1, line.getSource()); - if (matcher != null && matcher.find()) { - line.setType(Line.LINE_TYPE_H1); - line.setStyle(SpannableStringBuilder.valueOf(matcher.group(1))); - inline(line); - line.setStyle(styleBuilder.h1(line.getStyle())); - return true; - } - return false; - } - - @Override - public boolean h2(Line line) { - Matcher matcher = obtain(Tag.H2, line.getSource()); - if (matcher.find()) { - line.setType(Line.LINE_TYPE_H2); - line.setStyle(SpannableStringBuilder.valueOf(matcher.group(1))); - inline(line); - line.setStyle(styleBuilder.h2(line.getStyle())); - return true; - } - return false; - } - - @Override - public boolean h3(Line line) { - Matcher matcher = obtain(Tag.H3, line.getSource()); - if (matcher.find()) { - line.setType(Line.LINE_TYPE_H3); - line.setStyle(SpannableStringBuilder.valueOf(matcher.group(1))); - inline(line); - line.setStyle(styleBuilder.h3(line.getStyle())); - - return true; - } - return false; - } - - @Override - public boolean h4(Line line) { - Matcher matcher = obtain(Tag.H4, line.getSource()); - if (matcher.find()) { - line.setType(Line.LINE_TYPE_H4); - line.setStyle(SpannableStringBuilder.valueOf(matcher.group(1))); - inline(line); - line.setStyle(styleBuilder.h4(line.getStyle())); - - return true; - } - return false; - } - - @Override - public boolean h5(Line line) { - Matcher matcher = obtain(Tag.H5, line.getSource()); - if (matcher.find()) { - line.setType(Line.LINE_TYPE_H5); - line.setStyle(SpannableStringBuilder.valueOf(matcher.group(1))); - inline(line); - line.setStyle(styleBuilder.h5(line.getStyle())); - - return true; - } - return false; - } - - @Override - public boolean h6(Line line) { - Matcher matcher = obtain(Tag.H6, line.getSource()); - if (matcher.find()) { - line.setType(Line.LINE_TYPE_H6); - line.setStyle(SpannableStringBuilder.valueOf(matcher.group(1))); - inline(line); - line.setStyle(styleBuilder.h6(line.getStyle())); - return true; - } - return false; - } - - @Override - public boolean quota(Line line) { - LineQueue queue = queueProvider.getQueue(); - line = line.get(); - - Matcher matcher = obtain(Tag.QUOTA, line.getSource()); - if (matcher.find()) { - line.setType(Line.LINE_TYPE_QUOTA); - Line child = line.createChild(matcher.group(1)); - line.attachChildToNext(); - line.attachChildToPrev(); - - Line prev = queue.prevLine(); - if (line.parentLine() == null && prev != null && prev.getType() == Line.LINE_TYPE_QUOTA) { - SpannableStringBuilder style = new SpannableStringBuilder(" "); - styleBuilder.quota(style); - while (prev.childLine() != null && prev.childLine().getType() == Line.LINE_TYPE_QUOTA) { - prev = prev.childLine(); - styleBuilder.quota(style); - } - prev.copyToNext(); - queue.prevLine().setStyle(style); - } - if (quota(child) || ul(child) || ol(child) || h(child)) { - if (child.getHandle() == Line.HANDLE_BY_ROOT) { - if (line.parentLine() == null) { - if (child.getData() == Line.LINE_TYPE_UL) { - line.setStyle(styleBuilder.ul2(child.getStyle(), findCount(Tag.QUOTA, line, 1) - 1, child.getAttr())); - } else { - line.setStyle(styleBuilder.ol2(child.getStyle(), findCount(Tag.QUOTA, line, 1) - 1, child.getAttr(), child.getCount())); - } - } else { - line.setData(child.getData()); - line.setStyle(child.getStyle()); - line.setAttr(child.getAttr()); - line.setCount(child.getCount()); - line.setHandle(Line.HANDLE_BY_ROOT); - } - return true; - } - } else { - child.setStyle(SpannableStringBuilder.valueOf(child.getSource())); - inline(child); - } - - line.setStyle(styleBuilder.quota(child.getStyle())); - return true; - } - return false; - } - - @Override - public boolean ul(Line line) { - return ul(line, 0); - } - - private boolean ul(Line line, int level) { - if (line.getSource() != null && (line.getSource().startsWith("- [ ]") || line.getSource().startsWith("- [x]"))) { - if (line.getSource().startsWith("- [x]")) { - return todoChecked(line); - } else { - return todoUnChecked(line); - } - } - Matcher matcher = obtain(Tag.UL, line.getSource()); - if (matcher.find()) { - line.setType(Line.LINE_TYPE_UL); - Line line1 = line.createChild(matcher.group(1)); - line.setAttr(0); - Line parent = line.parentLine(); - LineQueue queue = queueProvider.getQueue(); - Line prev = line.prevLine(); - boolean inQuota = queue.currLine().getType() == Line.LINE_TYPE_QUOTA; - if (inQuota) { - line.setHandle(Line.HANDLE_BY_ROOT); - line.setData(Line.LINE_TYPE_UL); - } - if (prev != null && (prev.getType() == Line.LINE_TYPE_OL || prev.getType() == Line.LINE_TYPE_UL)) { - if (level > 0) { - line.setAttr(level); - } else { - String m = line.getSource().substring(matcher.start(), matcher.start(1) - 2); - m = m.replaceAll("\\t", " "); - if (m.length() > prev.getAttr() * 2 + 1) - line.setAttr(prev.getAttr() + 1); - else - line.setAttr(m.length() / 2); - } - - } - if (inQuota) { - line.setStyle(" "); - } else { - line.setStyle(styleBuilder.ul(" ", line.getAttr())); - } - if (find(Tag.UL, line1)) { - int nextLevel = line.getAttr() + 1; - line1.unAttachFromParent(); - - if (parent != null) { - Line p = parent.copyToNext(); - p.addChild(line1); - queue.next(); - ul(line1, nextLevel); - if (inQuota) { - while (p.parentLine() != null) { - p = p.parentLine(); - } - p.setStyle(styleBuilder.ul2(line1.getStyle(), findCount(Tag.QUOTA, p, 1) - 1, line1.getAttr())); - } else { - while (p != null && p.getType() == Line.LINE_TYPE_QUOTA) { - p.setStyle(styleBuilder.quota(line1.getStyle())); - p = p.parentLine(); - } - } - } else { - line.addNext(line1); - queue.next(); - ul(queue.currLine(), nextLevel); - } - - return true; - } - if (find(Tag.OL, line1)) { - int nextLevel = line.getAttr() + 1; - line1.unAttachFromParent(); - - if (parent != null) { - Line p = parent.copyToNext(); - p.addChild(line1); - queue.next(); - ol(line1, nextLevel); - if (inQuota) { - while (p.parentLine() != null) { - p = p.parentLine(); - } - p.setStyle(styleBuilder.ol2(line1.getStyle(), findCount(Tag.QUOTA, p, 1) - 1, line1.getAttr(), line1.getCount())); - } else { - while (p != null && p.getType() == Line.LINE_TYPE_QUOTA) { - p.setStyle(styleBuilder.quota(line1.getStyle())); - p = p.parentLine(); - } - } - - } else { - line.addNext(line1); - queue.next(); - ol(queue.currLine(), nextLevel); - } - - return true; - } - - CharSequence userText; - if (h(line1)) { - userText = line1.getStyle(); - } else { - userText = line1.getSource(); - } - SpannableStringBuilder builder; - if (userText instanceof SpannableStringBuilder) { - builder = (SpannableStringBuilder) userText; - } else { - builder = new SpannableStringBuilder(userText); - } - line.setStyle(builder); - inline(line); - if (!inQuota) { - line.setStyle(styleBuilder.ul(line.getStyle(), line.getAttr())); - } - return true; - } - return false; - } - - @Override - public boolean ol(Line line) { - return ol(line, 0); - } - - private boolean ol(Line line, int level) { - if (line.getSource() != null && (line.getSource().startsWith("- [ ]") || line.getSource().startsWith("- [x]"))) { - if (line.getSource().startsWith("- [x]")) { - return todoChecked(line); - } else { - return todoUnChecked(line); - } - } - Matcher matcher = obtain(Tag.OL, line.getSource()); - if (matcher.find()) { - line.setType(Line.LINE_TYPE_OL); - Line line1 = new Line(matcher.group(1)); - line.setAttr(0); - - Line parent = line.parentLine(); - LineQueue queue = queueProvider.getQueue(); - Line prev = line.prevLine(); - boolean inQuota = queue.currLine().getType() == Line.LINE_TYPE_QUOTA; - if (inQuota) { - line.setHandle(Line.HANDLE_BY_ROOT); - line.setData(Line.LINE_TYPE_OL); - } - - if (prev != null && (prev.getType() == Line.LINE_TYPE_OL || prev.getType() == Line.LINE_TYPE_UL)) { - if (level > 0) { - line.setAttr(level); - } else { - String m = line.getSource().substring(matcher.start(), matcher.start(1) - 2); - m = m.replaceAll("\\t", " "); - if (m.length() > prev.getAttr() * 2 + 1) - line.setAttr(prev.getAttr() + 1); - else - line.setAttr(m.length() / 2); - } - - } - if (prev != null && prev.getType() == Line.LINE_TYPE_OL && prev.getAttr() == line.getAttr()) { - line.setCount(prev.getCount() + 1); - } else { - line.setCount(1); - } - if (inQuota) { - line.setStyle(" "); - } else { - line.setStyle(styleBuilder.ol(" ", line.getAttr(), line.getCount())); - } - if (find(Tag.UL, line1)) { - int nextLevel = line.getAttr() + 1; - line1.unAttachFromParent(); - - if (parent != null) { - Line p = parent.copyToNext(); - p.addChild(line1); - queue.next(); - ul(line1, nextLevel); - if (inQuota) { - while (p.parentLine() != null) { - p = p.parentLine(); - } - p.setStyle(styleBuilder.ul2(line1.getStyle(), findCount(Tag.QUOTA, p, 1) - 1, line1.getAttr())); - } else { - while (p != null && p.getType() == Line.LINE_TYPE_QUOTA) { - p.setStyle(styleBuilder.quota(line1.getStyle())); - p = p.parentLine(); - } - } - } else { - line.addNext(line1); - queue.next(); - ul(queue.currLine(), nextLevel); - } - - return true; - } - if (find(Tag.OL, line1)) { - int nextLevel = line.getAttr() + 1; - line1.unAttachFromParent(); - - if (parent != null) { - Line p = parent.copyToNext(); - p.addChild(line1); - queue.next(); - ol(line1, nextLevel); - if (inQuota) { - while (p.parentLine() != null) { - p = p.parentLine(); - } - p.setStyle(styleBuilder.ol2(line1.getStyle(), findCount(Tag.QUOTA, p, 1) - 1, line1.getAttr(), line1.getCount())); - } else { - while (p != null && p.getType() == Line.LINE_TYPE_QUOTA) { - p.setStyle(styleBuilder.quota(line1.getStyle())); - p = p.parentLine(); - } - } - } else { - line.addNext(line1); - queue.next(); - ol(queue.currLine(), nextLevel); - } - - return true; - } - - CharSequence userText; - if (h(line1)) { - userText = line1.getStyle(); - } else { - userText = line1.getSource(); - } - SpannableStringBuilder builder; - if (userText instanceof SpannableStringBuilder) { - builder = (SpannableStringBuilder) userText; - } else { - builder = new SpannableStringBuilder(userText); - } - line.setStyle(builder); - inline(line); - - if (!inQuota) { - line.setStyle(styleBuilder.ol(line.getStyle(), line.getAttr(), line.getCount())); - } - return true; - } - return false; - } - - @Override - public boolean gap(Line line) { - line = line.get(); - Matcher matcher = obtain(Tag.GAP, line.getSource()); - if (matcher.matches()) { - line.setType(Line.LINE_TYPE_GAP); - line.setStyle(styleBuilder.gap()); - return true; - } - return false; - } - - @Override - public boolean em(Line line) { - line = line.get(); - SpannableStringBuilder builder = (SpannableStringBuilder) line.getStyle(); - Matcher matcher = obtain(Tag.EM, builder); - while (matcher.find()) { - int start = matcher.start(1); - int end = matcher.end(1); - if (checkInCode(builder, start, end)) { - continue; - } - SpannableStringBuilder sb = (SpannableStringBuilder) builder.subSequence(matcher.start(3), matcher.end(3)); - builder.delete(matcher.start(1), matcher.end(1)); - builder.insert(matcher.start(1), styleBuilder.em(sb)); - em(line); - return true; - } - return false; - } - - @Override - public boolean italic(Line line) { - line = line.get(); - SpannableStringBuilder builder = (SpannableStringBuilder) line.getStyle(); - Matcher matcher = obtain(Tag.ITALIC, builder); - while (matcher.find()) { - int start = matcher.start(1); - int end = matcher.end(1); - if (checkInCode(builder, start, end)) { - continue; - } - SpannableStringBuilder sb = (SpannableStringBuilder) builder.subSequence(matcher.start(3), matcher.end(3)); - builder.delete(matcher.start(1), matcher.end(1)); - builder.insert(matcher.start(1), styleBuilder.italic(sb)); - italic(line); - return true; - } - return false; - } - - @Override - public boolean emItalic(Line line) { - line = line.get(); - SpannableStringBuilder builder = (SpannableStringBuilder) line.getStyle(); - Matcher matcher = obtain(Tag.EM_ITALIC, builder); - while (matcher.find()) { - int start = matcher.start(1); - int end = matcher.end(1); - if (checkInCode(builder, start, end)) { - continue; - } - SpannableStringBuilder sb = (SpannableStringBuilder) builder.subSequence(matcher.start(3), matcher.end(3)); - builder.delete(matcher.start(1), matcher.end(1)); - builder.insert(matcher.start(1), styleBuilder.emItalic(sb)); - emItalic(line); - return true; - } - return false; - } - - @Override - public boolean code(Line line) { - line = line.get(); - SpannableStringBuilder builder = (SpannableStringBuilder) line.getStyle(); - if (builder.toString().endsWith("```") || builder.toString().startsWith("```")) { - return codeBlock2(line); - } - Matcher matcher = obtain(Tag.CODE, builder); - if (matcher.find()) { - String content = matcher.group(3); - builder.delete(matcher.start(1), matcher.end(1)); - builder.insert(matcher.start(1), styleBuilder.code(content)); - code(line); - return true; - } - return false; - } - - @Override - public boolean email(Line line) { - line = line.get(); - SpannableStringBuilder builder = (SpannableStringBuilder) line.getStyle(); - Matcher matcher = obtain(Tag.EMAIL, builder); - if (matcher.find()) { - SpannableStringBuilder sb = (SpannableStringBuilder) builder.subSequence(matcher.start(2), matcher.end(2)); - builder.delete(matcher.start(1), matcher.end(1)); - builder.insert(matcher.start(1), styleBuilder.email(sb)); - email(line); - return true; - } - return false; - } - - @Override - public boolean delete(Line line) { - line = line.get(); - SpannableStringBuilder builder = (SpannableStringBuilder) line.getStyle(); - Matcher matcher = obtain(Tag.DELETE, builder); - while (matcher.find()) { - int start = matcher.start(1); - int end = matcher.end(1); - if (checkInCode(builder, start, end)) { - continue; - } - SpannableStringBuilder sb = (SpannableStringBuilder) builder.subSequence(matcher.start(3), matcher.end(3)); - builder.delete(matcher.start(1), matcher.end(1)); - builder.insert(matcher.start(1), styleBuilder.delete(sb)); - delete(line); - return true; - } - return false; - } - - @Override - public boolean autoLink(Line line) { - line = line.get(); - SpannableStringBuilder builder = (SpannableStringBuilder) line.getStyle(); - Matcher matcher = obtain(Tag.AUTO_LINK, builder); - boolean m = false; - while (matcher.find()) { - String content = matcher.group(); - builder.delete(matcher.start(), matcher.end()); - builder.insert(matcher.start(), styleBuilder.link(content, content, "")); - m = true; - } - return m; - } - - @Override - public boolean link(Line line) { - line = line.get(); - SpannableStringBuilder builder = (SpannableStringBuilder) line.getStyle(); - Matcher matcher = obtain(Tag.LINK, builder); - if (matcher.find()) { - String title = matcher.group(2); - String link = matcher.group(3); - String hint = matcher.group(6); - builder.delete(matcher.start(1), matcher.end(1)); - builder.insert(matcher.start(1), styleBuilder.link(title, link, hint)); - link(line); - return true; - } - return false; - } - - @Override - public boolean link2(Line line) { - line = line.get(); - SpannableStringBuilder builder = (SpannableStringBuilder) line.getStyle(); - Matcher matcher = obtain(Tag.LINK2, builder); - if (matcher.find()) { - String title = matcher.group(2); - String id = matcher.group(3); - Pair link = idLinkLinks.get(id); - if (link != null) { - builder.delete(matcher.start(1), matcher.end(1)); - builder.insert(matcher.start(1), styleBuilder.link(title, link.first, link.second)); - } else { - return false; - } - link2(line); - return true; - } - return false; - } - - @Override - public boolean linkId(String line) { - Matcher matcher = obtain(Tag.LINK_ID, line); - if (matcher.find()) { - String id = matcher.group(1); - String link = matcher.group(2); - String hint = matcher.group(5); - idLinkLinks.put(id, new Pair<>(link, hint)); - return true; - } - return false; - } - - @Override - public boolean image(Line line) { - line = line.get(); - SpannableStringBuilder builder = (SpannableStringBuilder) line.getStyle(); - Matcher matcher = obtain(Tag.IMAGE, builder); - if (matcher.find()) { - String title = matcher.group(2); - String link = matcher.group(3); - String hint = matcher.group(6); - builder.delete(matcher.start(1), matcher.end(1)); - builder.insert(matcher.start(1), styleBuilder.image(title, link, hint)); - image(line); - return true; - } - return false; - } - - @Override - public boolean image2(Line line) { - line = line.get(); - SpannableStringBuilder builder = (SpannableStringBuilder) line.getStyle(); - Matcher matcher = obtain(Tag.IMAGE2, builder); - if (matcher.find()) { - String title = matcher.group(2); - String id = matcher.group(3); - Pair image = idImageUrl.get(id); - if (image != null) { - builder.delete(matcher.start(1), matcher.end(1)); - builder.insert(matcher.start(1), styleBuilder.image(title, image.first, image.second)); - } else { - return false; - } - image2(line); - return true; - } - return false; - } - - @Override - public boolean imageId(String line) { - Matcher matcher = obtain(Tag.IMAGE_ID, line); - if (matcher.find()) { - String id = matcher.group(1); - String link = matcher.group(2); - String hint = matcher.group(5); - idImageUrl.put(id, new Pair<>(link, hint)); - return true; - } - return false; - } - - @Override - public boolean codeBlock1(Line line) { - Matcher matcher = obtain(Tag.CODE_BLOCK_1, line.getSource()); - if (matcher.find()) { - String content = matcher.group(2); - LineQueue queue = queueProvider.getQueue(); - Line next = queue.nextLine(); - StringBuilder sb = new StringBuilder(content); - StringBuilder bsb = new StringBuilder(); - - while (next != null) { - CharSequence r = get(Tag.CODE_BLOCK_1, next, 2); - if (r == null) { - if (find(Tag.BLANK, next)) { - bsb.append(' ').append('\n'); - } else { - break; - } - } else { - if (bsb.length() != 0) { - sb.append(bsb).append(r); - bsb.delete(0, sb.length()); - } else { - sb.append('\n').append(r); - } - } - queue.removeNextLine(); - next = queue.nextLine(); - } - - - line.setType(Line.LINE_TYPE_CODE_BLOCK_1); - line.setStyle(styleBuilder.codeBlock(sb.toString())); - return true; - } - return false; - } - - - @Override - public boolean codeBlock2(Line line) { - if (find(Tag.CODE_BLOCK_2, line)) { - LineQueue queue = queueProvider.getQueue(); - LineQueue nextQueue = queue.copy(); - boolean find = false; - while (nextQueue.nextLine() != null) { - if (find(Tag.CODE_BLOCK_2, nextQueue.nextLine())) { - nextQueue.next(); - removePrevBlankLine(nextQueue); - removeNextBlankLine(queue); - find = true; - break; - } - nextQueue.next(); - } - if (find) { - StringBuilder sb = new StringBuilder(); - queue.next(); - queue.removePrevLine(); - while (queue.currLine() != nextQueue.currLine()) { - sb.append(queue.currLine().getSource()).append('\n'); - queue.next(); - queue.removePrevLine(); - } - removeNextBlankLine(nextQueue); - nextQueue.currLine().setType(Line.LINE_TYPE_CODE_BLOCK_2); - nextQueue.currLine().setStyle(styleBuilder.codeBlock(sb.toString())); - return true; - } else { - return false; - } - } - return false; - } - - @Override public boolean todoChecked(Line line) { - Matcher matcher = obtain(Tag.TODO_CHECKED, line.getSource()); - if (matcher != null && matcher.find()) { - line.setType(Line.LINE_TYPE_CHECKED); - line.setStyle(SpannableStringBuilder.valueOf(matcher.group(1))); - inline(line); - line.setStyle(styleBuilder.checked(line.getStyle())); - return true; - } - return false; - } - - @Override public boolean todoUnChecked(Line line) { - Matcher matcher = obtain(Tag.TODO_UNCHECKED, line.getSource()); - if (matcher != null && matcher.find()) { - line.setType(Line.LINE_TYPE_UN_CHECKED); - line.setStyle(SpannableStringBuilder.valueOf(matcher.group(1))); - inline(line); - line.setStyle(styleBuilder.unChecked(line.getStyle())); - return true; - } - return false; - } - - @Override - public boolean inline(Line line) { - boolean flag = code(line); - flag = emItalic(line) || flag; - flag = em(line) || flag; - flag = italic(line) || flag; - flag = delete(line) || flag; - flag = email(line) || flag; - flag = image(line) || flag; - flag = image2(line) || flag; - flag = link(line) || flag; - flag = link2(line) || flag; - flag = autoLink(line) || flag; - return flag; - } - - @Override - public boolean find(int tag, Line line) { - return line != null && find(tag, line.getSource()); - } - - @Override - public boolean find(int tag, String line) { - if (line == null) { - return false; - } - Matcher m = obtain(tag, line); - return m != null && m.find(); - } - - @Override - public int findCount(int tag, Line line, int group) { - return line == null ? 0 : findCount(tag, line.getSource(), group); - } - - @Override - public int findCount(int tag, String line, int group) { - if (line == null) { - return 0; - } - - Matcher matcher = obtain(tag, line); - if (matcher == null) { - return 0; - } - if (matcher.find()) { - return findCount(tag, matcher.group(group), group) + 1; - } - - return 0; - } - - private boolean checkInCode(SpannableStringBuilder builder, int start, int end) { - CodeSpan[] css = builder.getSpans(0, builder.length(), CodeSpan.class); - for (CodeSpan cs : css) { - int c_start = builder.getSpanStart(cs); - int c_end = builder.getSpanEnd(cs); - if (!(c_start >= end || c_end <= start)) { - return true; - } - } - return false; - } - - private Matcher obtain(int tag, CharSequence src) { - Matcher m = matchers.get(tag, null); - if (m != null) { - m.reset(src); - } - return m; - } - - public void setQueueProvider(QueueProvider queueProvider) { - this.queueProvider = queueProvider; - } - - - @Override - public CharSequence get(int tag, Line line, int group) { - return get(tag, line.getSource(), group); - } - - @Override - public CharSequence get(int tag, CharSequence line, int group) { - Matcher m = obtain(tag, line); - return m.find() ? m.group(group) : null; - } - - private void removeNextBlankLine(LineQueue queue) { - while (queue.nextLine() != null) { - if (find(Tag.BLANK, queue.nextLine())) { - queue.removeNextLine(); - } else { - return; - } - } - } - - private void removePrevBlankLine(LineQueue queue) { - while (queue.prevLine() != null) { - if (find(Tag.BLANK, queue.prevLine())) { - queue.removePrevLine(); - } else { - return; - } - } - } - - -} diff --git a/app/src/main/java/com/zzhoujay/markdown/style/CodeBlockSpan.java b/app/src/main/java/com/zzhoujay/markdown/style/CodeBlockSpan.java deleted file mode 100755 index 44a586d2..00000000 --- a/app/src/main/java/com/zzhoujay/markdown/style/CodeBlockSpan.java +++ /dev/null @@ -1,120 +0,0 @@ -package com.zzhoujay.markdown.style; - -import android.graphics.Canvas; -import android.graphics.Paint; -import android.graphics.drawable.Drawable; -import android.graphics.drawable.GradientDrawable; -import android.support.annotation.NonNull; -import android.text.style.LineHeightSpan; -import android.text.style.ReplacementSpan; -import android.util.Pair; - -import java.util.ArrayList; -import java.util.List; - -/** - * Created by zhou on 16-7-2. - * 代码块Span - */ -public class CodeBlockSpan extends ReplacementSpan implements LineHeightSpan { - - private static final float radius = 10; - private static final int padding = 30; - - private int width; - private Drawable drawable; - private int baseLine; - private int lineHeight; - private CharSequence[] ls; - private List> lines; - - public CodeBlockSpan(int width, int color, CharSequence... lines) { - this.width = width; - GradientDrawable g = new GradientDrawable(); - g.setColor(color); - g.setCornerRadius(radius); - drawable = g; - this.ls = lines; - } - - @Override public int getSize(Paint paint, CharSequence text, int start, int end, Paint.FontMetricsInt fm) { - if (fm != null && lines == null) { - lines = new ArrayList<>(); - for (CharSequence c : ls) { - lines.addAll(measureTextLine(c, 0, c.length(), paint)); - } - } - return width; - } - - @Override public void draw(@NonNull Canvas canvas, CharSequence text, int start, int end, float x, - int top, int y, int bottom, @NonNull Paint paint) { - drawable.setBounds((int) x, top, (int) x + width, bottom); - drawable.draw(canvas); - int lineNum = 0; - x = x + padding; - int i = baseLine + lineHeight / 2 + top; - for (Pair line : lines) { - try { - CharSequence t = ls[lineNum]; - canvas.drawText(t, line.first, line.second, x + padding, i, paint); - if (line.second >= t.length()) { - lineNum++; - } - i += lineHeight; - } catch (IndexOutOfBoundsException ignored) {} - } - } - - private int getTextInLineLen(CharSequence text, int start, int end, Paint paint) { - int e = start; - while (paint.measureText(text, start, e) < width - padding * 2) { - e++; - if (e > end) { - break; - } - } - return e - 1; - } - - private int getTextInLineLenInRange(CharSequence text, int start, int end, int rs, int re, Paint paint) { - int e = rs; - if (rs > end) { - return end; - } - try { - while (paint.measureText(text, start, e) < width - padding * 2) { - e++; - if (e > end || e > re) { - break; - } - } - } catch (Exception ignored) {} - return e - 1; - } - - private List> measureTextLine(CharSequence text, int start, int end, Paint paint) { - List> lines = new ArrayList<>(); - int l = getTextInLineLen(text, start, end, paint); - int count = l; - lines.add(new Pair<>(start, l)); - while (l < end) { - int temp = l; - l = getTextInLineLenInRange(text, l, end, l + count - 4, l + count + 4, paint); - count = l - temp; - lines.add(new Pair<>(temp, l)); - } - return lines; - } - - @Override public void chooseHeight(CharSequence text, int start, int end, int spanstartv, int v, Paint.FontMetricsInt fm) { - int num = lines.size(); - lineHeight = fm.bottom - fm.top; - baseLine = -fm.top; - fm.ascent = fm.top; - fm.bottom += num * lineHeight; - fm.descent = fm.bottom; - } - - -} diff --git a/app/src/main/java/com/zzhoujay/markdown/style/EmailSpan.java b/app/src/main/java/com/zzhoujay/markdown/style/EmailSpan.java deleted file mode 100755 index 5fa6b686..00000000 --- a/app/src/main/java/com/zzhoujay/markdown/style/EmailSpan.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.zzhoujay.markdown.style; - -import android.annotation.SuppressLint; -import android.content.ActivityNotFoundException; -import android.content.Intent; -import android.net.Uri; -import android.text.TextPaint; -import android.text.style.URLSpan; -import android.util.Log; -import android.view.View; - -/** - * Created by zhou on 16-7-30. - * EmailSpan - */ -@SuppressLint("ParcelCreator") -public class EmailSpan extends URLSpan { - - private int color; - - public EmailSpan(String email, int color) { - super(email); - this.color = color; - } - - @Override - public void updateDrawState(TextPaint ds) { - super.updateDrawState(ds); - ds.setColor(color); - ds.setUnderlineText(false); - } - - @Override - public void onClick(View widget) { - Intent intent = new Intent(Intent.ACTION_SENDTO); - intent.setData(Uri.parse("mailto:" + getURL())); - intent.putExtra(Intent.EXTRA_SUBJECT, ""); - intent.putExtra(Intent.EXTRA_TEXT, ""); - try { - widget.getContext().startActivity(intent); - } catch (ActivityNotFoundException e) { - Log.w("URLSpan", "Actvity was not found for intent, " + intent.toString()); - } - } -} diff --git a/app/src/main/java/com/zzhoujay/markdown/style/MarkDownBulletSpan.java b/app/src/main/java/com/zzhoujay/markdown/style/MarkDownBulletSpan.java deleted file mode 100755 index 66907c39..00000000 --- a/app/src/main/java/com/zzhoujay/markdown/style/MarkDownBulletSpan.java +++ /dev/null @@ -1,139 +0,0 @@ -package com.zzhoujay.markdown.style; - -import android.annotation.TargetApi; -import android.graphics.Canvas; -import android.graphics.Paint; -import android.graphics.Path; -import android.os.Build; -import android.text.Layout; -import android.text.Spanned; -import android.text.style.BulletSpan; -import android.widget.TextView; - -import com.zzhoujay.markdown.util.NumberKit; - -import java.lang.ref.WeakReference; - -/** - * Created by zhou on 16-6-25. - * 列表Span - */ -public class MarkDownBulletSpan extends BulletSpan { - private static final int tab = 40; - private static final int mGapWidth = 40; - private static final int BULLET_RADIUS = 6; - - private final boolean mWantColor; - private final int mColor; - private final String index; - private int level = 0; - private int margin; - - private static Path circleBulletPath = null; - private static Path rectBulletPath = null; - - private WeakReference textViewWeakReference; - - public MarkDownBulletSpan(int l, int color, int pointIndex, TextView textView) { - super(mGapWidth, color); - level = l; - if (pointIndex > 0) { - if (level == 1) { - this.index = NumberKit.toRomanNumerals(pointIndex); - } else if (level >= 2) { - this.index = NumberKit.toABC(pointIndex - 1); - } else { - this.index = pointIndex + ""; - } - } else { - index = null; - } - mWantColor = true; - mColor = color; - textViewWeakReference = new WeakReference<>(textView); - } - - public MarkDownBulletSpan(int level, int color, int pointIndex) { - super(mGapWidth, color); - this.level = level; - if (pointIndex > 0) { - if (level == 1) { - this.index = NumberKit.toRomanNumerals(pointIndex); - } else if (level >= 2) { - this.index = NumberKit.toABC(pointIndex - 1); - } else { - this.index = pointIndex + ""; - } - } else { - index = null; - } - mWantColor = true; - mColor = color; - } - - - @Override - public int getLeadingMargin(boolean first) { - TextView textView = textViewWeakReference != null ? textViewWeakReference.get() : null; - if (index != null && textView != null) { - margin = (int) (tab + (mGapWidth + textView.getPaint().measureText(index)) * (level + 1)); - } else { - margin = (2 * BULLET_RADIUS + mGapWidth) * (level + 1) + tab; - } - return margin; - } - - @TargetApi(Build.VERSION_CODES.HONEYCOMB) - @Override - public void drawLeadingMargin(Canvas c, Paint p, int x, int dir, int top, int baseline, int bottom, CharSequence text, int start, int end, boolean first, Layout l) { - if (((Spanned) text).getSpanStart(this) == start) { - int oldcolor = 0; - if (mWantColor) { - oldcolor = p.getColor(); - p.setColor(mColor); - } - if (index != null) { - c.drawText(index + '.', x - p.measureText(index) + margin - mGapWidth, baseline, p); - } else { - Paint.Style style = p.getStyle(); - if (level == 1) { - p.setStyle(Paint.Style.STROKE); - } else { - p.setStyle(Paint.Style.FILL); - } - - if (c.isHardwareAccelerated()) { - Path path; - if (level >= 2) { - if (rectBulletPath == null) { - rectBulletPath = new Path(); - float w = 1.2f * BULLET_RADIUS; - rectBulletPath.addRect(-w, -w, w, w, Path.Direction.CW); - } - path = rectBulletPath; - } else { - if (circleBulletPath == null) { - circleBulletPath = new Path(); - // Bullet is slightly better to avoid aliasing artifacts on mdpi devices. - circleBulletPath.addCircle(0.0f, 0.0f, 1.2f * BULLET_RADIUS, Path.Direction.CW); - } - path = circleBulletPath; - } - - c.save(); - c.translate(x + margin - mGapWidth, (top + bottom) / 2.0f); - c.drawPath(path, p); - c.restore(); - } else { - c.drawCircle(x + margin - mGapWidth, (top + bottom) / 2.0f, BULLET_RADIUS, p); - } - - p.setStyle(style); - } - if (mWantColor) { - p.setColor(oldcolor); - } - } - } - -} diff --git a/app/src/main/java/com/zzhoujay/markdown/style/MarkDownInnerBulletSpan.java b/app/src/main/java/com/zzhoujay/markdown/style/MarkDownInnerBulletSpan.java deleted file mode 100755 index 22d7ed86..00000000 --- a/app/src/main/java/com/zzhoujay/markdown/style/MarkDownInnerBulletSpan.java +++ /dev/null @@ -1,106 +0,0 @@ -package com.zzhoujay.markdown.style; - -import android.annotation.TargetApi; -import android.graphics.Canvas; -import android.graphics.Paint; -import android.graphics.Path; -import android.os.Build; -import android.text.style.ReplacementSpan; - -import com.zzhoujay.markdown.util.NumberKit; - -/** - * Created by zhou on 16-7-3. - * 列表Span - */ -public class MarkDownInnerBulletSpan extends ReplacementSpan { - - private static final int BULLET_RADIUS = 6; - private static final int tab = 40; - private static final int gap = 40; - - private final int mColor; - private final String index; - private int margin; - private int level; - - private static Path circleBulletPath = null; - private static Path rectBulletPath = null; - - - public MarkDownInnerBulletSpan(int level, int mColor, int index) { - this.mColor = mColor; - this.level = level; - if (index > 0) { - if (level == 1) { - this.index = NumberKit.toRomanNumerals(index) + '.'; - } else if (level >= 2) { - this.index = NumberKit.toABC(index - 1) + '.'; - } else { - this.index = index + "."; - } - } else { - this.index = null; - } - } - - @Override - public int getSize(Paint paint, CharSequence text, int start, int end, Paint.FontMetricsInt fm) { - if (index == null) { - margin = tab + (gap + BULLET_RADIUS * 2) * (level + 1); - } else { - margin = (int) (tab + (gap + paint.measureText(index)) * (level + 1)); - } - return (int) (margin + paint.measureText(text, start, end)); - } - - @TargetApi(Build.VERSION_CODES.HONEYCOMB) - @Override - public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, Paint paint) { - int oldcolor = paint.getColor(); - paint.setColor(mColor); - // draw bullet - if (index != null) { - canvas.drawText(index, x + tab, y, paint); - } else { - Paint.Style style = paint.getStyle(); - - if (level == 1) { - paint.setStyle(Paint.Style.STROKE); - } else { - paint.setStyle(Paint.Style.FILL); - } - - if (canvas.isHardwareAccelerated()) { - Path path; - if (level >= 2) { - if (rectBulletPath == null) { - rectBulletPath = new Path(); - float w = 1.2f * BULLET_RADIUS; - rectBulletPath.addRect(-w, -w, w, w, Path.Direction.CW); - } - path = rectBulletPath; - } else { - if (circleBulletPath == null) { - circleBulletPath = new Path(); - // Bullet is slightly better to avoid aliasing artifacts on mdpi devices. - circleBulletPath.addCircle(0.0f, 0.0f, 1.2f * BULLET_RADIUS, Path.Direction.CW); - } - path = circleBulletPath; - } - - canvas.save(); - canvas.translate(x + margin - gap, (top + bottom) / 2.0f); - canvas.drawPath(path, paint); - canvas.restore(); - } else { - canvas.drawCircle(x + margin - gap, (top + bottom) / 2.0f, BULLET_RADIUS, paint); - } - paint.setStyle(style); - } - // drawText - canvas.drawText(text, start, end, x + margin, y, paint); - paint.setColor(oldcolor); - } - -} diff --git a/app/src/main/java/com/zzhoujay/markdown/style/QuotaBulletSpan.java b/app/src/main/java/com/zzhoujay/markdown/style/QuotaBulletSpan.java deleted file mode 100755 index 6efd8676..00000000 --- a/app/src/main/java/com/zzhoujay/markdown/style/QuotaBulletSpan.java +++ /dev/null @@ -1,147 +0,0 @@ -package com.zzhoujay.markdown.style; - -import android.annotation.TargetApi; -import android.graphics.Canvas; -import android.graphics.Paint; -import android.graphics.Path; -import android.os.Build; -import android.text.Layout; -import android.text.Spanned; -import android.text.style.QuoteSpan; -import android.widget.TextView; - -import com.zzhoujay.markdown.util.NumberKit; - -import java.lang.ref.WeakReference; - -/** - * Created by zhou on 16-7-30. - */ -public class QuotaBulletSpan extends QuoteSpan { - - private static final int tab = 40; - private static final int mGapWidth = 40; - private static final int BULLET_RADIUS = 6; - - - private static final int STRIPE_WIDTH = 15; - private static final int GAP_WIDTH = 40; - - private static Path circleBulletPath = null; - private static Path rectBulletPath = null; - - private final String index; - private int level = 0; - private int bulletColor; - private int margin; - private WeakReference textViewWeakReference; - private int quotaLevel; - - - public QuotaBulletSpan(int quotaLevel, int bulletLevel, int quotaColor, int bulletColor, int pointIndex, TextView textView) { - super(quotaColor); - this.quotaLevel = quotaLevel; - this.level = bulletLevel; - if (pointIndex > 0) { - if (bulletLevel == 1) { - this.index = NumberKit.toRomanNumerals(pointIndex); - } else if (bulletLevel >= 2) { - this.index = NumberKit.toABC(pointIndex - 1); - } else { - this.index = pointIndex + ""; - } - } else { - index = null; - } - this.bulletColor = bulletColor; - this.textViewWeakReference = new WeakReference<>(textView); - } - - @TargetApi(Build.VERSION_CODES.HONEYCOMB) - @Override - public void drawLeadingMargin(Canvas c, Paint p, int x, int dir, int top, int baseline, int bottom, CharSequence text, int start, int end, boolean first, Layout layout) { - // draw quota - Paint.Style style = p.getStyle(); - int color = p.getColor(); - - p.setStyle(Paint.Style.FILL); - p.setColor(getColor()); - - int i = 0; - int quotaWidth = STRIPE_WIDTH + GAP_WIDTH; - - while (i <= quotaLevel) { - int offset = i * quotaWidth; - c.drawRect(x + offset, top, x + offset + dir * STRIPE_WIDTH, bottom, p); - i++; - } - - p.setStyle(style); - p.setColor(color); - - // draw bullet - if (((Spanned) text).getSpanStart(this) == start) { - int oldColor; - oldColor = p.getColor(); - p.setColor(bulletColor); - if (index != null) { - c.drawText(index + '.', x - p.measureText(index) + margin - mGapWidth, baseline, p); - } else { - style = p.getStyle(); - if (level == 1) { - p.setStyle(Paint.Style.STROKE); - } else { - p.setStyle(Paint.Style.FILL); - } - - if (c.isHardwareAccelerated()) { - Path path; - if (level >= 2) { - if (rectBulletPath == null) { - rectBulletPath = new Path(); - float w = 1.2f * BULLET_RADIUS; - rectBulletPath.addRect(-w, -w, w, w, Path.Direction.CW); - } - path = rectBulletPath; - } else { - if (circleBulletPath == null) { - circleBulletPath = new Path(); - // Bullet is slightly better to avoid aliasing artifacts on mdpi devices. - circleBulletPath.addCircle(0.0f, 0.0f, 1.2f * BULLET_RADIUS, Path.Direction.CW); - } - path = circleBulletPath; - } - - c.save(); - c.translate(x + margin - mGapWidth, (top + bottom) / 2.0f); - c.drawPath(path, p); - c.restore(); - } else { - c.drawCircle(x + margin - mGapWidth, (top + bottom) / 2.0f, BULLET_RADIUS, p); - } - - p.setStyle(style); - } - p.setColor(oldColor); - } - - - } - - @Override - public int getLeadingMargin(boolean first) { - if (textViewWeakReference == null && margin != 0) { - return margin; - } - TextView textView = textViewWeakReference.get(); - if (index != null && textView != null) { - margin = (int) (tab + (mGapWidth + textView.getPaint().measureText(index)) * (level + 1)); - } else { - margin = (2 * BULLET_RADIUS + mGapWidth) * (level + 1) + tab; - } - int bulletMargin = (quotaLevel + 1) * (STRIPE_WIDTH + GAP_WIDTH); - margin += bulletMargin; - return margin; - } - -} diff --git a/app/src/main/java/com/zzhoujay/markdown/style/ScaleHeightSpan.java b/app/src/main/java/com/zzhoujay/markdown/style/ScaleHeightSpan.java deleted file mode 100755 index 74b12ec5..00000000 --- a/app/src/main/java/com/zzhoujay/markdown/style/ScaleHeightSpan.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.zzhoujay.markdown.style; - -import android.graphics.Paint; -import android.text.style.LineHeightSpan; - -/** - * Created by zhou on 16-7-2. - * ScaleHeightSpan - */ -public class ScaleHeightSpan implements LineHeightSpan { - - private float scale; - - public ScaleHeightSpan(float scale) { - this.scale = scale; - } - - @Override - public void chooseHeight(CharSequence text, int start, int end, int spanstartv, int v, Paint.FontMetricsInt fm) { - fm.ascent *= scale; - fm.top *= scale; - fm.descent *= scale; - fm.bottom *= scale; - } - -} diff --git a/app/src/main/java/com/zzhoujay/markdown/style/UnderLineSpan.java b/app/src/main/java/com/zzhoujay/markdown/style/UnderLineSpan.java deleted file mode 100755 index 6a46da31..00000000 --- a/app/src/main/java/com/zzhoujay/markdown/style/UnderLineSpan.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.zzhoujay.markdown.style; - -import android.graphics.Canvas; -import android.graphics.Paint; -import android.graphics.drawable.Drawable; -import android.text.style.LineHeightSpan; -import android.text.style.ReplacementSpan; - -/** - * Created by zhou on 16-7-2. - */ -public class UnderLineSpan extends ReplacementSpan implements LineHeightSpan { - - private int height; - private int width; - private Drawable drawable; - - public UnderLineSpan(Drawable drawable, int width, int height) { - this.height = height; - this.width = width; - this.drawable = drawable; - } - - - @Override - public int getSize(Paint paint, CharSequence text, int start, int end, Paint.FontMetricsInt fm) { - return (int) paint.measureText(text, start, end); - } - - @Override - public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, Paint paint) { - drawable.setBounds((int) x, bottom - height, (int) x + width, bottom); - drawable.draw(canvas); - } - - @Override - public void chooseHeight(CharSequence text, int start, int end, int spanstartv, int v, Paint.FontMetricsInt fm) { - fm.top /= 3; - fm.ascent /= 3; - fm.bottom /= 3; - fm.descent /= 3; - } -} diff --git a/app/src/main/java/com/zzhoujay/markdown/util/FontKit.java b/app/src/main/java/com/zzhoujay/markdown/util/FontKit.java deleted file mode 100755 index e5cd7e0e..00000000 --- a/app/src/main/java/com/zzhoujay/markdown/util/FontKit.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.zzhoujay.markdown.util; - -import android.graphics.Paint; - -/** - * Created by zhou on 16-7-3. - */ -public class FontKit { - - public static void scale(Paint.FontMetricsInt fm, float scale) { - fm.top *= scale; - fm.bottom *= scale; - fm.ascent *= scale; - fm.descent *= scale; - fm.leading *= scale; - } - - public static void scaleTo(Paint.FontMetricsInt from, Paint.FontMetricsInt to, float scale) { - to.top = (int) (from.top * scale); - to.bottom = (int) (from.bottom * scale); - to.ascent = (int) (from.ascent * scale); - to.descent = (int) (from.descent * scale); - to.leading = (int) (from.leading * scale); - } -} diff --git a/app/src/main/java/com/zzhoujay/markdown/util/NumberKit.java b/app/src/main/java/com/zzhoujay/markdown/util/NumberKit.java deleted file mode 100755 index 5aec29cc..00000000 --- a/app/src/main/java/com/zzhoujay/markdown/util/NumberKit.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.zzhoujay.markdown.util; - -/** - * created by zhou on 16-7-17. - */ -public class NumberKit { - - private static final String[] digit = {"", "i", "ii", "iii", "iv", "v", "vi", "vii", "viii", "ix"}; - private static final String[] ten = {"", "x", "xx", "xxx", "xl", "l", "lx", "lxx", "lxxx", "xc"}; - private static final String[] hundreds = {"", "c", "cc", "ccc", "cd", "d", "dc", "dcc", "dccc", "cm"}; - private static final String[] thousand = {"", "m", "mm", "mmm"}; - - private static final int ROMAN_MAX = 4996; - - public static String toRomanNumerals(int num) { - while (num > ROMAN_MAX) { - num -= ROMAN_MAX; - } - String th = thousand[num / 1000]; - num %= 1000; - String hu = hundreds[num / 100]; - num %= 100; - String te = ten[num / 10]; - num %= 10; - String di = digit[num]; - return String.format("%s%s%s%s", th, hu, te, di); - } - - public static String toABC(int num) { - int a = num / 26; - int b = num % 26; - StringBuilder sb = new StringBuilder(); - if (a > 26) { - sb.append(toABC(a - 1)).append((char) (b + 'a')); - } else if (a == 0) { - sb.append((char) (b + 'a')); - } else { - sb.append((char) (a + 'a')).append((char) (b + 'a')); - } - return sb.toString(); -// while (num < 0) { -// num += 26; -// } -// while (num > 26) { -// num -= 26; -// } -// return String.valueOf((char) (num + 'a')); - } - -}