Skip to content

Commit

Permalink
Allow separators in all numeric sequences
Browse files Browse the repository at this point in the history
  • Loading branch information
jakeboone02 committed Jun 12, 2023
1 parent d9ed4b2 commit 323ae19
Show file tree
Hide file tree
Showing 8 changed files with 796 additions and 488 deletions.
3 changes: 2 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{
"editor.formatOnSave": true
"editor.formatOnSave": true,
"prettier.prettierPath": "./node_modules/prettier"
}
8 changes: 4 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
### Changed

- `numericQuantity` is now a named export; there is no default export.
- Parsing logic now accepts/ignores any trailing non-numeric characters, to more closely resemble the behavior of `parseFloat`.
- Parsing logic now accepts/ignores any trailing non-numeric characters, more closely resembling the behavior of `parseFloat`.
- UMD build assigns all exports, including `numericQuantity`, to the global object `NumericQuantity`. Previously, it assigned the main function to the global namespace as `numericQuantity`.

### Added

- Support for comma (`','`) and underscore (`'_'`) separators within the whole number or numerator segments.
- Support for Roman numerals (modern/strict rules), including Unicode code points `U+2160` through `U+217F`.
- Support for Unicode "Fraction Numerator One" code point (`'⅟'`, `U+215F`), which must be followed by a string of pure digit characters (the denominator) to be valid.
- Support for comma (`','`) and underscore (`'_'`) separators within Arabic numeral sequences. If a numeric sequence has a leading or trailing separator, that sequence and everything after it will be ignored.
- Support for Roman numerals with modern, strict rules, including the Unicode code points `U+2160` through `U+217F`.
- Support for Unicode "Fraction Numerator One" code point (`'⅟'`, `U+215F`), which must be followed by a valid numeric sequence (the denominator) to be included in the conversion.
- Named exports of regular expressions, character maps, types, and other internal tools.
- Build with ([tsup](https://tsup.egoist.dev/)).

Expand Down
10 changes: 5 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,14 @@
"pretty-print": "prettier --write *.{mjs,js,ts,json} src/*.*"
},
"devDependencies": {
"@babel/core": "^7.22.1",
"@babel/preset-env": "^7.22.4",
"@babel/preset-typescript": "^7.21.5",
"@babel/core": "^7.22.5",
"@babel/preset-env": "^7.22.5",
"@babel/preset-typescript": "^7.22.5",
"@types/jest": "^29.5.2",
"@types/node": "^20.2.5",
"@types/node": "^20.3.0",
"gh-pages": "^5.0.0",
"jest": "^29.5.0",
"np": "^8.0.2",
"np": "^8.0.3",
"prettier": "^2.8.8",
"prettier-plugin-organize-imports": "^3.2.2",
"tsup": "^6.7.0",
Expand Down
2 changes: 1 addition & 1 deletion src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export const vulgarFractionToAsciiMap: Record<VulgarFraction, string> = {
* numericRegex.exec("2 / 3") // [ "2 / 3", "2", "/ 3", null ]
*/
export const numericRegex =
/^(?=-?\s*\.\d|-?\s*\d+)(-)?\s*((?:\d+[\d,_]*)*)(\.\d+|(\s+\d*\s*)?\s*\/\s*\d+)?(?:\s*[^\.\d\/].*)?/;
/^(?=-?\s*\.\d|-?\s*\d)(-)?\s*((?:\d(?:[\d,_]*\d)?)*)(\.\d(?:[\d,_]*\d)?|(\s+\d(?:[\d,_]*\d)?\s*)?\s*\/\s*\d(?:[\d,_]*\d)?)?(?:\s*[^\.\d\/].*)?/;

/**
* Captures any Unicode vulgar fractions
Expand Down
5 changes: 3 additions & 2 deletions src/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@ import { numericQuantityTests } from './numericQuantityTests';
for (const [title, tests] of Object.entries(numericQuantityTests)) {
it(title, () => {
for (const [arg, expected] of tests) {
const expectation = expect(numericQuantity(arg));
if (isNaN(expected)) {
expect(numericQuantity(arg)).toBeNaN();
expectation.toBeNaN();
} else {
expect(numericQuantity(arg)).toBe(expected);
expectation.toBe(expected);
}
}
});
Expand Down
3 changes: 2 additions & 1 deletion src/numericQuantity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,9 @@ export const numericQuantity = (quantity: string | number) => {
return parseRomanNumerals(quantityAsString);
}

const [, dash, ng1temp, numberGroup2] = regexResult;
const [, dash, ng1temp, ng2temp] = regexResult;
const numberGroup1 = ng1temp.replace(/[,_]/g, '');
const numberGroup2 = ng2temp?.replace(/[,_]/g, '');

// Numerify capture group 1
if (!numberGroup1 && numberGroup2 && numberGroup2.startsWith('.')) {
Expand Down
31 changes: 22 additions & 9 deletions src/numericQuantityTests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,30 @@ export const numericQuantityTests: Record<string, [string | number, number][]> =
['-1_000', -1000],
['1_1 1/2', 11.5],
['1,1 1/2', 11.5],
// TODO: Should separators in the numerator be allowed?
['1_1/22', 0.5],
['1,1/22', 0.5],
['11 1_1/2_2', 11.5],
['11 1,1/2,2', 11.5],
['1.2,3', 1.23],
['1.2_3', 1.23],
['1/2,3', 0.043],
['1/2_3', 0.043],
['1 2/3,4', 1.059],
['1 2/3_4', 1.059],
],
'Invalid/ignored separators': [
['_11 11/22', NaN],
[',11 11/22', NaN],
['11 _11/22', 11],
['11 ,11/22', 11],
['11 11/_22', 11],
['11 11/,22', 11],
['11_ 11/22', 11],
['11, 11/22', 11],
['11 11_/22', 11],
['11 11,/22', 11],
['11 11/22_', 11.5],
['11 11/22,', 11.5],
],
'Trailing invalid characters': [
['1 2 3', 1],
Expand All @@ -64,14 +85,6 @@ export const numericQuantityTests: Record<string, [string | number, number][]> =
['\u215F', 1],
['0 . 1', 0],
['0.1.2', 0.1],
['1.2,3', 1.2],
['1.2_3', 1.2],
['1/2,3', 0.5],
['1/2_3', 0.5],
['1 2/3,4', 1.667],
['1 2/3_4', 1.667],
['11 2_3/45', 11],
['11 2,3/45', 11],
],
Decimals: [
['.9', 0.9],
Expand Down
Loading

0 comments on commit 323ae19

Please sign in to comment.