private SpannableStringBuilder doAutoLinks( SpannableStringBuilder ssb, ArrayList<MarkdownURL> urls) { // Colorize URLs AutomatonMatcher am = autoLinkUrlAutomaton.newMatcher(ssb); while (am.find()) { ForegroundColorSpan fcs = new ForegroundColorSpan(Constants.MARKDOWN_LINK_COLOR); ssb.setSpan(fcs, am.start(), am.end(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); urls.add(new MarkdownURL(am.start(), am.group(), null)); } // Don't autolink emails for now. Neither does reddit.com // m = autoLinkEmail.matcher(ssb); // int start = 0; // while (m.find(start)) { // String address = m.group(1); // TextEditor ed = new TextEditor(address); // unEscapeSpecialChars(ed); // String addr = encodeEmail(ed.toString()); // String url = encodeEmail("mailto:" + ed.toString()); // // urls.add(url); // ssb.replace(m.start(), m.end(), addr); // ForegroundColorSpan fcs = new ForegroundColorSpan(Constants.MARKDOWN_LINK_COLOR); // ssb.setSpan(fcs, m.start(), m.end(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); // // Skip what we just replaced // m = autoLinkEmail.matcher(ssb); // start = m.start() + addr.length(); // } return ssb; }
/** Adapted from MarkdownJ. Convert links, return URL */ private SpannableStringBuilder doAnchors( SpannableStringBuilder ssb, ArrayList<MarkdownURL> urls) { // Inline-style links: [link text](url "optional title") AutomatonMatcher am = inlineLinkAutomaton.newMatcher(ssb); // The offset into the entire original string int start = 0; while (am.find()) { // The offsets from start (offset into orig. string = start + anchorStart) int anchorStart = am.start(); int anchorEnd = am.end(); Matcher m = inlineLink.matcher(am.group()); if (!m.find()) continue; String linkText = m.group(2); String url = m.group(3); String title = m.group(6); int linkTextLength = linkText.length(); if (Constants.LOGGING) Log.d( TAG, "pos=" + am.start() + " linkText=" + linkText + " url=" + url + " title=" + title); // protect emphasis (* and _) within urls // url = url.replaceAll("\\*", CHAR_PROTECTOR.encode("*")); // url = url.replaceAll("_", CHAR_PROTECTOR.encode("_")); urls.add(new MarkdownURL(start + anchorStart, url, linkText)); // StringBuffer result = new StringBuffer(); // TODO: Show title (if any) alongside url in popup menu // if (title != null) { // // protect emphasis (* and _) within urls // title = title.replaceAll("\\*", CHAR_PROTECTOR.encode("*")); // title = title.replaceAll("_", CHAR_PROTECTOR.encode("_")); // title.replaceAll("\"", """); // result.append(" title=\""); // result.append(title); // result.append("\""); // } // Replace whole anchor thing with just linkText, colored different color SpannableString ss = new SpannableString(linkText); ForegroundColorSpan fcs = new ForegroundColorSpan(Constants.MARKDOWN_LINK_COLOR); ss.setSpan(fcs, 0, linkTextLength, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); ssb = ssb.replace(start + anchorStart, start + anchorEnd, ss); // Skip past what we just replaced am = inlineLinkAutomaton.newMatcher(ssb, start + anchorStart + linkTextLength, ssb.length()); start += anchorStart + linkTextLength; } return ssb; }
/** * @param txt input text * @param urls Out URLs from anchors * @return updated text with anchors replaced */ private String doAnchorURLs( String txt, ArrayList<MarkdownURL> urls, TreeMap<Integer, Integer> startToEndOffsetMap) { // Inline-style links: [link text](url "optional title") AutomatonMatcher am = inlineLinkAutomaton.newMatcher(txt); // The offset into the entire original string int start = 0; while (am.find()) { // The offsets from start (offset into orig. string = start + anchorStart) int anchorStart = am.start(); int anchorEnd = am.end(); Matcher m = inlineLink.matcher(am.group()); if (!m.find()) continue; String linkText = m.group(2); String url = m.group(3); String title = m.group(6); int linkTextLength = linkText.length(); if (Constants.LOGGING) Log.d( TAG, "pos=" + (start + anchorStart) + " linkText=" + linkText + " url=" + url + " title=" + title); // protect emphasis (* and _) within urls // url = url.replaceAll("\\*", CHAR_PROTECTOR.encode("*")); // url = url.replaceAll("_", CHAR_PROTECTOR.encode("_")); if (!isOverlapping( start + anchorStart, start + anchorStart + linkTextLength, startToEndOffsetMap)) { saveStartAndEnd( start + anchorStart, start + anchorStart + linkTextLength, startToEndOffsetMap); urls.add(new MarkdownURL(start + anchorStart, Util.absolutePathToURL(url), linkText)); } // StringBuffer result = new StringBuffer(); // TODO: Show title (if any) alongside url in popup menu // if (title != null) { // // protect emphasis (* and _) within urls // title = title.replaceAll("\\*", CHAR_PROTECTOR.encode("*")); // title = title.replaceAll("_", CHAR_PROTECTOR.encode("_")); // title.replaceAll("\"", """); // result.append(" title=\""); // result.append(title); // result.append("\""); // } txt = new StringBuilder(txt.substring(0, start + anchorStart)) .append(linkText) .append(txt.substring(start + anchorEnd, txt.length())) .toString(); // Skip past what we just replaced am = inlineLinkAutomaton.newMatcher(txt, start + anchorStart + linkTextLength, txt.length()); start += anchorStart + linkTextLength; } return txt; }