https://github.com/manferlo81/gen-unit
A generic unit parser/formatter
https://github.com/manferlo81/gen-unit
format formatter generic parse parser unit units
Last synced: about 1 year ago
JSON representation
A generic unit parser/formatter
- Host: GitHub
- URL: https://github.com/manferlo81/gen-unit
- Owner: manferlo81
- License: mit
- Created: 2019-10-23T08:41:54.000Z (over 6 years ago)
- Default Branch: main
- Last Pushed: 2025-03-13T01:48:01.000Z (over 1 year ago)
- Last Synced: 2025-03-13T02:34:00.719Z (over 1 year ago)
- Topics: format, formatter, generic, parse, parser, unit, units
- Language: TypeScript
- Homepage:
- Size: 2.8 MB
- Stars: 0
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
# gen-unit
[](https://github.com/manferlo81/gen-unit/actions/workflows/ci.yml)
[](https://www.npmjs.com/package/gen-unit)
[](https://codecov.io/gh/manferlo81/gen-unit)
[](https://github.com/manferlo81/gen-unit)
[](https://www.jsdelivr.com/package/npm/gen-unit)
[](https://libraries.io/npm/gen-unit)
[](https://packagephobia.com/result?p=gen-unit)
[](https://bundlephobia.com/result?p=gen-unit)
[](https://github.com/microsoft/typescript)
[](https://snyk.io/test/github/manferlo81/gen-unit?targetFile=package.json)
[](LICENSE)
A generic unit parser/formatter
## Install
```bash
# Using npm
npm i gen-unit
# Using yarn
yarn add gen-unit
```
## API
- `createParser` [function](#the-createparser-function)
- `createParser` [options](#createparser-options)
- `unit` [option](#the-unit-option)
- `match` [option](#the-match-option)
- `match` [option as a RegExp](#match-option-as-a-regexp)
- `match` [option as a string](#match-option-as-a-string)
- `match` [option as a function](#match-option-as-a-function)
- `find` [option](#the-find-option)
- `find` [option as a number](#find-option-as-a-number)
- `find` [option as an array](#find-option-as-an-array)
- `find` [option as an object](#find-option-as-an-object)
- `find` [option as a function](#find-option-as-a-function)
- `createFormatter` [function](#the-createformatter-function)
- `createFormatter` [options](#createformatter-options)
- `unit` [option](#the-unit-option-1)
- `find` [option](#the-find-option-1)
- `find` [option as a number](#find-option-as-a-number-1)
- `find` [option as an array](#find-option-as-an-array-1)
- `find` [option as an object](#find-option-as-an-object-1)
- `find` [option as a function](#find-option-as-a-function-1)
- `round` [option](#the-round-option)
- `round` [option as an object](#round-option-as-an-object)
- `round` [option as a number](#round-option-as-a-number)
- `round` [option as a function](#round-option-as-a-function)
- `output` [option](#the-output-option)
- `output` [option as an object](#output-option-as-an-object)
- `output` [option as a function](#output-option-as-a-function)
- `parse` [function](#the-parse-function)
- `format` [function](#the-format-function)
- `MICRO` [constant](#the-micro-constant)
### The `createParser` function
Creates a `parse` function using the given [options](#createparser-options).
```typescript
function createParser(options): Parser;
type Parser = (input: unknown) => number;
```
### `createParser` options
#### The `unit` option
Defines the `unit` to be used during parsing.
```typescript
unit: string;
```
***Example***
```typescript
const parse = createParser({
unit: 'g',
});
parse('1'); // => 1
parse('1 g'); // => 1
parse('1 m'); // => 0.001
parse('1 mg'); // => 0.001
parse('1 k'); // => 1000
parse('1 kg'); // => 1000
parse('1 ms'); // => NaN because "s" is not recognized as unit
```
***Precedence***
This option takes precedence over any `prefix` or `prefixed unit`.
***Examples***
```typescript
const parseMeter = createParser({
unit: 'm', // Meter
});
parseMeter('1 m'); // returns 1 (1 meter)
parseMeter('1 mm'); // returns 0.001 (1 millimeter)
```
```typescript
const parseSecond = createParser({
unit: 's' // Seconds
});
parseSecond('1 m'); // returns 0.001 (1 millisecond)
parseSecond('1 ms'); // returns 0.001 (1 millisecond)
```
```typescript
const parse = createParser({
unit: 'eg', // assuming "eg" is the unit... for some reason
});
parse('1 meg'); // => 0.001 (not 1000000), it's interpreted as 1 milli-eg
parse('1 megeg'); // => 1000000, it's interpreted as 1 mega-eg
parse('1 Meg'); // => 1000000, it's interpreted as 1 mega-eg because capital "M" parses as mega
```
#### The `match` option
```typescript
match: RegExp | string | MatchFunction;
type MatchFunction = (input: string) => [value: string, unit: string] | null | undefined;
default /^\s*(-?\d*\.?\d*(?:e[+-]?\d+)?)\s*([a-z\xb5]*)\s*$/i
```
Defines the first step in the `parse` process, it takes the `input` and should turn it into an `array` with `two elements` with the `value`, and the `unit` to be process further down the road, or `null` (or `undefined`) if the `input` can't be parsed.
##### `match` option as a RegExp
```typescript
match: RegExp;
default /^\s*(-?\d*\.?\d*(?:e[+-]?\d+)?)\s*([a-z\xb5]*)\s*$/i
```
A RegExp with `two capturing groups`, the first to be used as `value` and the second as `unit`. If the RegExp has less than `two capturing groups`, parse function will `throw`.
***Example***
```typescript
const parse = createParser({
match: /^\s*([\d.]+)\s*([a-z]*)\s*$/i,
});
parse('1 m'); // => 0.001
parse('1 k'); // => 1000
```
##### `match` option as a string
```typescript
match: string;
```
A string to be used to create a RegExp. It is expected to have `two capturing groups`, the first to be used as `value` and the second as `unit`.
***Example***
```typescript
const parse = createParser({
match: '^\\s*([\\d.]+)\\s*([a-z]*)\\s*$',
});
parse('1 m'); // => 0.001
parse('1 k'); // => 1000
```
##### `match` option as a function
```typescript
match: (input: string) => [value: string, unit: string] | null | undefined;
```
A function which will receive the `input` and should return an `array` of `two elements`, the first to be used as `value` and the second as `unit`, or `null` (or `undefined`) if the input can't be parsed.
***Example***
```typescript
const parse = createParser({
match(input) {
return [input, 'k']
},
});
parse('1'); // => 1000
parse('2'); // => 2000
```
#### The `find` option
The `find` option describes how to find the multiplier which is the `number` by which the parsed value should be multiplied.
##### `find` option as a number
```typescript
find: number;
```
A number to be used as `base` during parsing.
***Example***
```typescript
const parse = createParser({
find: 1024,
});
parse('2'); // => 2
parse('2 k'); // => 2048
parse('2 M'); // => 2097152
parse('2 G'); // => 2147483648
```
##### `find` option as an array
```typescript
find: Array<{ pre: string; exp: number }>;
```
An `array` of `objects` describing `prefixes` and `exponents` to use with the default `base` (1000) to find the `multiplier` to be used during parsing. Every item should have a unique `pre`, if there are duplicates `createParser` will `throw`.
***notes***
Note that `empty prefix` (`{ pre: '', exp: 0 }`) is not necessary, as an `empty prefix` will result in `multiplier = 1`
***Example***
```typescript
const parse = createParser({
find: [
{ pre: 'k', exp: 1 },
{ pre: 'M', exp: 2 },
],
});
parse('1.3'); // => 1.3
parse('1.3 k'); // => 1300
parse('1.3 M'); // => 1300000
parse('1.3 G'); // => NaN because prefix "G" can't be found
```
##### `find` option as an object
```typescript
find: {
base?: number;
items?: Array<{ pre: string; exp: number }>;
};
default: {
base: 1000,
items: [
{ pre: 'a', exp: -6 },
{ pre: 'f', exp: -5 },
{ pre: 'p', exp: -4 },
{ pre: 'n', exp: -3 },
{ pre: 'u', exp: -2 },
{ pre: 'µ', exp: -2 },
{ pre: 'm', exp: -1 },
{ pre: 'k', exp: 1 },
{ pre: 'K', exp: 1 },
{ pre: 'meg', exp: 2 },
{ pre: 'M', exp: 2 },
{ pre: 'G', exp: 3 },
{ pre: 'T', exp: 4 },
{ pre: 'P', exp: 5 },
{ pre: 'E', exp: 6 },
],
}
```
An object describing the `base` and a series of `objects` describing `prefixes` and `exponents` to find the `multiplier` to be used during parsing. Every item in `items` array should have a unique `pre`, if there are duplicates `createParser` will `throw`.
***Notes***
Note that `empty prefix` (`{ pre: '', exp: 0 }`) is not necessary, as an `empty prefix` will result in `multiplier = 1`
***Example***
```typescript
const parse = createParser({
find: {
base: 1024,
items: [
{ pre: 'K', exp: 1 },
{ pre: 'M', exp: 2 },
],
},
});
parse('1'); // => 1
parse('1 K'); // => 1024
parse('1 M'); // => 1048576
parse('1 G'); // => NaN
```
##### `find` option as a function
```typescript
find: (pre: string) => number | null | undefined;
```
A function that should return a non-zero `number` by which the parsed value should be multiplied based on the captured prefix. Return `null` (or `undefined`) if multiplier can't be determined. It will cause the parse function to return `NaN`. If your function returns `zero`, `negative number` or any other invalid multiplier, parse function will throw a `TypeError`.
***Example***
```typescript
const parse = createParser({
find: (unit) => {
if (unit === 'K' || unit === 'k') {
return 1024;
} else if (unit === 'M') {
return 1024 ** 2;
}
// next line can be omitted
// as it will return undefined anyway
return null;
},
});
parse('2'); // => 2
parse('2 k'); // => 2048
parse('2 K'); // => 2048
parse('2 M'); // => 2097152
parse('2 G'); // => NaN
```
***Notes***
Previous version of this library allow this function to return an object `{ mul: number }` containing the multiplier. This behavior has been removed, it will `throw` instead.
### The `createFormatter` function
Creates a `format` function using the given [options](#createformatter-options).
```typescript
function createFormatter(options): Formatter;
type Formatter = (input: number) => string;
```
### `createFormatter` options
#### The `unit` option
A `string` to be used as main `unit` during formatting.
```typescript
unit: string;
```
***Example***
```typescript
const format = createFormatter({
unit: 'm',
});
format(100); // => '100 m'
format(0.0012); // => '1.2 mm'
format(1200); // => '1.2 Km'
```
#### The `find` option
Describes how to find the unit `prefix` and `divider` based on input value.
##### `find` option as a number
```typescript
find: number;
```
A `number` to be used as `base` during formatting.
***Example***
```typescript
const format = createFormatter({
find: 1024,
});
format(100); // => '100'
format(2048); // => '2 k'
format(2097152); // => '2 M'
```
##### `find` option as an array
```typescript
find: Array<{ pre: string; exp: number }>;
```
An `array` of `objects` describing `prefixes` and `exponents` to use with the default `base` (1000) to find the `prefix` and `multiplier` to be used during formatting. Every item should have a unique `exp`, if there are duplicates `createFormatter` will `throw`.
***Example***
```typescript
const format = createFormatter({
find: [
{ exp: 0, pre: '' },
{ exp: 1, pre: 'K' },
],
});
format(2); // => '2'
format(2000); // => '2 K'
format(2000000); // => '2000 K'
```
##### `find` option as an object
```typescript
find: {
base?: number;
items?: Array<{ exp: number; pre: string }>;
}
default: {
base: 1000,
items: [
{ exp: -6, pre: 'a' },
{ exp: -5, pre: 'f' },
{ exp: -4, pre: 'p' },
{ exp: -3, pre: 'n' },
{ exp: -2, pre: 'µ' },
{ exp: -1, pre: 'm' },
{ exp: 0, pre: '' },
{ exp: 1, pre: 'k' },
{ exp: 2, pre: 'M' },
{ exp: 3, pre: 'G' },
{ exp: 4, pre: 'T' },
{ exp: 5, pre: 'P' },
{ exp: 6, pre: 'E' },
],
}
```
An object describing the `base` and a series of `objects` describing `prefixes` and `exponents` to find the `prefix` and `multiplier` to be used during formatting. Every item in `items` array should have a unique `exp`, if there are duplicates `createFormatter` will `throw`.
***Example***
```typescript
const format = createFormatter({
find: {
base: 1024,
items: [
{ exp: 0, pre: '' },
{ exp: 1, pre: 'K' },
],
},
});
format(100); // => '100'
format(2048); // => '2 K'
format(2097152); // => '2048 K'
```
##### `find` option as a function
```typescript
find: (value: number) => { pre: string; mul: number };
```
A `function` that `returns` an `object` describing the unit `prefix` (`pre`) and `multiplier` (`mul`).
***Example***
```typescript
const format = createFormatter({
find: (value) => {
if (value >= 1000) {
return { pre: 'K', mul: 1000 };
} else {
return { pre: '', mul: 1 };
}
},
});
format(0.2); // => '0.2'
format(2); // => '2'
format(2000); // => '2 K'
format(2000000); // => '2000 K'
```
#### The `round` option
Describes how to `round` the output value before final `format`.
##### `round` option as an object
```typescript
round: {
dec?: number;
fixed?: boolean;
};
default: {
dec: 2,
fixed: false,
};
```
An `object` describing how to `round` the value before final format. Describes the number of decimal (`dec`) and whether or not the output should have a fixed number of decimal (`fixed`).
***Example***
```typescript
const format = createFormatter({
round: {
dec: 3,
fixed: true,
},
});
format(1.23); // => '1.230'
format(1230); // => '1.230 k'
format(0.00123); // => '1.230 m'
```
##### `round` option as a number
```typescript
round: number;
```
A `number` defining the number of decimal places to round to.
***Example***
```typescript
const format = createFormatter({
round: 1,
});
format(1.23); // => '1.2'
format(1.28); // => '1.3'
format(1230); // => '1.2 k'
format(0.00123); // => '1.2 m'
```
##### `round` option as a function
```typescript
round: (num: number) => (string | number);
```
A `function` which `returns` the rounded value.
***Example***
```typescript
const format = createFormatter({
round: Math.round,
});
format(1.23); // => '1'
format(1.75); // => '2'
format(1230); // => '1 k'
format(0.00123); // => '1 m'
```
#### The `output` option
Describes the final output format.
```typescript
output: FormatOutputFunction | FormatOutputAdvancedOption;
type FormatOutputFunction = (value: string | number, prefix: string, unit: string) => string;
interface FormatOutputAdvancedOption {
space: string;
}
```
##### `output` option as an object
```typescript
output: {
space?: string;
}
default {
space: ' ';
}
```
***Example***
```typescript
const format = createFormatter({
output: {
space: '-', // unrealistic, for demonstration only
},
})
format(1.23); // => '1.23'
format(1230); // => '1.23-k'
format(0.00123); // => '1.23-m'
```
##### `output` option as a function
A `function` to format the final output.
```typescript
output: (value: string | number, prefix: string, unit: string) => string;
```
***Example***
```typescript
const format = createFormatter({
unit: 'x',
output: (value, pre) => {
// ignore original unit and hardcode one
return `${value}${pre}s`;
},
});
format(1.23); // => '1.23s'
format(1230); // => '1.23ks'
format(0.00123); // => '1.23ms'
```
### The `parse` function
A convenient function to parse an `input` in one step. I will internally call `createParser` then will call the newly created parser. See `createParser` [options](#createparser-options).
```typescript
function parse(input, options): number;
```
### The `format` function
A convenient function to format a `number` in one step. It wil internally call `createFormatter` then will call the newly created formatter. See `createFormatter` [options](#createformatter-options).
```typescript
function format(input, options): string;
```
### The `MICRO` constant
A constant containing the micro symbol ("µ"). Used internally, exported for convenience.
## License
[MIT](LICENSE) © 2019-2024 [Manuel Fernández](https://github.com/manferlo81)