下面列出了android.text.SpannableStringBuilder#delete ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
private static CharSequence obtainThreadComment(String comment, String chanName, ChanMarkup.MarkupExtra extra) {
SpannableStringBuilder commentBuilder = new SpannableStringBuilder(obtainComment(comment,
chanName, null, extra));
int linebreaks = 0;
// Remove more than one linebreaks in sequence
for (int i = commentBuilder.length() - 1; i >= 0; i--) {
char c = commentBuilder.charAt(i);
if (c == '\n') {
linebreaks++;
} else {
if (linebreaks > 1) {
// Remove linebreaks - 1 characters, keeping one line break
commentBuilder.delete(i + 1, i + linebreaks);
}
linebreaks = 0;
}
}
return commentBuilder;
}
/**
* Parse the given input using {@link TouchableUrlSpan}s
* rather than vanilla {@link URLSpan}s so that they respond to touch.
*
* @param input
* @param linkTextColor
* @param linkHighlightColor
* @return
*/
public static Spanned parseHtml(String input,
ColorStateList linkTextColor,
@ColorInt int linkHighlightColor) {
SpannableStringBuilder spanned = (SpannableStringBuilder) Html.fromHtml(input);
// strip any trailing newlines
while (spanned.charAt(spanned.length() - 1) == '\n') {
spanned = spanned.delete(spanned.length() - 1, spanned.length());
}
URLSpan[] urlSpans = spanned.getSpans(0, spanned.length(), URLSpan.class);
for (URLSpan urlSpan : urlSpans) {
int start = spanned.getSpanStart(urlSpan);
int end = spanned.getSpanEnd(urlSpan);
spanned.removeSpan(urlSpan);
// spanned.subSequence(start, start + 1) == "@" TODO send to our own user activity...
// when i've written it
spanned.setSpan(new TouchableUrlSpan(urlSpan.getURL(), linkTextColor,
linkHighlightColor), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
return spanned;
}
@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;
}
/**
* Replace the control codes
*
* @param m
* @param ssb
* @param style
*/
private static void replaceControlCodes(Matcher m, SpannableStringBuilder ssb, CharacterStyle style) {
ArrayList<Integer> toremove = new ArrayList<Integer>();
while ( m.find() ) {
toremove.add(0, m.start());
// Remove the ending control character unless it's \x0F
if( m.group(2) != null && m.group(2) != m.group(3) ) {
toremove.add(0, m.end() - 1);
}
ssb.setSpan(style, m.start(), m.end(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
for( Integer i : toremove ) {
ssb.delete(i, i + 1);
}
}
private static void endSpan(SpannableStringBuilder text) {
int len = text.length();
Object obj = getLast(text, Href.class);
int where = text.getSpanStart(obj);
text.removeSpan(obj);
if (where != len) {
if (isEmoji) {
text.delete(where, len);
return;
}
Href h = (Href) obj;
if (h != null && h.mHref != null) {
if (ZulipApp.get().getEmail().equals(h.mHref)) {
text.setSpan(new ForegroundColorSpan(userMentionSelfColor), where, len, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
} else {
text.setSpan(new ProfileSpan(h.mHref, userMentionColor), where, len, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
}
}
@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<String, String> 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;
}
String getCopyReadyComment(CharSequence text, int start, int end) {
if (text instanceof Spanned) {
SpannableStringBuilder builder = new SpannableStringBuilder(text.subSequence(start, end));
LinkSuffixSpan[] spans = builder.getSpans(0, builder.length(), LinkSuffixSpan.class);
if (spans != null && spans.length > 0) {
for (LinkSuffixSpan span : spans) {
int spanStart = builder.getSpanStart(span);
int spanEnd = builder.getSpanEnd(span);
builder.delete(spanStart, spanEnd);
}
}
return builder.toString();
} else {
return text.subSequence(start, end).toString();
}
}
/**
* Removes mIRC color and style codes and returns the message without them.
*
* @param text A message with mirc colors and styles.
* @return The same message with all the colors and styles removed.
*/
public static SpannableStringBuilder removeStyleAndColors(SpannableStringBuilder text) {
ArrayList<int[]> toremove = new ArrayList<int[]>();
Matcher m = cleanupPattern.matcher(text);
while ( m.find() ) {
toremove.add(0, new int[]{m.start(), m.end()});
}
for( int[] i : toremove ) {
text.delete(i[0], i[1]);
}
return text;
}
@Override
public boolean code(Line line) {
line = line.get();
SpannableStringBuilder builder = (SpannableStringBuilder) line.getStyle();
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;
}
/**
* Returns the hierarchy of groups to which the question belongs.
*/
private SpannableStringBuilder deriveGroupText(FormEntryCaption[] groups) {
SpannableStringBuilder s = new SpannableStringBuilder("");
String t;
String m;
int i;
// list all groups in one string
for (FormEntryCaption g : groups) {
i = g.getMultiplicity() + 1;
t = g.getLongText();
m = g.getMarkdownText();
if (m != null) {
Spannable markdownSpannable = MarkupUtil.returnMarkdown(getContext(), m);
s.append(markdownSpannable);
} else if (t != null && !t.trim().equals("")) {
s.append(t);
} else {
continue;
}
if (g.repeats() && i > 0) {
s.append(" (").append(String.valueOf(i)).append(")");
}
s.append(" > ");
}
//remove the trailing " > "
if (s.length() > 0) {
s.delete(s.length() - 2, s.length());
}
return s;
}
/**
* Parse the given input using {@link TouchableUrlSpan}s rather than vanilla {@link URLSpan}s
* so that they respond to touch.
*/
public static SpannableStringBuilder parseHtml(
String input,
ColorStateList linkTextColor,
@ColorInt int linkHighlightColor) {
SpannableStringBuilder spanned = fromHtml(input);
// strip any trailing newlines
while (spanned.charAt(spanned.length() - 1) == '\n') {
spanned = spanned.delete(spanned.length() - 1, spanned.length());
}
return linkifyPlainLinks(spanned, linkTextColor, linkHighlightColor);
}
private void setupUrls(SpannableStringBuilder stringBuilder) {
Matcher matcher = OrgNodeUtils.urlPattern.matcher(stringBuilder);
int currentIndex = 0;
while(matcher.find(currentIndex)) {
int beginIndex = matcher.start();
final String url = matcher.group(1) != null ? matcher.group(1) : matcher.group(3);
String alias = matcher.group(2) != null ? matcher.group(2) : url;
stringBuilder.delete(matcher.start(), matcher.end());
currentIndex = beginIndex + alias.length();
stringBuilder.insert(beginIndex, alias);
ClickableSpan clickable = new ClickableSpan() {
public void onClick(View view) {
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
try {
Application.getInstace().getApplicationContext().startActivity(intent);
} catch (ActivityNotFoundException ex) {
ex.printStackTrace();
}
}
};
stringBuilder.setSpan(clickable, beginIndex, currentIndex, 0);
matcher = OrgNodeUtils.urlPattern.matcher(stringBuilder);
}
}
private SpannableStringBuilder cleanUpText(SpannableStringBuilder builder) {
// Having joined the text elements, we need to do some final cleanup on the result.
// 1. Collapse multiple consecutive spaces into a single space.
int builderLength = builder.length();
for (int i = 0; i < builderLength; i++) {
if (builder.charAt(i) == ' ') {
int j = i + 1;
while (j < builder.length() && builder.charAt(j) == ' ') {
j++;
}
int spacesToDelete = j - (i + 1);
if (spacesToDelete > 0) {
builder.delete(i, i + spacesToDelete);
builderLength -= spacesToDelete;
}
}
}
// 2. Remove any spaces from the start of each line.
if (builderLength > 0 && builder.charAt(0) == ' ') {
builder.delete(0, 1);
builderLength--;
}
for (int i = 0; i < builderLength - 1; i++) {
if (builder.charAt(i) == '\n' && builder.charAt(i + 1) == ' ') {
builder.delete(i + 1, i + 2);
builderLength--;
}
}
// 3. Remove any spaces from the end of each line.
if (builderLength > 0 && builder.charAt(builderLength - 1) == ' ') {
builder.delete(builderLength - 1, builderLength);
builderLength--;
}
for (int i = 0; i < builderLength - 1; i++) {
if (builder.charAt(i) == ' ' && builder.charAt(i + 1) == '\n') {
builder.delete(i, i + 1);
builderLength--;
}
}
// 4. Trim a trailing newline, if there is one.
if (builderLength > 0 && builder.charAt(builderLength - 1) == '\n') {
builder.delete(builderLength - 1, builderLength);
/*builderLength--;*/
}
return builder;
}
/**
* Applies QuoteSpan to group of lines which starts with > or » characters.
* Appends likebreaks and applies DividerSpan to them to show a padding between quote and text.
*/
private boolean handleTextQuotes(SpannableStringBuilder body, boolean darkBackground) {
boolean startsWithQuote = false;
char previous = '\n';
int lineStart = -1;
int lineTextStart = -1;
int quoteStart = -1;
for (int i = 0; i <= body.length(); i++) {
char current = body.length() > i ? body.charAt(i) : '\n';
if (lineStart == -1) {
if (previous == '\n') {
if ((current == '>' && UIHelper.isPositionFollowedByQuoteableCharacter(body, i))
|| current == '\u00bb' && !UIHelper.isPositionFollowedByQuote(body, i)) {
// Line start with quote
lineStart = i;
if (quoteStart == -1) quoteStart = i;
if (i == 0) startsWithQuote = true;
} else if (quoteStart >= 0) {
// Line start without quote, apply spans there
applyQuoteSpan(body, quoteStart, i - 1, darkBackground);
quoteStart = -1;
}
}
} else {
// Remove extra spaces between > and first character in the line
// > character will be removed too
if (current != ' ' && lineTextStart == -1) {
lineTextStart = i;
}
if (current == '\n') {
body.delete(lineStart, lineTextStart);
i -= lineTextStart - lineStart;
if (i == lineStart) {
// Avoid empty lines because span over empty line can be hidden
body.insert(i++, " ");
}
lineStart = -1;
lineTextStart = -1;
}
}
previous = current;
}
if (quoteStart >= 0) {
// Apply spans to finishing open quote
applyQuoteSpan(body, quoteStart, body.length(), darkBackground);
}
return startsWithQuote;
}
private SpannableStringBuilder cleanUpText(SpannableStringBuilder builder) {
// Having joined the text elements, we need to do some final cleanup on the result.
// 1. Collapse multiple consecutive spaces into a single space.
int builderLength = builder.length();
for (int i = 0; i < builderLength; i++) {
if (builder.charAt(i) == ' ') {
int j = i + 1;
while (j < builder.length() && builder.charAt(j) == ' ') {
j++;
}
int spacesToDelete = j - (i + 1);
if (spacesToDelete > 0) {
builder.delete(i, i + spacesToDelete);
builderLength -= spacesToDelete;
}
}
}
// 2. Remove any spaces from the start of each line.
if (builderLength > 0 && builder.charAt(0) == ' ') {
builder.delete(0, 1);
builderLength--;
}
for (int i = 0; i < builderLength - 1; i++) {
if (builder.charAt(i) == '\n' && builder.charAt(i + 1) == ' ') {
builder.delete(i + 1, i + 2);
builderLength--;
}
}
// 3. Remove any spaces from the end of each line.
if (builderLength > 0 && builder.charAt(builderLength - 1) == ' ') {
builder.delete(builderLength - 1, builderLength);
builderLength--;
}
for (int i = 0; i < builderLength - 1; i++) {
if (builder.charAt(i) == ' ' && builder.charAt(i + 1) == '\n') {
builder.delete(i, i + 1);
builderLength--;
}
}
// 4. Trim a trailing newline, if there is one.
if (builderLength > 0 && builder.charAt(builderLength - 1) == '\n') {
builder.delete(builderLength - 1, builderLength);
/*builderLength--;*/
}
return builder;
}
private SpannableStringBuilder cleanUpText(SpannableStringBuilder builder) {
// Having joined the text elements, we need to do some final cleanup on the result.
// 1. Collapse multiple consecutive spaces into a single space.
int builderLength = builder.length();
for (int i = 0; i < builderLength; i++) {
if (builder.charAt(i) == ' ') {
int j = i + 1;
while (j < builder.length() && builder.charAt(j) == ' ') {
j++;
}
int spacesToDelete = j - (i + 1);
if (spacesToDelete > 0) {
builder.delete(i, i + spacesToDelete);
builderLength -= spacesToDelete;
}
}
}
// 2. Remove any spaces from the start of each line.
if (builderLength > 0 && builder.charAt(0) == ' ') {
builder.delete(0, 1);
builderLength--;
}
for (int i = 0; i < builderLength - 1; i++) {
if (builder.charAt(i) == '\n' && builder.charAt(i + 1) == ' ') {
builder.delete(i + 1, i + 2);
builderLength--;
}
}
// 3. Remove any spaces from the end of each line.
if (builderLength > 0 && builder.charAt(builderLength - 1) == ' ') {
builder.delete(builderLength - 1, builderLength);
builderLength--;
}
for (int i = 0; i < builderLength - 1; i++) {
if (builder.charAt(i) == ' ' && builder.charAt(i + 1) == '\n') {
builder.delete(i, i + 1);
builderLength--;
}
}
// 4. Trim a trailing newline, if there is one.
if (builderLength > 0 && builder.charAt(builderLength - 1) == '\n') {
builder.delete(builderLength - 1, builderLength);
/*builderLength--;*/
}
return builder;
}
private Spannable cleanDiffText(String diffText) {
String[] lines = diffText.split("\\r?\\n");
SpannableStringBuilder output = new SpannableStringBuilder();
boolean pastHeader = false;
for (String line : lines) {
if (!pastHeader) {
//Filter out unwanted header text
if (line.startsWith("diff --git")) continue;
if (line.startsWith("index")) continue;
if (line.startsWith("+++")) continue;
if (line.startsWith("---")) continue;
if (line.startsWith("old mode")) continue;
if (line.startsWith("new mode")) continue;
if (line.startsWith("new file mode")) continue;
if (line.startsWith("deleted file mode")) continue;
if (line.startsWith("similarity index")) continue;
if (line.startsWith("rename from")) continue;
if (line.startsWith("rename to")) continue;
if (line.startsWith("copy from")) continue;
if (line.startsWith("copy to")) continue;
if (line.startsWith("dissimilarity index")) continue;
}
pastHeader = true;
int outputLength = output.length();
int lineLength = line.length();
//We can remove the "+" and "-" characters from the beginning of the line if we want to
//Currently opting not to for two reasons:
// - People aren't used to it
// - Blank lines aren't highlighted properly
if (line.startsWith("+")) {
output.append(line);
output.setSpan(new ForegroundColorSpan(getResources().getColor(R.color.git_diff_plus)), outputLength, outputLength + lineLength, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
} else if (line.startsWith("-")) {
output.append(line);
output.setSpan(new ForegroundColorSpan(getResources().getColor(R.color.git_diff_minus)), outputLength, outputLength + lineLength, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
} else if (line.startsWith("@@") && line.endsWith("@@")) {
output.append(line);
output.setSpan(new ForegroundColorSpan(getResources().getColor(R.color.git_diff_hunk_header)), outputLength, outputLength + lineLength, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
} else if (line.equals("\\ No newline at end of file")) {
output.append(line);
output.setSpan(new ForegroundColorSpan(getResources().getColor(R.color.git_diff_no_newline)), outputLength, outputLength + lineLength, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
} else if (line.startsWith(" ")) {
//Context lines
output.append(line);
} else {
output.append(line);
}
output.append('\n');
}
//Trim off the trailing newline
return output.length() > 0 ? output.delete(output.length() - 1, output.length()) : output;
}
/**
* Applies QuoteSpan to group of lines which starts with > or » characters.
* Appends likebreaks and applies DividerSpan to them to show a padding between quote and text.
*/
private boolean handleTextQuotes(SpannableStringBuilder body, boolean darkBackground) {
boolean startsWithQuote = false;
char previous = '\n';
int lineStart = -1;
int lineTextStart = -1;
int quoteStart = -1;
for (int i = 0; i <= body.length(); i++) {
char current = body.length() > i ? body.charAt(i) : '\n';
if (lineStart == -1) {
if (previous == '\n') {
if ((current == '>' && UIHelper.isPositionFollowedByQuoteableCharacter(body, i))
|| current == '\u00bb' && !UIHelper.isPositionFollowedByQuote(body, i)) {
// Line start with quote
lineStart = i;
if (quoteStart == -1) quoteStart = i;
if (i == 0) startsWithQuote = true;
} else if (quoteStart >= 0) {
// Line start without quote, apply spans there
applyQuoteSpan(body, quoteStart, i - 1, darkBackground);
quoteStart = -1;
}
}
} else {
// Remove extra spaces between > and first character in the line
// > character will be removed too
if (current != ' ' && lineTextStart == -1) {
lineTextStart = i;
}
if (current == '\n') {
body.delete(lineStart, lineTextStart);
i -= lineTextStart - lineStart;
if (i == lineStart) {
// Avoid empty lines because span over empty line can be hidden
body.insert(i++, " ");
}
lineStart = -1;
lineTextStart = -1;
}
}
previous = current;
}
if (quoteStart >= 0) {
// Apply spans to finishing open quote
applyQuoteSpan(body, quoteStart, body.length(), darkBackground);
}
return startsWithQuote;
}
private SpannableStringBuilder cleanUpText(SpannableStringBuilder builder) {
// Having joined the text elements, we need to do some final cleanup on the result.
// 1. Collapse multiple consecutive spaces into a single space.
int builderLength = builder.length();
for (int i = 0; i < builderLength; i++) {
if (builder.charAt(i) == ' ') {
int j = i + 1;
while (j < builder.length() && builder.charAt(j) == ' ') {
j++;
}
int spacesToDelete = j - (i + 1);
if (spacesToDelete > 0) {
builder.delete(i, i + spacesToDelete);
builderLength -= spacesToDelete;
}
}
}
// 2. Remove any spaces from the start of each line.
if (builderLength > 0 && builder.charAt(0) == ' ') {
builder.delete(0, 1);
builderLength--;
}
for (int i = 0; i < builderLength - 1; i++) {
if (builder.charAt(i) == '\n' && builder.charAt(i + 1) == ' ') {
builder.delete(i + 1, i + 2);
builderLength--;
}
}
// 3. Remove any spaces from the end of each line.
if (builderLength > 0 && builder.charAt(builderLength - 1) == ' ') {
builder.delete(builderLength - 1, builderLength);
builderLength--;
}
for (int i = 0; i < builderLength - 1; i++) {
if (builder.charAt(i) == ' ' && builder.charAt(i + 1) == '\n') {
builder.delete(i, i + 1);
builderLength--;
}
}
// 4. Trim a trailing newline, if there is one.
if (builderLength > 0 && builder.charAt(builderLength - 1) == '\n') {
builder.delete(builderLength - 1, builderLength);
/*builderLength--;*/
}
return builder;
}