|
- import BigNumber from 'bignumber.js';
- import {
- BLANK_DIGIT,
- createBlankDigits,
- deconstructNumeric,
- groupDigits,
- NEGATIVE_SIGN,
- normalizeNumeric,
- Numeric,
- } from '../../utils/numeric';
- import getLatinPowerName from '../../utils/common/latinPowers';
-
- const config = {
- "onesNames": ["zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"],
- "teensNames": ["ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen"],
- "tensNames": ["zero", "ten", "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety"],
- "hundredName": "hundred",
- "thousandName": "thousand",
- "millia": "millia",
- "illion": "illion",
- "hundredsLatinNames": ["", "cen", "duocen", "trecen", "quadringen", "quingen", "sescen", "septingen", "octingen", "nongen"],
- "onesLatinNames": ["", "un", "duo", "tre", "quattuor", "quin", "sex", "septen", "octo", "novem"],
- "tensLatinNames": ["", "dec", "vigin", "trigin", "quadragin", "quinquagin", "sexagin", "septuagin", "octogin", "nonagin"],
- "onesSpecialLatinNames": ["", "m", "b", "tr", "quadr", "quin", "sex", "sep", "oct", "non"],
- "negative": "negative",
- "grouping": 3,
- "latinGrouping": 3
- }
-
- const getGroupIndexName = (index: BigNumber) => {
- if (index.eq(1)) {
- return config.thousandName
- }
-
- const basicIndex = index.dividedToIntegerBy(2)
- const isOdd = false
- const latinPowerName = getLatinPowerName(basicIndex, isOdd, config)
- if (index.mod(2).eq(1)) {
- return [config.thousandName, latinPowerName].join(' ')
- }
-
- return latinPowerName
- }
-
- const getGroupDigitsName = (digitsRaw: string) => {
- const { grouping, onesNames, teensNames, tensNames, hundredName } = config
- const digits = digitsRaw.padStart(grouping, BLANK_DIGIT)
- const [hundreds, tens, ones] = digits.split('').map(s => Number(s))
- const names = []
- if (hundreds !== 0) {
- names.push(onesNames[hundreds])
- names.push(hundredName)
- }
- if (tens === 1) {
- names.push(teensNames[ones])
- } else if (tens > 1) {
- names.push(tensNames[tens])
- if (ones > 0) {
- names.push(onesNames[ones])
- }
- } else {
- if (hundreds !== 0 && ones > 0 || hundreds === 0) {
- names.push(onesNames[ones])
- }
- }
- return names.join(' ')
- }
-
- const getGroupName = (g: [string, BigNumber]) => {
- const [digits, index] = g
- if (index.lt(1)) {
- return getGroupDigitsName(digits)
- }
- return [getGroupDigitsName(digits), getGroupIndexName(index)].join(' ')
- }
-
- type Options = {
- groupSeparator: string
- }
-
- const getLocalizedNumberName = (xRaw: Numeric, options = {} as Partial<Options>) => {
- const {
- groupSeparator = ' '
- } = options
-
- const x = normalizeNumeric(xRaw)
- const { significandDigits, exponent } = deconstructNumeric(x)
- const blankDigits = createBlankDigits(config.grouping)
- const groups = groupDigits(significandDigits, exponent, config.grouping)
-
- if (groups.length === 1) {
- return getGroupName(groups[0])
- }
-
- const base = groups.filter(([digits]) => digits !== blankDigits).map(g => getGroupName(g)).join(groupSeparator)
-
- if (x.startsWith(NEGATIVE_SIGN)) {
- return [config.negative, base].join(' ')
- }
-
- return base
- }
-
- export default getLocalizedNumberName
|