| /* ==================================================================== |
| Licensed to the Apache Software Foundation (ASF) under one or more |
| contributor license agreements. See the NOTICE file distributed with |
| this work for additional information regarding copyright ownership. |
| The ASF licenses this file to You under the Apache License, Version 2.0 |
| (the "License"); you may not use this file except in compliance with |
| the License. You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| ==================================================================== */ |
| |
| package org.apache.poi.sl.usermodel; |
| |
| import java.util.Locale; |
| |
| public enum AutoNumberingScheme { |
| /** Lowercase alphabetic character enclosed in parentheses. Example: (a), (b), (c), ... */ |
| alphaLcParenBoth(0x0008, 1), |
| /** Uppercase alphabetic character enclosed in parentheses. Example: (A), (B), (C), ... */ |
| alphaUcParenBoth(0x000A, 2), |
| /** Lowercase alphabetic character followed by a closing parenthesis. Example: a), b), c), ... */ |
| alphaLcParenRight(0x0009, 3), |
| /** Uppercase alphabetic character followed by a closing parenthesis. Example: A), B), C), ... */ |
| alphaUcParenRight(0x000B, 4), |
| /** Lowercase Latin character followed by a period. Example: a., b., c., ... */ |
| alphaLcPeriod(0x0000, 5), |
| /** Uppercase Latin character followed by a period. Example: A., B., C., ... */ |
| alphaUcPeriod(0x0001, 6), |
| /** Arabic numeral enclosed in parentheses. Example: (1), (2), (3), ... */ |
| arabicParenBoth(0x000C, 7), |
| /** Arabic numeral followed by a closing parenthesis. Example: 1), 2), 3), ... */ |
| arabicParenRight(0x0002, 8), |
| /** Arabic numeral followed by a period. Example: 1., 2., 3., ... */ |
| arabicPeriod(0x0003, 9), |
| /** Arabic numeral. Example: 1, 2, 3, ... */ |
| arabicPlain(0x000D, 10), |
| /** Lowercase Roman numeral enclosed in parentheses. Example: (i), (ii), (iii), ... */ |
| romanLcParenBoth(0x0004, 11), |
| /** Uppercase Roman numeral enclosed in parentheses. Example: (I), (II), (III), ... */ |
| romanUcParenBoth(0x000E, 12), |
| /** Lowercase Roman numeral followed by a closing parenthesis. Example: i), ii), iii), ... */ |
| romanLcParenRight(0x0005, 13), |
| /** Uppercase Roman numeral followed by a closing parenthesis. Example: I), II), III), .... */ |
| romanUcParenRight(0x000F, 14), |
| /** Lowercase Roman numeral followed by a period. Example: i., ii., iii., ... */ |
| romanLcPeriod(0x0006, 15), |
| /** Uppercase Roman numeral followed by a period. Example: I., II., III., ... */ |
| romanUcPeriod(0x0007, 16), |
| /** Double byte circle numbers. */ |
| circleNumDbPlain(0x0012, 17), |
| /** Wingdings black circle numbers. */ |
| circleNumWdBlackPlain(0x0014, 18), |
| /** Wingdings white circle numbers. */ |
| circleNumWdWhitePlain(0x0013, 19), |
| /** Double-byte Arabic numbers with double-byte period. */ |
| arabicDbPeriod(0x001D, 20), |
| /** Double-byte Arabic numbers. */ |
| arabicDbPlain(0x001C, 21), |
| /** Simplified Chinese with single-byte period. */ |
| ea1ChsPeriod(0x0011, 22), |
| /** Simplified Chinese. */ |
| ea1ChsPlain(0x0010, 23), |
| /** Traditional Chinese with single-byte period. */ |
| ea1ChtPeriod(0x0015, 24), |
| /** Traditional Chinese. */ |
| ea1ChtPlain(0x0014, 25), |
| /** Japanese with double-byte period. */ |
| ea1JpnChsDbPeriod(0x0026, 26), |
| /** Japanese/Korean. */ |
| ea1JpnKorPlain(0x001A, 27), |
| /** Japanese/Korean with single-byte period. */ |
| ea1JpnKorPeriod(0x001B, 28), |
| /** Bidi Arabic 1 (AraAlpha) with ANSI minus symbol. */ |
| arabic1Minus(0x0017, 29), |
| /** Bidi Arabic 2 (AraAbjad) with ANSI minus symbol. */ |
| arabic2Minus(0x0018, 30), |
| /** Bidi Hebrew 2 with ANSI minus symbol. */ |
| hebrew2Minus(0x0019, 31), |
| /** Thai alphabetic character followed by a period. */ |
| thaiAlphaPeriod(0x001E, 32), |
| /** Thai alphabetic character followed by a closing parenthesis. */ |
| thaiAlphaParenRight(0x001F, 33), |
| /** Thai alphabetic character enclosed by parentheses. */ |
| thaiAlphaParenBoth(0x0020, 34), |
| /** Thai numeral followed by a period. */ |
| thaiNumPeriod(0x0021, 35), |
| /** Thai numeral followed by a closing parenthesis. */ |
| thaiNumParenRight(0x0022, 36), |
| /** Thai numeral enclosed in parentheses. */ |
| thaiNumParenBoth(0x0023, 37), |
| /** Hindi alphabetic character followed by a period. */ |
| hindiAlphaPeriod(0x0024, 38), |
| /** Hindi numeric character followed by a period. */ |
| hindiNumPeriod(0x0025, 39), |
| /** Hindi numeric character followed by a closing parenthesis. */ |
| hindiNumParenRight(0x0027, 40), |
| /** Hindi alphabetic character followed by a period. */ |
| hindiAlpha1Period(0x0027, 41); |
| |
| public final int nativeId, ooxmlId; |
| |
| AutoNumberingScheme(int nativeId, int ooxmlId) { |
| this.nativeId = nativeId; |
| this.ooxmlId = ooxmlId; |
| } |
| |
| public static AutoNumberingScheme forNativeID(int nativeId) { |
| for (AutoNumberingScheme ans : values()) { |
| if (ans.nativeId == nativeId) return ans; |
| } |
| return null; |
| } |
| |
| public static AutoNumberingScheme forOoxmlID(int ooxmlId) { |
| for (AutoNumberingScheme ans : values()) { |
| if (ans.ooxmlId == ooxmlId) return ans; |
| } |
| return null; |
| } |
| |
| public String getDescription() { |
| switch (this) { |
| case alphaLcPeriod : return "Lowercase Latin character followed by a period. Example: a., b., c., ..."; |
| case alphaUcPeriod : return "Uppercase Latin character followed by a period. Example: A., B., C., ..."; |
| case arabicParenRight : return "Arabic numeral followed by a closing parenthesis. Example: 1), 2), 3), ..."; |
| case arabicPeriod : return "Arabic numeral followed by a period. Example: 1., 2., 3., ..."; |
| case romanLcParenBoth : return "Lowercase Roman numeral enclosed in parentheses. Example: (i), (ii), (iii), ..."; |
| case romanLcParenRight : return "Lowercase Roman numeral followed by a closing parenthesis. Example: i), ii), iii), ..."; |
| case romanLcPeriod : return "Lowercase Roman numeral followed by a period. Example: i., ii., iii., ..."; |
| case romanUcPeriod : return "Uppercase Roman numeral followed by a period. Example: I., II., III., ..."; |
| case alphaLcParenBoth : return "Lowercase alphabetic character enclosed in parentheses. Example: (a), (b), (c), ..."; |
| case alphaLcParenRight : return "Lowercase alphabetic character followed by a closing parenthesis. Example: a), b), c), ..."; |
| case alphaUcParenBoth : return "Uppercase alphabetic character enclosed in parentheses. Example: (A), (B), (C), ..."; |
| case alphaUcParenRight : return "Uppercase alphabetic character followed by a closing parenthesis. Example: A), B), C), ..."; |
| case arabicParenBoth : return "Arabic numeral enclosed in parentheses. Example: (1), (2), (3), ..."; |
| case arabicPlain : return "Arabic numeral. Example: 1, 2, 3, ..."; |
| case romanUcParenBoth : return "Uppercase Roman numeral enclosed in parentheses. Example: (I), (II), (III), ..."; |
| case romanUcParenRight : return "Uppercase Roman numeral followed by a closing parenthesis. Example: I), II), III), ..."; |
| case ea1ChsPlain : return "Simplified Chinese."; |
| case ea1ChsPeriod : return "Simplified Chinese with single-byte period."; |
| case circleNumDbPlain : return "Double byte circle numbers."; |
| case circleNumWdWhitePlain : return "Wingdings white circle numbers."; |
| case circleNumWdBlackPlain : return "Wingdings black circle numbers."; |
| case ea1ChtPlain : return "Traditional Chinese."; |
| case ea1ChtPeriod : return "Traditional Chinese with single-byte period."; |
| case arabic1Minus : return "Bidi Arabic 1 (AraAlpha) with ANSI minus symbol."; |
| case arabic2Minus : return "Bidi Arabic 2 (AraAbjad) with ANSI minus symbol."; |
| case hebrew2Minus : return "Bidi Hebrew 2 with ANSI minus symbol."; |
| case ea1JpnKorPlain : return "Japanese/Korean."; |
| case ea1JpnKorPeriod : return "Japanese/Korean with single-byte period."; |
| case arabicDbPlain : return "Double-byte Arabic numbers."; |
| case arabicDbPeriod : return "Double-byte Arabic numbers with double-byte period."; |
| case thaiAlphaPeriod : return "Thai alphabetic character followed by a period."; |
| case thaiAlphaParenRight : return "Thai alphabetic character followed by a closing parenthesis."; |
| case thaiAlphaParenBoth : return "Thai alphabetic character enclosed by parentheses."; |
| case thaiNumPeriod : return "Thai numeral followed by a period."; |
| case thaiNumParenRight : return "Thai numeral followed by a closing parenthesis."; |
| case thaiNumParenBoth : return "Thai numeral enclosed in parentheses."; |
| case hindiAlphaPeriod : return "Hindi alphabetic character followed by a period."; |
| case hindiNumPeriod : return "Hindi numeric character followed by a period."; |
| case ea1JpnChsDbPeriod : return "Japanese with double-byte period."; |
| case hindiNumParenRight : return "Hindi numeric character followed by a closing parenthesis."; |
| case hindiAlpha1Period : return "Hindi alphabetic character followed by a period."; |
| default : return "Unknown Numbered Scheme"; |
| } |
| } |
| |
| public String format(int value) { |
| String index = formatIndex(value); |
| String cased = formatCase(index); |
| return formatSeperator(cased); |
| } |
| |
| private String formatSeperator(String cased) { |
| String name = name().toLowerCase(Locale.ROOT); |
| if (name.contains("plain")) return cased; |
| if (name.contains("parenright")) return cased+")"; |
| if (name.contains("parenboth")) return "("+cased+")"; |
| if (name.contains("period")) return cased+"."; |
| if (name.contains("minus")) return cased+"-"; // ??? |
| return cased; |
| } |
| |
| private String formatCase(String index) { |
| String name = name().toLowerCase(Locale.ROOT); |
| if (name.contains("lc")) return index.toLowerCase(Locale.ROOT); |
| if (name.contains("uc")) return index.toUpperCase(Locale.ROOT); |
| return index; |
| } |
| |
| private static final String ARABIC_LIST = "0123456789"; |
| private static final String ALPHA_LIST = "abcdefghijklmnopqrstuvwxyz"; |
| private static final String WINGDINGS_WHITE_LIST = |
| "\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089"; |
| private static final String WINGDINGS_BLACK_LIST = |
| "\u008B\u008C\u008D\u008E\u008F\u0090\u0091\u0092\u0093\u0094"; |
| private static final String CIRCLE_DB_LIST = |
| "\u2776\u2777\u2778\u2779\u277A\u277B\u277C\u277D\u277E"; |
| |
| private String formatIndex(int value) { |
| String name = name().toLowerCase(Locale.ROOT); |
| if (name.startsWith("roman")) { |
| return formatRomanIndex(value); |
| } else if (name.startsWith("arabic") && !name.contains("db")) { |
| return getIndexedList(value, ARABIC_LIST, false); |
| } else if (name.startsWith("alpha")) { |
| return getIndexedList(value, ALPHA_LIST, true); |
| } else if (name.contains("WdWhite")) { |
| return (value == 10) ? "\u008A" |
| : getIndexedList(value, WINGDINGS_WHITE_LIST, false); |
| } else if (name.contains("WdBlack")) { |
| return (value == 10) ? "\u0095" |
| : getIndexedList(value, WINGDINGS_BLACK_LIST, false); |
| } else if (name.contains("NumDb")) { |
| return (value == 10) ? "\u277F" |
| : getIndexedList(value, CIRCLE_DB_LIST, true); |
| } else { |
| return "?"; |
| } |
| } |
| |
| private static String getIndexedList(int val, String list, boolean oneBased) { |
| StringBuilder sb = new StringBuilder(); |
| addIndexedChar(val, list, oneBased, sb); |
| return sb.toString(); |
| } |
| |
| private static void addIndexedChar(int val, String list, boolean oneBased, StringBuilder sb) { |
| if (oneBased) val -= 1; |
| final int len = list.length(); |
| if (val >= len) { |
| addIndexedChar(val/len, list, oneBased, sb); |
| } |
| sb.append(list.charAt(val%len)); |
| } |
| |
| |
| private String formatRomanIndex(int value) { |
| //M (1000), CM (900), D (500), CD (400), C (100), XC (90), L (50), XL (40), X (10), IX (9), V (5), IV (4) and I (1). |
| final int[] VALUES = new int[]{1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1}; |
| final String[] ROMAN = new String[]{"M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"}; |
| final String[][] conciseList = { |
| {"XLV", "VL"}, //45 |
| {"XCV", "VC"}, //95 |
| {"CDL", "LD"}, //450 |
| {"CML", "LM"}, //950 |
| {"CMVC", "LMVL"}, //995 |
| {"CDXC", "LDXL"}, //490 |
| {"CDVC", "LDVL"}, //495 |
| {"CMXC", "LMXL"}, //990 |
| {"XCIX", "VCIV"}, //99 |
| {"XLIX", "VLIV"}, //49 |
| {"XLIX", "IL"}, //49 |
| {"XCIX", "IC"}, //99 |
| {"CDXC", "XD"}, //490 |
| {"CDVC", "XDV"}, //495 |
| {"CDIC", "XDIX"}, //499 |
| {"LMVL", "XMV"}, //995 |
| {"CMIC", "XMIX"}, //999 |
| {"CMXC", "XM"}, // 990 |
| {"XDV", "VD"}, //495 |
| {"XDIX", "VDIV"}, //499 |
| {"XMV", "VM"}, // 995 |
| {"XMIX", "VMIV"}, //999 |
| {"VDIV", "ID"}, //499 |
| {"VMIV", "IM"} //999 |
| }; |
| |
| StringBuilder sb = new StringBuilder(); |
| for (int i = 0; i < 13; i++) { |
| while (value >= VALUES[i]) { |
| value -= VALUES[i]; |
| sb.append(ROMAN[i]); |
| } |
| } |
| String result = sb.toString(); |
| for (String[] cc : conciseList) { |
| result = result.replace(cc[0], cc[1]); |
| } |
| return result; |
| } |
| } |