n2words 1.12.2 → 1.14.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/.eslintrc.json +2 -2
- package/README.md +3 -2
- package/bench.mjs +94 -0
- package/dist/n2words.js +1 -1
- package/examples/node.mjs +10 -0
- package/lib/classes/AbstractLanguage.mjs +151 -0
- package/lib/classes/BaseLanguage.mjs +174 -0
- package/lib/i18n/AR.mjs +19 -9
- package/lib/i18n/AZ.mjs +62 -0
- package/lib/i18n/CZ.mjs +78 -69
- package/lib/i18n/DE.mjs +54 -49
- package/lib/i18n/DK.mjs +56 -50
- package/lib/i18n/EN.mjs +64 -53
- package/lib/i18n/ES.mjs +61 -55
- package/lib/i18n/FA.mjs +74 -63
- package/lib/i18n/FR.mjs +52 -47
- package/lib/i18n/HE.mjs +75 -23
- package/lib/i18n/HR.mjs +82 -70
- package/lib/i18n/HU.mjs +80 -75
- package/lib/i18n/ID.mjs +27 -20
- package/lib/i18n/IT.mjs +26 -17
- package/lib/i18n/KO.mjs +36 -31
- package/lib/i18n/LT.mjs +80 -67
- package/lib/i18n/LV.mjs +68 -57
- package/lib/i18n/NL.mjs +72 -61
- package/lib/i18n/NO.mjs +56 -51
- package/lib/i18n/PL.mjs +79 -67
- package/lib/i18n/PT.mjs +50 -44
- package/lib/i18n/RU.mjs +152 -122
- package/lib/i18n/SR.mjs +82 -70
- package/lib/i18n/TR.mjs +54 -362
- package/lib/i18n/UK.mjs +13 -6
- package/lib/i18n/VI.mjs +31 -24
- package/lib/i18n/ZH.mjs +38 -32
- package/lib/n2words.mjs +33 -103
- package/package.json +18 -11
- package/webpack.config.js +1 -1
- package/lib/classes/N2WordsAbs.mjs +0 -72
- package/lib/classes/N2WordsBase.mjs +0 -105
package/lib/n2words.mjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/* eslint-disable import/max-dependencies */
|
|
2
2
|
import n2wordsAR from './i18n/AR.mjs';
|
|
3
|
+
import n2wordsAZ from './i18n/AZ.mjs';
|
|
3
4
|
import n2wordsCZ from './i18n/CZ.mjs';
|
|
4
5
|
import n2wordsDE from './i18n/DE.mjs';
|
|
5
6
|
import n2wordsDK from './i18n/DK.mjs';
|
|
@@ -26,112 +27,41 @@ import n2wordsUK from './i18n/UK.mjs';
|
|
|
26
27
|
import n2wordsVI from './i18n/VI.mjs';
|
|
27
28
|
import n2wordsZH from './i18n/ZH.mjs';
|
|
28
29
|
|
|
29
|
-
const supportedLanguages = [
|
|
30
|
-
'en',
|
|
31
|
-
'fr',
|
|
32
|
-
'es',
|
|
33
|
-
'de',
|
|
34
|
-
'pt',
|
|
35
|
-
'it',
|
|
36
|
-
'tr',
|
|
37
|
-
'ru',
|
|
38
|
-
'cz',
|
|
39
|
-
'no',
|
|
40
|
-
'dk',
|
|
41
|
-
'pl',
|
|
42
|
-
'uk',
|
|
43
|
-
'lt',
|
|
44
|
-
'lv',
|
|
45
|
-
'ar',
|
|
46
|
-
'he',
|
|
47
|
-
'ko',
|
|
48
|
-
'nl',
|
|
49
|
-
'sr',
|
|
50
|
-
'fa',
|
|
51
|
-
'zh',
|
|
52
|
-
'hu',
|
|
53
|
-
'id',
|
|
54
|
-
'hr',
|
|
55
|
-
'vi',
|
|
56
|
-
];
|
|
57
|
-
|
|
58
30
|
/**
|
|
59
31
|
* Converts a number to written form.
|
|
60
|
-
*
|
|
61
|
-
* @param {number} n The number to convert.
|
|
32
|
+
* @param {number|string} value The number to convert.
|
|
62
33
|
* @param {object} [options={lang: "en"}] User options.
|
|
63
|
-
* @returns {string}
|
|
34
|
+
* @returns {string} Value in written format.
|
|
64
35
|
*/
|
|
65
|
-
export default function(
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
return
|
|
83
|
-
|
|
84
|
-
return
|
|
85
|
-
|
|
86
|
-
return
|
|
87
|
-
|
|
88
|
-
return
|
|
89
|
-
|
|
90
|
-
return
|
|
91
|
-
|
|
92
|
-
return
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
} else if (lang === 'TR') {
|
|
96
|
-
return n2wordsTR(n, options);
|
|
97
|
-
} else if (lang === 'RU') {
|
|
98
|
-
return n2wordsRU(n);
|
|
99
|
-
} else if (lang === 'CZ') {
|
|
100
|
-
return n2wordsCZ(n);
|
|
101
|
-
} else if (lang === 'NO') {
|
|
102
|
-
return n2wordsNO(n);
|
|
103
|
-
} else if (lang === 'DK') {
|
|
104
|
-
return n2wordsDK(n);
|
|
105
|
-
} else if (lang === 'PL') {
|
|
106
|
-
return n2wordsPL(n);
|
|
107
|
-
} else if (lang === 'UK') {
|
|
108
|
-
return n2wordsUK(n);
|
|
109
|
-
} else if (lang === 'LT') {
|
|
110
|
-
return n2wordsLT(n);
|
|
111
|
-
} else if (lang === 'LV') {
|
|
112
|
-
return n2wordsLV(n);
|
|
113
|
-
} else if (lang === 'AR') {
|
|
114
|
-
return n2wordsAR(n);
|
|
115
|
-
} else if (lang === 'HE') {
|
|
116
|
-
// only for numbers <= 9999
|
|
117
|
-
return n2wordsHE(n);
|
|
118
|
-
} else if (lang === 'HR') {
|
|
119
|
-
return n2wordsHR(n);
|
|
120
|
-
} else if (lang === 'HU') {
|
|
121
|
-
return n2wordsHU(n);
|
|
122
|
-
} else if (lang === 'KO') {
|
|
123
|
-
return n2wordsKO(n);
|
|
124
|
-
} else if (lang === 'NL') {
|
|
125
|
-
return n2wordsNL(n, options);
|
|
126
|
-
} else if (lang === 'SR') {
|
|
127
|
-
return n2wordsSR(n);
|
|
128
|
-
} else if (lang === 'FA') {
|
|
129
|
-
return n2wordsFA(n);
|
|
130
|
-
} else if (lang === 'ZH') {
|
|
131
|
-
return n2wordsZH(n);
|
|
132
|
-
} else if (lang === 'VI') {
|
|
133
|
-
return n2wordsVI(n);
|
|
134
|
-
} else {
|
|
135
|
-
return n2wordsEN(n);
|
|
36
|
+
export default function(value, options = {lang: 'en'}) {
|
|
37
|
+
switch (options.lang) {
|
|
38
|
+
case 'en': return n2wordsEN(value);
|
|
39
|
+
case 'fr': return n2wordsFR(value);
|
|
40
|
+
case 'es': return n2wordsES(value);
|
|
41
|
+
case 'de': return n2wordsDE(value);
|
|
42
|
+
case 'pt': return n2wordsPT(value);
|
|
43
|
+
case 'it': return n2wordsIT(value);
|
|
44
|
+
case 'tr': return n2wordsTR(value, options);
|
|
45
|
+
case 'ru': return n2wordsRU(value);
|
|
46
|
+
case 'cz': return n2wordsCZ(value);
|
|
47
|
+
case 'no': return n2wordsNO(value);
|
|
48
|
+
case 'dk': return n2wordsDK(value);
|
|
49
|
+
case 'pl': return n2wordsPL(value);
|
|
50
|
+
case 'uk': return n2wordsUK(value);
|
|
51
|
+
case 'lt': return n2wordsLT(value);
|
|
52
|
+
case 'lv': return n2wordsLV(value);
|
|
53
|
+
case 'ar': return n2wordsAR(value);
|
|
54
|
+
case 'he': return n2wordsHE(value); // only for numbers <= 9999
|
|
55
|
+
case 'ko': return n2wordsKO(value);
|
|
56
|
+
case 'nl': return n2wordsNL(value, options);
|
|
57
|
+
case 'sr': return n2wordsSR(value);
|
|
58
|
+
case 'fa': return n2wordsFA(value);
|
|
59
|
+
case 'zh': return n2wordsZH(value);
|
|
60
|
+
case 'hu': return n2wordsHU(value);
|
|
61
|
+
case 'id': return n2wordsID(value);
|
|
62
|
+
case 'hr': return n2wordsHR(value);
|
|
63
|
+
case 'vi': return n2wordsVI(value);
|
|
64
|
+
case 'az': return n2wordsAZ(value);
|
|
65
|
+
default: throw Error('Unsupported language: ' + value + '.');
|
|
136
66
|
}
|
|
137
67
|
}
|
package/package.json
CHANGED
|
@@ -1,18 +1,22 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "n2words",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.14.0",
|
|
4
4
|
"description": "Convert numbers to words, in multiple languages",
|
|
5
5
|
"main": "dist/n2words.js",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"lint": "eslint --config .eslintrc.json lib/ test/",
|
|
8
8
|
"test": "ava --verbose",
|
|
9
9
|
"coverage": "c8 ava",
|
|
10
|
-
"build": "webpack --config webpack.config.js --progress"
|
|
10
|
+
"build": "webpack --config webpack.config.js --progress",
|
|
11
|
+
"bench": "node bench.mjs"
|
|
11
12
|
},
|
|
12
13
|
"repository": {
|
|
13
14
|
"type": "git",
|
|
14
15
|
"url": "git+https://github.com/forzagreen/n2words.git"
|
|
15
16
|
},
|
|
17
|
+
"engines": {
|
|
18
|
+
"node": "16 || >=18"
|
|
19
|
+
},
|
|
16
20
|
"keywords": [
|
|
17
21
|
"n2words",
|
|
18
22
|
"convert",
|
|
@@ -47,7 +51,8 @@
|
|
|
47
51
|
"hungarian",
|
|
48
52
|
"indonesian",
|
|
49
53
|
"croatian",
|
|
50
|
-
"vietnamese"
|
|
54
|
+
"vietnamese",
|
|
55
|
+
"azerbaijani"
|
|
51
56
|
],
|
|
52
57
|
"author": "Wael TELLAT",
|
|
53
58
|
"license": "MIT",
|
|
@@ -56,19 +61,21 @@
|
|
|
56
61
|
},
|
|
57
62
|
"homepage": "https://github.com/forzagreen/n2words#readme",
|
|
58
63
|
"devDependencies": {
|
|
59
|
-
"@babel/core": "^7.
|
|
60
|
-
"@babel/preset-env": "^7.
|
|
64
|
+
"@babel/core": "^7.21.8",
|
|
65
|
+
"@babel/preset-env": "^7.21.5",
|
|
61
66
|
"ava": "^5.2.0",
|
|
62
67
|
"babel-loader": "^9.1.2",
|
|
63
|
-
"
|
|
64
|
-
"
|
|
65
|
-
"
|
|
68
|
+
"benchmark": "^2.1.4",
|
|
69
|
+
"c8": "^7.13.0",
|
|
70
|
+
"core-js": "^3.30.2",
|
|
71
|
+
"eslint": "^8.40.0",
|
|
66
72
|
"eslint-plugin-ava": "^14.0.0",
|
|
67
73
|
"eslint-plugin-import": "^2.27.5",
|
|
68
|
-
"eslint-plugin-jsdoc": "^
|
|
74
|
+
"eslint-plugin-jsdoc": "^44.2.3",
|
|
69
75
|
"eslint-plugin-node": "^11.1.0",
|
|
70
|
-
"
|
|
71
|
-
"webpack
|
|
76
|
+
"microtime": "^3.1.1",
|
|
77
|
+
"webpack": "^5.82.1",
|
|
78
|
+
"webpack-cli": "^5.1.1"
|
|
72
79
|
},
|
|
73
80
|
"ava": {
|
|
74
81
|
"files": [
|
package/webpack.config.js
CHANGED
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Abstract class that must be inherited by all languages.
|
|
3
|
-
*/
|
|
4
|
-
export default class {
|
|
5
|
-
constructor() {
|
|
6
|
-
this.negativeWord = '';
|
|
7
|
-
this.separatorWord;
|
|
8
|
-
this.zero;
|
|
9
|
-
this.spaceSeparator = ' ';
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Convert a number to cardinal (written) format.
|
|
14
|
-
*
|
|
15
|
-
* @param {number} value The number value to convert to cardinal form.
|
|
16
|
-
* @returns {string} Cardinal representation of number value.
|
|
17
|
-
*/
|
|
18
|
-
toCardinal(value) {
|
|
19
|
-
return value;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
*
|
|
24
|
-
* @param {number} decimalPart Decimal part of the number to convert.
|
|
25
|
-
* @returns {string} Decimal part in written format.
|
|
26
|
-
*/
|
|
27
|
-
toDecimal(decimalPart) {
|
|
28
|
-
let decimalPartArray = Array.from(decimalPart);
|
|
29
|
-
let decimalPartWordsArray = [];
|
|
30
|
-
while (decimalPartArray[0] === '0') {
|
|
31
|
-
// Leading zeros
|
|
32
|
-
decimalPartArray.shift();
|
|
33
|
-
decimalPartWordsArray.push(this.zero);
|
|
34
|
-
}
|
|
35
|
-
decimalPartWordsArray.push(this.toCardinal(parseInt(decimalPart, 10)));
|
|
36
|
-
|
|
37
|
-
return decimalPartWordsArray.join(this.spaceSeparator);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
*
|
|
42
|
-
* @param {number} value Float number.
|
|
43
|
-
* @throws {TypeError} Value must be a valid number.
|
|
44
|
-
* @returns {string|undefined} Cardinal number in written format.
|
|
45
|
-
*/
|
|
46
|
-
floatToCardinal(value) {
|
|
47
|
-
if (isNaN(Number(value))) {
|
|
48
|
-
throw new TypeError(`Invalid number: ${value}, of type: ${typeof value}`);
|
|
49
|
-
}
|
|
50
|
-
value = Number(value);
|
|
51
|
-
let words = [];
|
|
52
|
-
let positiveValue = Math.abs(value);
|
|
53
|
-
if (value % 1 === 0 || typeof this.separatorWord === 'undefined') {
|
|
54
|
-
// if value is integer or if separatorWord is not defined
|
|
55
|
-
words = [this.toCardinal(positiveValue)];
|
|
56
|
-
} else {
|
|
57
|
-
const splittedValue = positiveValue.toString().split('.');
|
|
58
|
-
const wholeNumberStr = this.toCardinal(parseInt(splittedValue[0], 10));
|
|
59
|
-
this.wholeNumberInt = parseInt(splittedValue[0]);
|
|
60
|
-
|
|
61
|
-
let decimalPart = splittedValue[1];
|
|
62
|
-
|
|
63
|
-
const decimalPartStr = this.toDecimal(decimalPart);
|
|
64
|
-
words = [wholeNumberStr, this.separatorWord, decimalPartStr];
|
|
65
|
-
}
|
|
66
|
-
if (value < 0) {
|
|
67
|
-
// negative numbers
|
|
68
|
-
words = [this.negativeWord].concat(words);
|
|
69
|
-
}
|
|
70
|
-
return words.join(this.spaceSeparator);
|
|
71
|
-
}
|
|
72
|
-
}
|
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
import N2WordsAbs from './N2WordsAbs.mjs';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* This class has common functions used by multiple languages (mostly european).
|
|
5
|
-
*/
|
|
6
|
-
export default class extends N2WordsAbs {
|
|
7
|
-
getValueFromCards(elem) {
|
|
8
|
-
// 100
|
|
9
|
-
for (let i = 0; i < this.cards.length; i++) {
|
|
10
|
-
if (Object.prototype.hasOwnProperty.call(this.cards[i], elem)) {
|
|
11
|
-
return this.cards[i][elem];
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
splitNum(value) {
|
|
17
|
-
for (let i = 0; i < this.cards.length; i++) {
|
|
18
|
-
if (this.cards[i][0] == '.') {
|
|
19
|
-
continue;
|
|
20
|
-
}
|
|
21
|
-
const elem = parseInt(Object.keys(this.cards[i])[0], 10); // 100
|
|
22
|
-
if (elem > value) {
|
|
23
|
-
continue;
|
|
24
|
-
}
|
|
25
|
-
const out = [];
|
|
26
|
-
let div;
|
|
27
|
-
let mod;
|
|
28
|
-
if (value == 0) {
|
|
29
|
-
div = 1;
|
|
30
|
-
mod = 0;
|
|
31
|
-
} else {
|
|
32
|
-
div = Math.floor(value / elem);
|
|
33
|
-
mod = value % elem;
|
|
34
|
-
}
|
|
35
|
-
if (div == 1) {
|
|
36
|
-
out.push({
|
|
37
|
-
[this.getValueFromCards(1)]: 1,
|
|
38
|
-
}); // 'one'
|
|
39
|
-
} else {
|
|
40
|
-
if (div == value) {
|
|
41
|
-
return [(div * this.getValueFromCards(elem), div * elem)];
|
|
42
|
-
}
|
|
43
|
-
out.push(this.splitNum(div));
|
|
44
|
-
}
|
|
45
|
-
out.push({
|
|
46
|
-
[this.getValueFromCards(elem)]: elem,
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
if (mod) {
|
|
50
|
-
out.push(this.splitNum(mod));
|
|
51
|
-
}
|
|
52
|
-
return out;
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
scanNum(value) {
|
|
57
|
-
return value.split('').map(v => this.getValueFromCards(parseInt(v, 10)));
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
clean(val) {
|
|
61
|
-
let out = val;
|
|
62
|
-
while (val.length != 1) {
|
|
63
|
-
out = [];
|
|
64
|
-
const left = val[0];
|
|
65
|
-
const right = val[1];
|
|
66
|
-
if (!Array.isArray(left) && !Array.isArray(right)) {
|
|
67
|
-
// both json objects, not arrays
|
|
68
|
-
out.push(this.merge(left, right));
|
|
69
|
-
if (val.slice(2).length > 0) {
|
|
70
|
-
// all but first 2 elems
|
|
71
|
-
out.push(val.slice(2));
|
|
72
|
-
}
|
|
73
|
-
} else {
|
|
74
|
-
for (let i = 0; i < val.length; i++) {
|
|
75
|
-
const elem = val[i];
|
|
76
|
-
if (Array.isArray(elem)) {
|
|
77
|
-
if (elem.length == 1) out.push(elem[0]);
|
|
78
|
-
else out.push(this.clean(elem));
|
|
79
|
-
} else {
|
|
80
|
-
out.push(elem);
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
val = out;
|
|
85
|
-
}
|
|
86
|
-
return out[0];
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
postClean(out0) {
|
|
90
|
-
return out0.trimRight();
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
/**
|
|
94
|
-
* Convert a number to cardinal (written) format.
|
|
95
|
-
*
|
|
96
|
-
* @param {number} value The number value to convert to cardinal form.
|
|
97
|
-
* @returns {string} Cardinal representation of number value.
|
|
98
|
-
*/
|
|
99
|
-
toCardinal(value) {
|
|
100
|
-
const val = this.splitNum(value);
|
|
101
|
-
const preWords = Object.keys(this.clean(val))[0];
|
|
102
|
-
const words = this.postClean(preWords);
|
|
103
|
-
return words;
|
|
104
|
-
}
|
|
105
|
-
}
|