All files / roosterjs-content-model-dom/lib/modelApi/list getOrderedListNumberStr.ts

100% Statements 26/26
100% Branches 21/21
100% Functions 3/3
100% Lines 23/23

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 791x 1x   1x 1x                                           1x 225x         47x           49x           46x           49x     34x         96x 96x   96x 142x 142x   96x       95x   1235x 1235x 1235x 1235x   95x    
import { getObjectKeys } from '../../domUtils/getObjectKeys';
import { NumberingListType } from '../../constants/NumberingListType';
 
const CharCodeOfA = 65;
const RomanValues: Record<string, number> = {
    M: 1000,
    CM: 900,
    D: 500,
    CD: 400,
    C: 100,
    XC: 90,
    L: 50,
    XL: 40,
    X: 10,
    IX: 9,
    V: 5,
    IV: 4,
    I: 1,
};
 
/**
 * Get the list number for a list item according to list style type and its index number
 * @param styleType The list style number, should be a value of NumberingListType type
 * @param listNumber List number, start from 1
 * @returns A string for this list item. For example, when pass in NumberingListType.LowerAlpha and 2, it returns "b"
 */
export function getOrderedListNumberStr(styleType: number, listNumber: number): string {
    switch (styleType) {
        case NumberingListType.LowerAlpha:
        case NumberingListType.LowerAlphaDash:
        case NumberingListType.LowerAlphaDoubleParenthesis:
        case NumberingListType.LowerAlphaParenthesis:
            return convertDecimalsToAlpha(listNumber, true /*isLowerCase*/);
 
        case NumberingListType.UpperAlpha:
        case NumberingListType.UpperAlphaDash:
        case NumberingListType.UpperAlphaDoubleParenthesis:
        case NumberingListType.UpperAlphaParenthesis:
            return convertDecimalsToAlpha(listNumber, false /*isLowerCase*/);
 
        case NumberingListType.LowerRoman:
        case NumberingListType.LowerRomanDash:
        case NumberingListType.LowerRomanDoubleParenthesis:
        case NumberingListType.LowerRomanParenthesis:
            return convertDecimalsToRoman(listNumber, true /*isLowerCase*/);
 
        case NumberingListType.UpperRoman:
        case NumberingListType.UpperRomanDash:
        case NumberingListType.UpperRomanDoubleParenthesis:
        case NumberingListType.UpperRomanParenthesis:
            return convertDecimalsToRoman(listNumber, false /*isLowerCase*/);
 
        default:
            return listNumber + '';
    }
}
 
function convertDecimalsToAlpha(decimal: number, isLowerCase?: boolean): string {
    let alpha = '';
    decimal--;
 
    while (decimal >= 0) {
        alpha = String.fromCharCode((decimal % 26) + CharCodeOfA) + alpha;
        decimal = Math.floor(decimal / 26) - 1;
    }
    return isLowerCase ? alpha.toLowerCase() : alpha;
}
 
function convertDecimalsToRoman(decimal: number, isLowerCase?: boolean) {
    let romanValue = '';
 
    for (const i of getObjectKeys(RomanValues)) {
        const timesRomanCharAppear = Math.floor(decimal / RomanValues[i]);
        decimal = decimal - timesRomanCharAppear * RomanValues[i];
        romanValue = romanValue + i.repeat(timesRomanCharAppear);
    }
    return isLowerCase ? romanValue.toLocaleLowerCase() : romanValue;
}