QuoteHelper.java

  1package eu.siacs.conversations.ui.util;
  2
  3import eu.siacs.conversations.Config;
  4import eu.siacs.conversations.utils.UIHelper;
  5
  6public class QuoteHelper {
  7
  8
  9    public static final char QUOTE_CHAR = '>';
 10    public static final char QUOTE_END_CHAR = '<'; // used for one check, not for actual quoting
 11    public static final char QUOTE_ALT_CHAR = '»';
 12    public static final char QUOTE_ALT_END_CHAR = '«';
 13
 14    public static boolean isPositionQuoteCharacter(CharSequence body, int pos){
 15        // second part of logical check actually goes against the logic indicated in the method name, since it also checks for context
 16        // but it's very useful
 17        return body.charAt(pos) == QUOTE_CHAR || isPositionAltQuoteStart(body, pos);
 18    }
 19
 20    public static boolean isPositionQuoteEndCharacter(CharSequence body, int pos){
 21        return body.charAt(pos) == QUOTE_END_CHAR;
 22    }
 23
 24    public static boolean isPositionAltQuoteCharacter (CharSequence body, int pos){
 25        return body.charAt(pos) == QUOTE_ALT_CHAR;
 26    }
 27
 28    public static boolean isPositionAltQuoteEndCharacter(CharSequence body, int pos){
 29        return body.charAt(pos) == QUOTE_ALT_END_CHAR;
 30    }
 31
 32    public static boolean isPositionAltQuoteStart(CharSequence body, int pos){
 33        return isPositionAltQuoteCharacter(body, pos) && !isPositionFollowedByAltQuoteEnd(body, pos);
 34    }
 35
 36    public static boolean isPositionFollowedByQuoteChar(CharSequence body, int pos) {
 37        return body.length() > pos + 1 && isPositionQuoteCharacter(body, pos +1 );
 38    }
 39
 40    // 'Prequote' means anything we require or can accept in front of a QuoteChar
 41    public static boolean isPositionPrecededByPrequote(CharSequence body, int pos){
 42        return UIHelper.isPositionPrecededByLineStart(body, pos);
 43    }
 44
 45    public static boolean isPositionQuoteStart (CharSequence body, int pos){
 46        return (isPositionQuoteCharacter(body, pos)
 47                && isPositionPrecededByPrequote(body, pos)
 48                && (UIHelper.isPositionFollowedByQuoteableCharacter(body, pos)
 49                    || isPositionFollowedByQuoteChar(body, pos)));
 50    }
 51
 52    public static boolean bodyContainsQuoteStart (CharSequence body){
 53       for (int i = 0; i < body.length(); i++){
 54            if (isPositionQuoteStart(body, i)){
 55                return true;
 56            }
 57        }
 58        return false;
 59    }
 60
 61    public static boolean isPositionFollowedByAltQuoteEnd(CharSequence body, int pos) {
 62        if (body.length() <= pos + 1 || Character.isWhitespace(body.charAt(pos + 1))) {
 63            return false;
 64        }
 65        boolean previousWasWhitespace = false;
 66        for (int i = pos + 1; i < body.length(); i++) {
 67            char c = body.charAt(i);
 68            if (c == '\n' || isPositionAltQuoteCharacter(body, i)) {
 69                return false;
 70            } else if (isPositionAltQuoteEndCharacter(body, i) && !previousWasWhitespace) {
 71                return true;
 72            } else {
 73                previousWasWhitespace = Character.isWhitespace(c);
 74            }
 75        }
 76        return false;
 77    }
 78
 79    public static boolean isNestedTooDeeply (CharSequence line){
 80        if (isPositionQuoteCharacter(line, 0)) {
 81            int nestingDepth = 1;
 82            for (int i = 1; i < line.length(); i++) {
 83                if (isPositionQuoteCharacter(line, i)) {
 84                    nestingDepth++;
 85                }
 86                if (nestingDepth > (Config.QUOTING_MAX_DEPTH - 1)) {
 87                    return true;
 88                }
 89            }
 90        }
 91        return false;
 92    }
 93
 94    public static String replaceAltQuoteCharsInText(String text){
 95        for (int i = 0; i < text.length(); i++){
 96            if (isPositionAltQuoteStart(text, i)){
 97                text = text.substring(0, i) + QUOTE_CHAR + text.substring(i + 1);
 98            }
 99        }
100        return text;
101    }
102}