protected static String caseFoldCharset()

in src/prettify/parser/CombinePrefixPattern.java [113:193]


  protected static String caseFoldCharset(String charSet) {
    String[] charsetParts = Util.match(Pattern.compile("\\\\u[0-9A-Fa-f]{4}"
            + "|\\\\x[0-9A-Fa-f]{2}"
            + "|\\\\[0-3][0-7]{0,2}"
            + "|\\\\[0-7]{1,2}"
            + "|\\\\[\\s\\S]"
            + "|-"
            + "|[^-\\\\]"), charSet.substring(1, charSet.length() - 1), true);
    List<List<Integer>> ranges = new ArrayList<List<Integer>>();
    boolean inverse = charsetParts[0] != null && charsetParts[0].equals("^");

    List<String> out = new ArrayList<String>(Arrays.asList(new String[]{"["}));
    if (inverse) {
      out.add("^");
    }

    for (int i = inverse ? 1 : 0, n = charsetParts.length; i < n; ++i) {
      String p = charsetParts[i];
      if (Util.test(Pattern.compile("\\\\[bdsw]", Pattern.CASE_INSENSITIVE), p)) {  // Don't muck with named groups.
        out.add(p);
      } else {
        int start = decodeEscape(p);
        int end;
        if (i + 2 < n && "-".equals(charsetParts[i + 1])) {
          end = decodeEscape(charsetParts[i + 2]);
          i += 2;
        } else {
          end = start;
        }
        ranges.add(Arrays.asList(new Integer[]{start, end}));
        // If the range might intersect letters, then expand it.
        // This case handling is too simplistic.
        // It does not deal with non-latin case folding.
        // It works for latin source code identifiers though.
        if (!(end < 65 || start > 122)) {
          if (!(end < 65 || start > 90)) {
            ranges.add(Arrays.asList(new Integer[]{Math.max(65, start) | 32, Math.min(end, 90) | 32}));
          }
          if (!(end < 97 || start > 122)) {
            ranges.add(Arrays.asList(new Integer[]{Math.max(97, start) & ~32, Math.min(end, 122) & ~32}));
          }
        }
      }
    }

    // [[1, 10], [3, 4], [8, 12], [14, 14], [16, 16], [17, 17]]
    // -> [[1, 12], [14, 14], [16, 17]]
    Collections.sort(ranges, new Comparator<List<Integer>>() {

      @Override
      public int compare(List<Integer> a, List<Integer> b) {
        return a.get(0) != b.get(0) ? (a.get(0) - b.get(0)) : (b.get(1) - a.get(1));
      }
    });
    List<List<Integer>> consolidatedRanges = new ArrayList<List<Integer>>();
//        List<Integer> lastRange = Arrays.asList(new Integer[]{0, 0});
    List<Integer> lastRange = new ArrayList<Integer>(Arrays.asList(new Integer[]{0, 0}));
    for (int i = 0; i < ranges.size(); ++i) {
      List<Integer> range = ranges.get(i);
      if (lastRange.get(1) != null && range.get(0) <= lastRange.get(1) + 1) {
        lastRange.set(1, Math.max(lastRange.get(1), range.get(1)));
      } else {
        // reference of lastRange is added
        consolidatedRanges.add(lastRange = range);
      }
    }

    for (int i = 0; i < consolidatedRanges.size(); ++i) {
      List<Integer> range = consolidatedRanges.get(i);
      out.add(encodeEscape(range.get(0)));
      if (range.get(1) > range.get(0)) {
        if (range.get(1) + 1 > range.get(0)) {
          out.add("-");
        }
        out.add(encodeEscape(range.get(1)));
      }
    }
    out.add("]");

    return Util.join(out);
  }