@@ -5,8 +5,32 @@ import eu.siacs.conversations.utils.UIHelper;
public class QuoteHelper {
+
+ public static final char QUOTE_CHAR = '>';
+ public static final char QUOTE_END_CHAR = '<'; // used for one check, not for actual quoting
+ public static final char QUOTE_ALT_CHAR = '»';
+ public static final char QUOTE_ALT_END_CHAR = '«';
+
public static boolean isPositionQuoteCharacter(CharSequence body, int pos){
- return body.charAt(pos) == '>';
+ // second part of logical check actually goes against the logic indicated in the method name, since it also checks for context
+ // but it's very useful
+ return body.charAt(pos) == QUOTE_CHAR || isPositionAltQuoteStart(body, pos);
+ }
+
+ public static boolean isPositionQuoteEndCharacter(CharSequence body, int pos){
+ return body.charAt(pos) == QUOTE_END_CHAR;
+ }
+
+ public static boolean isPositionAltQuoteCharacter (CharSequence body, int pos){
+ return body.charAt(pos) == QUOTE_ALT_CHAR;
+ }
+
+ public static boolean isPositionAltQuoteEndCharacter(CharSequence body, int pos){
+ return body.charAt(pos) == QUOTE_ALT_END_CHAR;
+ }
+
+ public static boolean isPositionAltQuoteStart(CharSequence body, int pos){
+ return isPositionAltQuoteCharacter(body, pos) && !isPositionFollowedByAltQuoteEnd(body, pos);
}
public static boolean isPositionFollowedByQuoteChar(CharSequence body, int pos) {
@@ -19,10 +43,10 @@ public class QuoteHelper {
}
public static boolean isPositionQuoteStart (CharSequence body, int pos){
- return isPositionQuoteCharacter(body, pos)
+ return (isPositionQuoteCharacter(body, pos)
&& isPositionPrecededByPrequote(body, pos)
- && (UIHelper.isPositionFollowedByWhitespace(body, pos)
- || isPositionFollowedByQuoteChar(body, pos));
+ && (UIHelper.isPositionFollowedByQuoteableCharacter(body, pos)
+ || isPositionFollowedByQuoteChar(body, pos)));
}
public static boolean bodyContainsQuoteStart (CharSequence body){
@@ -34,6 +58,24 @@ public class QuoteHelper {
return false;
}
+ public static boolean isPositionFollowedByAltQuoteEnd(CharSequence body, int pos) {
+ if (body.length() <= pos + 1 || Character.isWhitespace(body.charAt(pos + 1))) {
+ return false;
+ }
+ boolean previousWasWhitespace = false;
+ for (int i = pos + 1; i < body.length(); i++) {
+ char c = body.charAt(i);
+ if (c == '\n' || isPositionAltQuoteCharacter(body, i)) {
+ return false;
+ } else if (isPositionAltQuoteEndCharacter(body, i) && !previousWasWhitespace) {
+ return true;
+ } else {
+ previousWasWhitespace = Character.isWhitespace(c);
+ }
+ }
+ return false;
+ }
+
public static boolean isNestedTooDeeply (CharSequence line){
if (isPositionQuoteCharacter(line, 0)) {
int nestingDepth = 1;
@@ -48,4 +90,13 @@ public class QuoteHelper {
}
return false;
}
-}
+
+ public static String replaceAltQuoteCharsInText(String text){
+ for (int i = 0; i < text.length(); i++){
+ if (isPositionAltQuoteStart(text, i)){
+ text = text.substring(0, i) + QUOTE_CHAR + text.substring(i + 1);
+ }
+ }
+ return text;
+ }
+}
@@ -329,7 +329,7 @@ public class UIHelper {
continue;
}
char first = l.charAt(0);
- if ((!QuoteHelper.isPositionQuoteStart(l, 0)) && first != '\u00bb') {
+ if ((!QuoteHelper.isPositionQuoteStart(l, 0))) {
CharSequence line = CharSequenceUtils.trim(l);
if (line.length() == 0) {
continue;
@@ -373,14 +373,6 @@ public class UIHelper {
return input.length() > 256 ? StylingHelper.subSequence(input, 0, 256) : input;
}
- public static boolean isPositionFollowedByWhitespace(CharSequence body, int pos){
- return Character.isWhitespace(body.charAt(pos + 1));
- }
-
- public static boolean isPositionPrecededByWhitespace(CharSequence body, int pos){
- return Character.isWhitespace(body.charAt(pos -1 ));
- }
-
public static boolean isPositionPrecededByBodyStart(CharSequence body, int pos){
// true if not a single linebreak before current position
for (int i = pos - 1; i >= 0; i--){
@@ -395,10 +387,7 @@ public class UIHelper {
if (isPositionPrecededByBodyStart(body, pos)){
return true;
}
- if (body.charAt(pos - 1) == '\n'){
- return true;
- }
- return false;
+ return body.charAt(pos - 1) == '\n';
}
public static boolean isPositionFollowedByQuoteableCharacter(CharSequence body, int pos) {
@@ -442,31 +431,13 @@ public class UIHelper {
final char c = body.charAt(i);
if (Character.isWhitespace(c)) {
return false;
- } else if (c == '<' || c == '>') {
+ } else if (QuoteHelper.isPositionQuoteCharacter(body, pos) || QuoteHelper.isPositionQuoteEndCharacter(body, pos)) {
return body.length() == i + 1 || Character.isWhitespace(body.charAt(i + 1));
}
}
return false;
}
- public static boolean isPositionFollowedByQuote(CharSequence body, int pos) {
- if (body.length() <= pos + 1 || Character.isWhitespace(body.charAt(pos + 1))) {
- return false;
- }
- boolean previousWasWhitespace = false;
- for (int i = pos + 1; i < body.length(); i++) {
- char c = body.charAt(i);
- if (c == '\n' || c == '»') {
- return false;
- } else if (c == '«' && !previousWasWhitespace) {
- return true;
- } else {
- previousWasWhitespace = Character.isWhitespace(c);
- }
- }
- return false;
- }
-
public static String getDisplayName(MucOptions.User user) {
Contact contact = user.getContact();
if (contact != null) {