reduce-precision 0.0.2 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +120 -14
- package/package.json +1 -1
- package/lib/format/index.d.ts +0 -16
- package/lib/format/index.js +0 -402
- package/lib/index.d.ts +0 -2
- package/lib/index.js +0 -8
package/README.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# reduce-precision
|
|
2
2
|
|
|
3
|
+
[](https://snyk.io/test/github/ArzDigitalLabs/reduce-precision?targetFile=package.json)
|
|
4
|
+
[](https://travis-ci.org/ArzDigitalLabs/reduce-precision)
|
|
5
|
+
[](https://codecov.io/github/ArzDigitalLabs/reduce-precision?branch=master)
|
|
6
|
+
[](https://codeclimate.com/github/ArzDigitalLabs/reduce-precision)
|
|
7
|
+
[](https://npmjs.org/package/reduce-precision)
|
|
8
|
+
|
|
3
9
|
`reduce-precision` is a versatile JavaScript/TypeScript package for formatting and reducing the precision of numbers, currencies, and percentages. It supports various templates, precision levels, languages, and output formats, making it easy to generate formatted strings for different use cases.
|
|
4
10
|
|
|
5
11
|
## Features
|
|
@@ -21,22 +27,36 @@ You can install `reduce-precision` using npm:
|
|
|
21
27
|
npm install reduce-precision
|
|
22
28
|
```
|
|
23
29
|
|
|
30
|
+
[](https://www.npmjs.com/package/reduce-precision)
|
|
31
|
+
|
|
24
32
|
## Usage
|
|
25
33
|
|
|
26
34
|
### JavaScript (CommonJS)
|
|
27
35
|
|
|
28
36
|
```javascript
|
|
29
|
-
const {
|
|
37
|
+
const { NumberFormatter } = require('reduce-precision');
|
|
38
|
+
|
|
39
|
+
const formatter = new NumberFormatter();
|
|
30
40
|
|
|
31
|
-
|
|
41
|
+
formatter.setLanguage('en', { prefixMarker: 'strong', prefix: 'USD ' });
|
|
42
|
+
|
|
43
|
+
console.log(formatter.toHtmlString(123456789));
|
|
44
|
+
console.log(formatter.format(123456789));
|
|
45
|
+
console.log(formatter.toString(123456789));
|
|
32
46
|
```
|
|
33
47
|
|
|
34
48
|
### TypeScript or ES Modules
|
|
35
49
|
|
|
36
50
|
```typescript
|
|
37
|
-
import {
|
|
51
|
+
import { NumberFormatter } from 'reduce-precision';
|
|
52
|
+
|
|
53
|
+
const formatter = new NumberFormatter();
|
|
38
54
|
|
|
39
|
-
|
|
55
|
+
formatter.setLanguage('en', { prefixMarker: 'strong', prefix: 'USD ' });
|
|
56
|
+
|
|
57
|
+
console.log(formatter.toHtmlString(123456789));
|
|
58
|
+
console.log(formatter.format(123456789));
|
|
59
|
+
console.log(formatter.toString(123456789));
|
|
40
60
|
```
|
|
41
61
|
|
|
42
62
|
## Options
|
|
@@ -57,32 +77,118 @@ The `format` function accepts an optional `options` object with the following pr
|
|
|
57
77
|
## Examples
|
|
58
78
|
|
|
59
79
|
```typescript
|
|
60
|
-
import {
|
|
80
|
+
import { NumberFormatter } from 'reduce-precision';
|
|
81
|
+
|
|
82
|
+
// Create a formatter instance with default options
|
|
83
|
+
const formatter = new NumberFormatter();
|
|
84
|
+
|
|
85
|
+
// Create a formatter instance with custom options
|
|
86
|
+
const formatterWithOptions = new NumberFormatter({
|
|
87
|
+
language: 'fa',
|
|
88
|
+
template: 'irr',
|
|
89
|
+
precision: 'medium',
|
|
90
|
+
prefixMarker: 'strong',
|
|
91
|
+
postfixMarker: 'em',
|
|
92
|
+
prefix: 'مبلغ: ',
|
|
93
|
+
postfix: ' ریال'
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
// Basic usage
|
|
97
|
+
formatter.setLanguage('en');
|
|
61
98
|
|
|
62
99
|
// Basic number formatting
|
|
63
|
-
format(1234.5678); // Output: 1,234.
|
|
100
|
+
formatter.format(1234.5678); // Output: { value: '1,234.6', ... }
|
|
64
101
|
|
|
65
102
|
// Formatting with medium precision
|
|
66
|
-
|
|
103
|
+
formatter.setTemplate('number', 'medium').format(1234.5678); // Output: { value: '1.23K', ... }
|
|
67
104
|
|
|
68
105
|
// Formatting as USD
|
|
69
|
-
|
|
106
|
+
formatter.setTemplate('usd', 'high').format(1234.5678); // Output: { value: '$1,234.6', ... }
|
|
70
107
|
|
|
71
108
|
// Formatting as Iranian Rial with Persian numerals
|
|
72
|
-
format(1234.5678
|
|
109
|
+
formatterWithOptions.format(1234.5678);
|
|
110
|
+
// Output: { value: 'مبلغ: ۱٫۲۳ هزار ت', ... }
|
|
73
111
|
|
|
74
112
|
// Formatting as a percentage with low precision
|
|
75
|
-
|
|
113
|
+
formatter.setTemplate('percent', 'low').format(0.1234); // Output: { value: '0.12%', ... }
|
|
76
114
|
|
|
77
115
|
// Formatting with HTML output and custom markers
|
|
78
|
-
|
|
79
|
-
|
|
116
|
+
|
|
117
|
+
formatter.setLanguage('en', { prefixMarker: 'strong', prefix: 'USD ' }).toHtmlString(1234.5678);
|
|
118
|
+
// Output: <strong>USD </strong>1,234.6
|
|
80
119
|
|
|
81
120
|
// Formatting with string input for small or big numbers
|
|
82
|
-
|
|
83
|
-
|
|
121
|
+
|
|
122
|
+
formatter.setTemplate('usd', 'medium').format("0.00000000000000000000005678521");
|
|
123
|
+
// Output: { value: '$0.0₂₂5678', ... }
|
|
84
124
|
```
|
|
85
125
|
|
|
126
|
+
## API
|
|
127
|
+
|
|
128
|
+
### `FormattedObject` Interface
|
|
129
|
+
|
|
130
|
+
The `FormattedObject` interface represents the structure of the formatted number object returned by the `format` method.
|
|
131
|
+
|
|
132
|
+
```typescript
|
|
133
|
+
interface FormattedObject {
|
|
134
|
+
value: string; // The formatted value as a string
|
|
135
|
+
prefix: string; // The prefix string
|
|
136
|
+
postfix: string; // The postfix string
|
|
137
|
+
sign: string; // The sign of the number (either an empty string or '-')
|
|
138
|
+
wholeNumber: string; // The whole number part of the value
|
|
139
|
+
fractionalPart: string; // The complete fractional part of the value
|
|
140
|
+
fractionalNonZeros: string; // The non-zero digits in the fractional part
|
|
141
|
+
fractionalZerosCount: number; // The count of zeros in the fractional part
|
|
142
|
+
unit: string; // The unit postfix
|
|
143
|
+
}
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### `NumberFormatter` Class
|
|
147
|
+
|
|
148
|
+
#### `constructor(options?: FormatterOptions)`
|
|
149
|
+
|
|
150
|
+
Creates a new instance of the `NumberFormatter` class with optional configuration options.
|
|
151
|
+
|
|
152
|
+
- `options` (optional): An object containing the initial configuration options for the formatter.
|
|
153
|
+
|
|
154
|
+
#### `setLanguage(lang: Language, config?: LanguageConfig): NumberFormatter`
|
|
155
|
+
|
|
156
|
+
Sets the language and optional language configuration for the formatter.
|
|
157
|
+
|
|
158
|
+
- `lang`: The language to be used for formatting (`'en'` for English or `'fa'` for Persian).
|
|
159
|
+
- `config` (optional): An object containing additional language configuration options.
|
|
160
|
+
- `prefixMarker` (optional): The marker for the prefix in HTML or Markdown output (default: `'i'`).
|
|
161
|
+
- `postfixMarker` (optional): The marker for the postfix in HTML or Markdown output (default: `'i'`).
|
|
162
|
+
- `prefix` (optional): The prefix string to be added before the formatted number.
|
|
163
|
+
- `postfix` (optional): The postfix string to be added after the formatted number.
|
|
164
|
+
|
|
165
|
+
Returns the `NumberFormatter` instance for method chaining.
|
|
166
|
+
|
|
167
|
+
#### `setTemplate(template: Template, precision: Precision): NumberFormatter`
|
|
168
|
+
|
|
169
|
+
Sets the template and precision for the formatter.
|
|
170
|
+
|
|
171
|
+
- `template`: The template to be used for formatting (`'number'`, `'usd'`, `'irt'`, `'irr'`, or `'percent'`).
|
|
172
|
+
- `precision`: The precision level for formatting (`'high'`, `'medium'`, `'low'`, or `'auto'`).
|
|
173
|
+
|
|
174
|
+
Returns the `NumberFormatter` instance for method chaining.
|
|
175
|
+
|
|
176
|
+
#### `format(input: string | number): FormattedObject`
|
|
177
|
+
|
|
178
|
+
Formats the input number and returns the formatted object.
|
|
179
|
+
|
|
180
|
+
- `input`: The number to be formatted, either as a string or a number.
|
|
181
|
+
|
|
182
|
+
Returns the formatted object.
|
|
183
|
+
|
|
184
|
+
#### `toHtmlString(): string`
|
|
185
|
+
|
|
186
|
+
Returns the formatted value as an HTML string.
|
|
187
|
+
|
|
188
|
+
#### `toString(): string`
|
|
189
|
+
|
|
190
|
+
Returns the formatted value as a plain string.
|
|
191
|
+
|
|
86
192
|
## TypeScript
|
|
87
193
|
|
|
88
194
|
`reduce-precision` is written in TypeScript and includes type definitions for all exported functions and interfaces.
|
package/package.json
CHANGED
package/lib/format/index.d.ts
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
declare type Template = 'number' | 'usd' | 'irt' | 'irr' | 'percent';
|
|
2
|
-
declare type Precision = 'auto' | 'high' | 'medium' | 'low';
|
|
3
|
-
declare type Language = 'en' | 'fa';
|
|
4
|
-
declare type OutputFormat = 'plain' | 'html' | 'markdown';
|
|
5
|
-
interface Options {
|
|
6
|
-
precision?: Precision;
|
|
7
|
-
template?: Template;
|
|
8
|
-
language?: Language;
|
|
9
|
-
outputFormat?: OutputFormat;
|
|
10
|
-
prefixMarker?: string;
|
|
11
|
-
postfixMarker?: string;
|
|
12
|
-
prefix?: string;
|
|
13
|
-
postfix?: string;
|
|
14
|
-
}
|
|
15
|
-
declare function format(input: string | number, options?: Options): string | number;
|
|
16
|
-
export default format;
|
package/lib/format/index.js
DELETED
|
@@ -1,402 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
function isENotation(input) {
|
|
4
|
-
return /^[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?$/.test(input);
|
|
5
|
-
}
|
|
6
|
-
function convertENotationToRegularNumber(eNotation) {
|
|
7
|
-
const [coefficientStr, exponentStr] = eNotation.toString().split('e');
|
|
8
|
-
const coefficientLength = coefficientStr
|
|
9
|
-
.replace('.', '')
|
|
10
|
-
.replace('-', '').length;
|
|
11
|
-
const exponent = parseFloat(exponentStr);
|
|
12
|
-
const precision = Math.max(coefficientLength - exponent, 1);
|
|
13
|
-
return eNotation.toFixed(precision);
|
|
14
|
-
}
|
|
15
|
-
function format(input, options = {
|
|
16
|
-
precision: 'high',
|
|
17
|
-
template: 'number',
|
|
18
|
-
language: 'en',
|
|
19
|
-
outputFormat: 'plain',
|
|
20
|
-
prefixMarker: 'i',
|
|
21
|
-
postfixMarker: 'i',
|
|
22
|
-
prefix: '',
|
|
23
|
-
postfix: '',
|
|
24
|
-
}) {
|
|
25
|
-
let { precision, template } = options;
|
|
26
|
-
const { language, outputFormat, prefixMarker, postfixMarker, prefix, postfix, } = options;
|
|
27
|
-
if (!input)
|
|
28
|
-
return 0;
|
|
29
|
-
if (!(template === null || template === void 0 ? void 0 : template.match(/^(number|usd|irt|irr|percent)$/g)))
|
|
30
|
-
template = 'number';
|
|
31
|
-
if (isENotation(input.toString())) {
|
|
32
|
-
input = convertENotationToRegularNumber(Number(input));
|
|
33
|
-
}
|
|
34
|
-
// Replace each Persian/Arabic numeral in the string with its English counterpart and strip all non-numeric chars
|
|
35
|
-
let numberString = input
|
|
36
|
-
.toString()
|
|
37
|
-
.replace(/[\u0660-\u0669\u06F0-\u06F9]/g, function (match) {
|
|
38
|
-
return String(match.charCodeAt(0) & 0xf);
|
|
39
|
-
})
|
|
40
|
-
.replace(/[^\d.-]/g, '');
|
|
41
|
-
// Stripping leading zeros and trailing zeros after a decimal point
|
|
42
|
-
numberString = numberString
|
|
43
|
-
.replace(/^0+(?=\d)/g, '')
|
|
44
|
-
.replace(/(?<=\.\d*)0+$|(?<=\.\d)0+\b/g, '');
|
|
45
|
-
const number = Math.abs(Number(numberString));
|
|
46
|
-
let p, d, r, c;
|
|
47
|
-
let f = 0;
|
|
48
|
-
// Auto precision selection
|
|
49
|
-
if (precision === 'auto') {
|
|
50
|
-
if (template.match(/^(usd|irt|irr)$/g)) {
|
|
51
|
-
if (number >= 0.0001 && number < 100000000000) {
|
|
52
|
-
precision = 'high';
|
|
53
|
-
}
|
|
54
|
-
else {
|
|
55
|
-
precision = 'medium';
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
else if (template === 'number') {
|
|
59
|
-
precision = 'medium';
|
|
60
|
-
}
|
|
61
|
-
else if (template === 'percent') {
|
|
62
|
-
precision = 'low';
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
if (precision === 'medium') {
|
|
66
|
-
if (number >= 0 && number < 0.0001) {
|
|
67
|
-
p = 33;
|
|
68
|
-
d = 4;
|
|
69
|
-
r = false;
|
|
70
|
-
c = true;
|
|
71
|
-
}
|
|
72
|
-
else if (number >= 0.0001 && number < 0.001) {
|
|
73
|
-
p = 7;
|
|
74
|
-
d = 4;
|
|
75
|
-
r = false;
|
|
76
|
-
c = false;
|
|
77
|
-
}
|
|
78
|
-
else if (number >= 0.001 && number < 0.01) {
|
|
79
|
-
p = 5;
|
|
80
|
-
d = 3;
|
|
81
|
-
r = false;
|
|
82
|
-
c = false;
|
|
83
|
-
}
|
|
84
|
-
else if (number >= 0.001 && number < 0.1) {
|
|
85
|
-
p = 3;
|
|
86
|
-
d = 2;
|
|
87
|
-
r = false;
|
|
88
|
-
c = false;
|
|
89
|
-
}
|
|
90
|
-
else if (number >= 0.1 && number < 1) {
|
|
91
|
-
p = 1;
|
|
92
|
-
d = 1;
|
|
93
|
-
r = false;
|
|
94
|
-
c = false;
|
|
95
|
-
}
|
|
96
|
-
else if (number >= 1 && number < 10) {
|
|
97
|
-
p = 3;
|
|
98
|
-
d = 3;
|
|
99
|
-
r = false;
|
|
100
|
-
c = false;
|
|
101
|
-
}
|
|
102
|
-
else if (number >= 10 && number < 100) {
|
|
103
|
-
p = 2;
|
|
104
|
-
d = 2;
|
|
105
|
-
r = false;
|
|
106
|
-
c = false;
|
|
107
|
-
}
|
|
108
|
-
else if (number >= 100 && number < 1000) {
|
|
109
|
-
p = 1;
|
|
110
|
-
d = 1;
|
|
111
|
-
r = false;
|
|
112
|
-
c = false;
|
|
113
|
-
}
|
|
114
|
-
else if (number >= 1000) {
|
|
115
|
-
const x = Math.floor(Math.log10(number)) % 3;
|
|
116
|
-
p = 2 - x;
|
|
117
|
-
d = 2 - x;
|
|
118
|
-
r = true;
|
|
119
|
-
c = true;
|
|
120
|
-
}
|
|
121
|
-
else {
|
|
122
|
-
p = 0;
|
|
123
|
-
d = 0;
|
|
124
|
-
r = true;
|
|
125
|
-
c = true;
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
else if (precision === 'low') {
|
|
129
|
-
if (number >= 0 && number < 0.01) {
|
|
130
|
-
p = 2;
|
|
131
|
-
d = 0;
|
|
132
|
-
r = true;
|
|
133
|
-
c = false;
|
|
134
|
-
f = 2;
|
|
135
|
-
}
|
|
136
|
-
else if (number >= 0.01 && number < 0.1) {
|
|
137
|
-
p = 2;
|
|
138
|
-
d = 1;
|
|
139
|
-
r = true;
|
|
140
|
-
c = false;
|
|
141
|
-
}
|
|
142
|
-
else if (number >= 0.1 && number < 1) {
|
|
143
|
-
p = 2;
|
|
144
|
-
d = 2;
|
|
145
|
-
r = true;
|
|
146
|
-
c = false;
|
|
147
|
-
}
|
|
148
|
-
else if (number >= 1 && number < 10) {
|
|
149
|
-
p = 2;
|
|
150
|
-
d = 2;
|
|
151
|
-
r = true;
|
|
152
|
-
c = false;
|
|
153
|
-
f = 2;
|
|
154
|
-
}
|
|
155
|
-
else if (number >= 10 && number < 100) {
|
|
156
|
-
p = 1;
|
|
157
|
-
d = 1;
|
|
158
|
-
r = true;
|
|
159
|
-
c = false;
|
|
160
|
-
f = 1;
|
|
161
|
-
}
|
|
162
|
-
else if (number >= 100 && number < 1000) {
|
|
163
|
-
p = 0;
|
|
164
|
-
d = 0;
|
|
165
|
-
r = true;
|
|
166
|
-
c = false;
|
|
167
|
-
}
|
|
168
|
-
else if (number >= 1000) {
|
|
169
|
-
const x = Math.floor(Math.log10(number)) % 3;
|
|
170
|
-
p = 1 - x;
|
|
171
|
-
d = 1 - x;
|
|
172
|
-
r = true;
|
|
173
|
-
c = true;
|
|
174
|
-
}
|
|
175
|
-
else {
|
|
176
|
-
p = 0;
|
|
177
|
-
d = 0;
|
|
178
|
-
r = true;
|
|
179
|
-
c = true;
|
|
180
|
-
f = 2;
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
else {
|
|
184
|
-
// precision === "high"
|
|
185
|
-
if (number >= 0 && number < 1) {
|
|
186
|
-
p = 33;
|
|
187
|
-
d = 4;
|
|
188
|
-
r = false;
|
|
189
|
-
c = false;
|
|
190
|
-
}
|
|
191
|
-
else if (number >= 1 && number < 10) {
|
|
192
|
-
p = 3;
|
|
193
|
-
d = 3;
|
|
194
|
-
r = true;
|
|
195
|
-
c = false;
|
|
196
|
-
}
|
|
197
|
-
else if (number >= 10 && number < 100) {
|
|
198
|
-
p = 2;
|
|
199
|
-
d = 2;
|
|
200
|
-
r = true;
|
|
201
|
-
c = false;
|
|
202
|
-
}
|
|
203
|
-
else if (number >= 100 && number < 1000) {
|
|
204
|
-
p = 2;
|
|
205
|
-
d = 2;
|
|
206
|
-
r = true;
|
|
207
|
-
c = false;
|
|
208
|
-
}
|
|
209
|
-
else if (number >= 1000 && number < 10000) {
|
|
210
|
-
p = 1;
|
|
211
|
-
d = 1;
|
|
212
|
-
r = true;
|
|
213
|
-
c = false;
|
|
214
|
-
}
|
|
215
|
-
else {
|
|
216
|
-
p = 0;
|
|
217
|
-
d = 0;
|
|
218
|
-
r = true;
|
|
219
|
-
c = false;
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
return reducePrecision(numberString, p, d, r, c, f, template, language, outputFormat, prefixMarker, postfixMarker, prefix, postfix);
|
|
223
|
-
}
|
|
224
|
-
function reducePrecision(numberString, precision = 30, nonZeroDigits = 4, round = false, compress = false, fixedDecimalZeros = 0, template = 'number', language = 'en', outputFormat = 'plain', prefixMarker = 'span', postfixMarker = 'span', prefix = '', postfix = '') {
|
|
225
|
-
if (!numberString)
|
|
226
|
-
return 0;
|
|
227
|
-
numberString = numberString.toString();
|
|
228
|
-
const maxPrecision = 30;
|
|
229
|
-
const maxIntegerDigits = 21;
|
|
230
|
-
const scaleUnits = template.match(/^(number|percent)$/g)
|
|
231
|
-
? {
|
|
232
|
-
'': '',
|
|
233
|
-
K: ' هزار',
|
|
234
|
-
M: ' میلیون',
|
|
235
|
-
B: ' میلیارد',
|
|
236
|
-
T: ' تریلیون',
|
|
237
|
-
Qd: ' کادریلیون',
|
|
238
|
-
Qt: ' کنتیلیون',
|
|
239
|
-
}
|
|
240
|
-
: {
|
|
241
|
-
'': '',
|
|
242
|
-
K: ' هزار ت',
|
|
243
|
-
M: ' میلیون ت',
|
|
244
|
-
B: ' میلیارد ت',
|
|
245
|
-
T: ' همت',
|
|
246
|
-
Qd: ' هزار همت',
|
|
247
|
-
Qt: ' میلیون همت',
|
|
248
|
-
};
|
|
249
|
-
let parts = /^(-)?(\d+)\.?([0]*)(\d*)$/g.exec(numberString);
|
|
250
|
-
if (!parts) {
|
|
251
|
-
return 0;
|
|
252
|
-
}
|
|
253
|
-
const sign = parts[1] || '';
|
|
254
|
-
let wholeNumberStr = parts[2];
|
|
255
|
-
let fractionalZeroStr = parts[3];
|
|
256
|
-
let fractionalNonZeroStr = parts[4];
|
|
257
|
-
let unitPrefix = '';
|
|
258
|
-
let unitPostfix = '';
|
|
259
|
-
if (fractionalZeroStr.length >= maxPrecision) {
|
|
260
|
-
// Number is smaller than maximum precision
|
|
261
|
-
fractionalZeroStr = '0'.padEnd(maxPrecision - 1, '0');
|
|
262
|
-
fractionalNonZeroStr = '1';
|
|
263
|
-
}
|
|
264
|
-
else if (fractionalZeroStr.length + nonZeroDigits > precision) {
|
|
265
|
-
// decrease non-zero digits
|
|
266
|
-
nonZeroDigits = precision - fractionalZeroStr.length;
|
|
267
|
-
if (nonZeroDigits < 1)
|
|
268
|
-
nonZeroDigits = 1;
|
|
269
|
-
}
|
|
270
|
-
else if (wholeNumberStr.length > maxIntegerDigits) {
|
|
271
|
-
wholeNumberStr = '0';
|
|
272
|
-
fractionalZeroStr = '';
|
|
273
|
-
fractionalNonZeroStr = '';
|
|
274
|
-
}
|
|
275
|
-
// compress large numbers
|
|
276
|
-
if (compress && wholeNumberStr.length >= 4) {
|
|
277
|
-
const scaleUnitKeys = Object.keys(scaleUnits);
|
|
278
|
-
let scaledWholeNumber = wholeNumberStr;
|
|
279
|
-
let unitIndex = 0;
|
|
280
|
-
while (+scaledWholeNumber > 999 && unitIndex < scaleUnitKeys.length - 1) {
|
|
281
|
-
scaledWholeNumber = (+scaledWholeNumber / 1000).toFixed(2);
|
|
282
|
-
unitIndex++;
|
|
283
|
-
}
|
|
284
|
-
unitPostfix = scaleUnitKeys[unitIndex];
|
|
285
|
-
parts = /^(-)?(\d+)\.?([0]*)(\d*)$/g.exec(scaledWholeNumber.toString());
|
|
286
|
-
if (!parts) {
|
|
287
|
-
return 0;
|
|
288
|
-
}
|
|
289
|
-
// sign = parts[1] || "";
|
|
290
|
-
wholeNumberStr = parts[2];
|
|
291
|
-
fractionalZeroStr = parts[3];
|
|
292
|
-
fractionalNonZeroStr = parts[4];
|
|
293
|
-
}
|
|
294
|
-
// Truncate the fractional part or round it
|
|
295
|
-
// if (precision > 0 && nonZeroDigits > 0 && fractionalNonZeroStr.length > nonZeroDigits) {
|
|
296
|
-
if (fractionalNonZeroStr.length > nonZeroDigits) {
|
|
297
|
-
if (!round) {
|
|
298
|
-
fractionalNonZeroStr = fractionalNonZeroStr.substring(0, nonZeroDigits);
|
|
299
|
-
}
|
|
300
|
-
else {
|
|
301
|
-
if (parseInt(fractionalNonZeroStr[nonZeroDigits]) < 5) {
|
|
302
|
-
fractionalNonZeroStr = fractionalNonZeroStr.substring(0, nonZeroDigits);
|
|
303
|
-
}
|
|
304
|
-
else {
|
|
305
|
-
fractionalNonZeroStr = (parseInt(fractionalNonZeroStr.substring(0, nonZeroDigits)) + 1).toString();
|
|
306
|
-
// If overflow occurs (e.g., 999 + 1 = 1000), adjust the substring length
|
|
307
|
-
if (fractionalNonZeroStr.length > nonZeroDigits) {
|
|
308
|
-
if (fractionalZeroStr.length > 0) {
|
|
309
|
-
fractionalZeroStr = fractionalZeroStr.substring(0, fractionalZeroStr.length - 1);
|
|
310
|
-
}
|
|
311
|
-
else {
|
|
312
|
-
wholeNumberStr = (Number(wholeNumberStr) + 1).toString();
|
|
313
|
-
fractionalNonZeroStr = fractionalNonZeroStr.substring(1);
|
|
314
|
-
}
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
// Using dex style
|
|
320
|
-
if (compress && fractionalZeroStr !== '' && unitPostfix === '') {
|
|
321
|
-
fractionalZeroStr =
|
|
322
|
-
'0' +
|
|
323
|
-
fractionalZeroStr.length.toString().replace(/\d/g, function (match) {
|
|
324
|
-
return [
|
|
325
|
-
'₀',
|
|
326
|
-
'₁',
|
|
327
|
-
'₂',
|
|
328
|
-
'₃',
|
|
329
|
-
'₄',
|
|
330
|
-
'₅',
|
|
331
|
-
'₆',
|
|
332
|
-
'₇',
|
|
333
|
-
'₈',
|
|
334
|
-
'₉',
|
|
335
|
-
][parseInt(match, 10)];
|
|
336
|
-
});
|
|
337
|
-
}
|
|
338
|
-
let fractionalPartStr = `${fractionalZeroStr}${fractionalNonZeroStr}`;
|
|
339
|
-
fractionalPartStr = fractionalPartStr.substring(0, precision);
|
|
340
|
-
fractionalPartStr = fractionalPartStr.replace(/^(\d*[1-9])0+$/g, '$1');
|
|
341
|
-
// Output Formating, Prefix, Postfix
|
|
342
|
-
if (template === 'usd') {
|
|
343
|
-
unitPrefix = language === 'en' ? '$' : '';
|
|
344
|
-
}
|
|
345
|
-
else if (template === 'irr') {
|
|
346
|
-
if (!unitPostfix)
|
|
347
|
-
unitPostfix = language === 'fa' ? ' ر' : ' R';
|
|
348
|
-
}
|
|
349
|
-
else if (template === 'irt') {
|
|
350
|
-
if (!unitPostfix)
|
|
351
|
-
unitPostfix = language === 'fa' ? ' ت' : ' T';
|
|
352
|
-
}
|
|
353
|
-
else if (template === 'percent') {
|
|
354
|
-
if (language === 'en') {
|
|
355
|
-
unitPostfix += '%';
|
|
356
|
-
}
|
|
357
|
-
else {
|
|
358
|
-
unitPostfix += !unitPostfix ? '٪' : ' درصد';
|
|
359
|
-
}
|
|
360
|
-
}
|
|
361
|
-
unitPrefix = prefix + unitPrefix;
|
|
362
|
-
unitPostfix += postfix;
|
|
363
|
-
if (outputFormat === 'html') {
|
|
364
|
-
if (unitPrefix)
|
|
365
|
-
unitPrefix = `<${prefixMarker}>${unitPrefix}</${prefixMarker}>`;
|
|
366
|
-
if (unitPostfix)
|
|
367
|
-
unitPostfix = `<${postfixMarker}>${unitPostfix}</${postfixMarker}>`;
|
|
368
|
-
}
|
|
369
|
-
else if (outputFormat === 'markdown') {
|
|
370
|
-
if (unitPrefix)
|
|
371
|
-
unitPrefix = `${prefixMarker}${unitPrefix}${prefixMarker}`;
|
|
372
|
-
if (unitPostfix)
|
|
373
|
-
unitPostfix = `${postfixMarker}${unitPostfix}${postfixMarker}`;
|
|
374
|
-
}
|
|
375
|
-
const thousandSeparatorRegex = /\B(?=(\d{3})+(?!\d))/g;
|
|
376
|
-
const fixedDecimalZeroStr = fixedDecimalZeros
|
|
377
|
-
? '.'.padEnd(fixedDecimalZeros + 1, '0')
|
|
378
|
-
: '';
|
|
379
|
-
let out = '';
|
|
380
|
-
if (precision <= 0 || nonZeroDigits <= 0 || !fractionalNonZeroStr) {
|
|
381
|
-
out = `${sign}${unitPrefix}${wholeNumberStr.replace(thousandSeparatorRegex, ',')}${fixedDecimalZeroStr}${unitPostfix}`;
|
|
382
|
-
}
|
|
383
|
-
else {
|
|
384
|
-
out = `${sign}${unitPrefix}${wholeNumberStr.replace(thousandSeparatorRegex, ',')}.${fractionalPartStr}${unitPostfix}`;
|
|
385
|
-
}
|
|
386
|
-
// Convert output to Persian numerals if language is "fa"
|
|
387
|
-
if (language === 'fa') {
|
|
388
|
-
out = out
|
|
389
|
-
.replace(/[0-9]/g, c => String.fromCharCode(c.charCodeAt(0) + 1728))
|
|
390
|
-
.replace(/,/g, '٬')
|
|
391
|
-
.replace(/\./g, '٫')
|
|
392
|
-
.replace(/(K|M|B|T|Qt|Qd)/g, function (c) {
|
|
393
|
-
return String(scaleUnits[c]);
|
|
394
|
-
});
|
|
395
|
-
}
|
|
396
|
-
return out;
|
|
397
|
-
}
|
|
398
|
-
console.log(format(3.1227533815325955e-10, { precision: 'low' }));
|
|
399
|
-
console.log(format(3.1227533815325955e-30, { precision: 'low' }));
|
|
400
|
-
console.log(format(3123123123, { precision: 'low' }));
|
|
401
|
-
console.log(format(2, { precision: 'low' }));
|
|
402
|
-
exports.default = format;
|
package/lib/index.d.ts
DELETED
package/lib/index.js
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.format = void 0;
|
|
7
|
-
const format_1 = __importDefault(require("./format"));
|
|
8
|
-
exports.format = format_1.default;
|