class AbbreviationLabel {

    static List<FormattedText> format(List<String> tokens) {
        List<FormattedText> texts = new ArrayList<>(2 + tokens.size());
        for (String token : tokens) {
            // charges
            if (isChargeToken(token)) {
                // charges are superscript
                String sign = Character.toString(norm(token.charAt(0)));
                String coef = token.length() > 1 ? token.substring(1) : "";
                if (sign.equals("-")) sign = MINUS_STRING;
                texts.add(new FormattedText(coef + sign, STYLE_SUPSCRIPT));
            }
            // subscript number after brackets
            else if (token.length() == 1 && isDigit(token.charAt(0)) && !texts.isEmpty() && texts.get(texts.size()-1).text.equals(")")) {
                texts.add(new FormattedText(token, STYLE_SUBSCRIPT));
            }
            else {
                // optional prefix
                int i = findPrefix(ITAL_PREFIX_TRIE, token, 0, 0);
                // find a numeric suffix to subscript
                int j = token.length();
                while (j > 0 && isDigit(token.charAt(j - 1)))
                    j--;
                // check if we have numeric suffix
                if (j > 0 && j < token.length()) {
                    if (i > j) i = 0; // prefix overlaps with suffix so don't use it
                    if (i > 0)
                        texts.add(new FormattedText(token.substring(0, i), STYLE_ITALIC));
                    texts.add(new FormattedText(token.substring(i, j), STYLE_NORMAL));
                    texts.add(new FormattedText(token.substring(j), STYLE_SUBSCRIPT));
                } else {
                    if (i > 0)
                        texts.add(new FormattedText(token.substring(0, i), STYLE_ITALIC));
                    texts.add(new FormattedText(token.substring(i), STYLE_NORMAL));
                }
            }
        }

        return texts;
    }

}