All Downloads are FREE. Search and download functionalities are using the official Maven repository.

de.undercouch.citeproc.helper.PageRangeFormatter Maven / Gradle / Ivy

package de.undercouch.citeproc.helper;

import de.undercouch.citeproc.bibtex.PageRange;
import org.apache.commons.lang3.StringUtils;

/**
 * Format page ranges according to CSL rules
 * @author Michel Kraemer
 */
public class PageRangeFormatter {
    public static final String DEFAULT_DELIMITER = "\u2013";

    public enum Format {
        CHICAGO15,
        CHICAGO16,
        EXPANDED,
        MINIMAL,
        MINIMAL2
    }

    public static String format(PageRange range, Format format) {
        return format(range, format, DEFAULT_DELIMITER);
    }

    public static String format(PageRange range, Format format, String delimiter) {
        String first = range.getPageFirst();
        String last = range.getPageLast();
        if (first == null || last == null || first.equals(last)) {
            return range.getLiteral().replace("-", delimiter);
        }

        if (last.length() <= first.length()) {
            if (last.length() < first.length()) {
                last = expanded(first, last);
            }
            switch (format) {
                case CHICAGO15:
                    last = chicago15(first, last);
                    break;

                case CHICAGO16:
                    last = chicago16(first, last);
                    break;

                case EXPANDED:
                    // already done above
                    break;

                case MINIMAL:
                    last = minimal(first, last);
                    break;

                case MINIMAL2:
                    last = minimal2(first, last);
                    break;
            }
        }

        return first + delimiter + last;
    }

    private static String expanded(String first, String last) {
        String fp = getAlphabeticPrefix(first);
        String lp = getAlphabeticPrefix(last);
        if (fp != null && lp == null || fp == null && lp != null) {
            return last;
        }
        if (fp != null) {
            if (fp.equals(lp)) {
                last = last.substring(lp.length());
            } else {
                return last;
            }
        }
        return first.substring(0, first.length() - last.length()) + last;
    }

    private static String getAlphabeticPrefix(String str) {
        int i = 0;
        while (i < str.length() && Character.isAlphabetic(str.charAt(i))) ++i;
        if (i == 0 || i == str.length()) {
            return null;
        }
        return str.substring(0, i);
    }

    private static String minimal(String first, String last) {
        int i = 0;
        while (i < first.length() && first.charAt(i) == last.charAt(i)) {
            ++i;
        }
        return last.substring(i);
    }

    private static String minimal2(String first, String last) {
        int i = 0;
        while (i < first.length() - 2 && first.charAt(i) == last.charAt(i)) {
            ++i;
        }
        return StringUtils.stripStart(last.substring(i), "0");
    }

    private static String chicago15(String first, String last) {
        String fp = getAlphabeticPrefix(first);
        String lp = getAlphabeticPrefix(last);
        if (fp != null && lp == null || fp == null && lp != null) {
            return last;
        }
        if (fp != null) {
            if (fp.equals(lp)) {
                first = first.substring(fp.length());
                last = last.substring(lp.length());
            } else {
                return last;
            }
        }

        if (lp == null) {
            lp = "";
        }

        int nFirst;
        int nLast;
        try {
            nFirst = Integer.parseInt(first);
            nLast = Integer.parseInt(last);
        } catch (NumberFormatException e) {
            return lp + last;
        }

        // noinspection StatementWithEmptyBody
        if (nFirst > 1000 && nFirst <= 9999 && nFirst / 100 != nLast / 100) {
            // use all digits
        } else if (nFirst > 100 && nFirst % 100 > 0) {
            last = minimal2(first, last);
        }
        return lp + last;
    }

    private static String chicago16(String first, String last) {
        String fp = getAlphabeticPrefix(first);
        String lp = getAlphabeticPrefix(last);
        if (fp != null && lp == null || fp == null && lp != null) {
            return last;
        }
        if (fp != null) {
            if (fp.equals(lp)) {
                first = first.substring(fp.length());
                last = last.substring(lp.length());
            } else {
                return last;
            }
        }

        if (lp == null) {
            lp = "";
        }

        int nFirst;
        try {
            nFirst = Integer.parseInt(first);
            Integer.parseInt(last);
        } catch (NumberFormatException e) {
            return lp + last;
        }

        if (nFirst > 100 && nFirst % 100 > 0) {
            last = StringUtils.stripStart(minimal2(first, last), "0");
        }
        return lp + last;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy