From 8fd3b115a36baa6cb6130ef38247265b8ed6c98e Mon Sep 17 00:00:00 2001 From: TheoryOfNekomata Date: Sat, 19 Aug 2023 03:46:57 +0800 Subject: [PATCH] Fix millia parsing/stringifying Only largest millia should remove prefix when group is 001. --- .../src/systems/en-US/short-count/parse.ts | 4 +-- .../systems/en-US/short-count/stringify.ts | 25 +++++++++++++------ packages/core/test/systems/en-US.test.ts | 5 ++++ packages/example-web/index.html | 16 ++++++------ 4 files changed, 32 insertions(+), 18 deletions(-) diff --git a/packages/core/src/systems/en-US/short-count/parse.ts b/packages/core/src/systems/en-US/short-count/parse.ts index fa6a40a..489a127 100644 --- a/packages/core/src/systems/en-US/short-count/parse.ts +++ b/packages/core/src/systems/en-US/short-count/parse.ts @@ -46,8 +46,8 @@ export const tokenize = (value: string) => ( .replace(/\n+/gs, ' ') .replace(/\s+/g, ' ') .replace( - new RegExp(`${SHORT_MILLIA_ILLION_DELIMITER}${T_AFFIX}${ILLION_SUFFIX}`, 'g'), - `${T_AFFIX}${ILLION_SUFFIX}`, + new RegExp(`${MILLIA_PREFIX}\\${SHORT_MILLIA_DELIMITER}(\\d+)${SHORT_MILLIA_ILLION_DELIMITER}`, 'g'), + (_substring, milliaCount: string) => `${MILLIA_PREFIX}${SHORT_MILLIA_DELIMITER}${milliaCount}`, ) .replace(new RegExp(`${TENS_ONES_SEPARATOR}`, 'g'), ' ') .split(' ') diff --git a/packages/core/src/systems/en-US/short-count/stringify.ts b/packages/core/src/systems/en-US/short-count/stringify.ts index 25ff09d..73ded72 100644 --- a/packages/core/src/systems/en-US/short-count/stringify.ts +++ b/packages/core/src/systems/en-US/short-count/stringify.ts @@ -82,12 +82,16 @@ const makeHundredsName = (hundreds: number, tens: number, ones: number, addTensD * @param longestMilliaCount - Number of millia- groups. * @returns string The millions prefix. */ -const makeMillionsPrefix = (millions: number, longestMilliaCount: GroupPlace) => { - if (longestMilliaCount > 0) { - return MILLIONS_PREFIXES[millions] as MillionsPrefix; +const makeMillionsPrefix = ( + millions: number, + currentMillia: GroupPlace, + longestMilliaCount: GroupPlace, +) => { + if (currentMillia === BigInt(0) && longestMilliaCount === BigInt(0)) { + return MILLIONS_SPECIAL_PREFIXES[millions] as MillionsSpecialPrefix; } - return MILLIONS_SPECIAL_PREFIXES[millions] as MillionsSpecialPrefix; + return MILLIONS_PREFIXES[millions] as MillionsPrefix; }; /** @@ -100,10 +104,11 @@ const makeMillionsPrefix = (millions: number, longestMilliaCount: GroupPlace) => const makeDecillionsPrefix = ( decillions: number, millions: number, + currentMillia: GroupPlace, longestMilliaCount: GroupPlace, ) => { if (decillions === 0) { - return makeMillionsPrefix(millions, longestMilliaCount); + return makeMillionsPrefix(millions, currentMillia, longestMilliaCount); } const onesPrefix = MILLIONS_PREFIXES[millions] as MillionsPrefix; @@ -123,10 +128,11 @@ const makeCentillionsPrefix = ( centillions: number, decillions: number, millions: number, + currentMillia: GroupPlace, longestMilliaCount: GroupPlace, ) => { if (centillions === 0) { - return makeDecillionsPrefix(decillions, millions, longestMilliaCount); + return makeDecillionsPrefix(decillions, millions, currentMillia, longestMilliaCount); } const onesPrefix = MILLIONS_PREFIXES[millions] as MillionsPrefix; @@ -189,11 +195,14 @@ const getGroupName = (place: GroupPlace, shortenMillia: boolean) => { .filter(([groupDigits]) => groupDigits !== EMPTY_GROUP_DIGITS) .map(([groupDigits, groupPlace], _index, millias) => { const [hundreds, tens, ones] = groupDigits.split('').map(Number); + const largestMillia = millias[0][GROUP_PLACE_INDEX]; + const centillionsPrefix = makeCentillionsPrefix( hundreds, tens, ones, - BigInt(millias.length - 1) + groupPlace, + largestMillia, ); if (groupPlace < 1) { @@ -206,7 +215,7 @@ const getGroupName = (place: GroupPlace, shortenMillia: boolean) => { : repeatString(MILLIA_PREFIX, groupPlace) ); - if (groupDigits === '001') { + if (groupDigits === '001' && groupPlace === largestMillia) { return milliaSuffix; } diff --git a/packages/core/test/systems/en-US.test.ts b/packages/core/test/systems/en-US.test.ts index 2da2c7e..2b89bf0 100644 --- a/packages/core/test/systems/en-US.test.ts +++ b/packages/core/test/systems/en-US.test.ts @@ -295,5 +295,10 @@ describe('numerica', () => { expect(parse(shortMillia2)).toBe('1e+3000003'); expect(stringify(parse(shortMillia2), { stringifyGroupsOptions: { shortenMillia: true } })) .toBe(shortMillia2); + + const exp = '1e+3003003'; + const shortMillia3 = 'one millia^2-unmilliatillion'; + expect(stringify(exp, { stringifyGroupsOptions: { shortenMillia: true } })).toBe(shortMillia3); + expect(parse(shortMillia3)).toBe('1e+3003003'); }); }); diff --git a/packages/example-web/index.html b/packages/example-web/index.html index 2c39f99..b83ccbd 100644 --- a/packages/example-web/index.html +++ b/packages/example-web/index.html @@ -150,8 +150,8 @@ const options = { stringify: { - makeGroupOptions: {}, - finalizeOptions: {}, + stringifyGroupsOptions: {}, + mergeTokensOptions: {}, }, parse: { type: 'bigint', @@ -193,19 +193,19 @@ }); addTensDashesCheckbox.addEventListener('change', (e) => { - options.stringify.makeGroupOptions.addTensDashes = e.currentTarget.checked; + options.stringify.stringifyGroupsOptions.addTensDashes = e.currentTarget.checked; numberInput.dispatchEvent(new Event('input')); nameInput.placeholder = createNamePlaceholder(options); }); shortenMilliaCheckbox.addEventListener('change', (e) => { - options.stringify.makeGroupOptions.shortenMillia = e.currentTarget.checked; + options.stringify.stringifyGroupsOptions.shortenMillia = e.currentTarget.checked; numberInput.dispatchEvent(new Event('input')); nameInput.placeholder = createNamePlaceholder(options); }); oneGroupPerLineCheckbox.addEventListener('change', (e) => { - options.stringify.finalizeOptions.oneGroupPerLine = e.currentTarget.checked; + options.stringify.mergeTokensOptions.oneGroupPerLine = e.currentTarget.checked; numberInput.dispatchEvent(new Event('input')); nameInput.placeholder = createNamePlaceholder(options); }); @@ -229,9 +229,9 @@ nameInput.placeholder = createNamePlaceholder(options); }); - options.stringify.makeGroupOptions.addTensDashes = addTensDashesCheckbox.checked; - options.stringify.makeGroupOptions.shortenMillia = shortenMilliaCheckbox.checked; - options.stringify.finalizeOptions.oneGroupPerLine = oneGroupPerLineCheckbox.checked; + options.stringify.stringifyGroupsOptions.addTensDashes = addTensDashesCheckbox.checked; + options.stringify.stringifyGroupsOptions.shortenMillia = shortenMilliaCheckbox.checked; + options.stringify.mergeTokensOptions.oneGroupPerLine = oneGroupPerLineCheckbox.checked; options.stringify.system = systems[localeSelect.value][variantSelect.value]; options.parse.system = systems[localeSelect.value][variantSelect.value]; Array.from(variantSelect.options).forEach((option) => {