n2words 1.24.0 → 2.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 +285 -156
- package/dist/ArabicConverter.js +3 -0
- package/dist/ArabicConverter.js.map +1 -0
- package/dist/AzerbaijaniConverter.js +3 -0
- package/dist/AzerbaijaniConverter.js.map +1 -0
- package/dist/BanglaConverter.js +3 -0
- package/dist/BanglaConverter.js.map +1 -0
- package/dist/BiblicalHebrewConverter.js +3 -0
- package/dist/BiblicalHebrewConverter.js.map +1 -0
- package/dist/CroatianConverter.js +3 -0
- package/dist/CroatianConverter.js.map +1 -0
- package/dist/CzechConverter.js +3 -0
- package/dist/CzechConverter.js.map +1 -0
- package/dist/DanishConverter.js +3 -0
- package/dist/DanishConverter.js.map +1 -0
- package/dist/DutchConverter.js +3 -0
- package/dist/DutchConverter.js.map +1 -0
- package/dist/EnglishConverter.js +3 -0
- package/dist/EnglishConverter.js.map +1 -0
- package/dist/FilipinoConverter.js +3 -0
- package/dist/FilipinoConverter.js.map +1 -0
- package/dist/FrenchBelgiumConverter.js +3 -0
- package/dist/FrenchBelgiumConverter.js.map +1 -0
- package/dist/FrenchConverter.js +3 -0
- package/dist/FrenchConverter.js.map +1 -0
- package/dist/GermanConverter.js +3 -0
- package/dist/GermanConverter.js.map +1 -0
- package/dist/GreekConverter.js +3 -0
- package/dist/GreekConverter.js.map +1 -0
- package/dist/GujaratiConverter.js +3 -0
- package/dist/GujaratiConverter.js.map +1 -0
- package/dist/HebrewConverter.js +3 -0
- package/dist/HebrewConverter.js.map +1 -0
- package/dist/HindiConverter.js +3 -0
- package/dist/HindiConverter.js.map +1 -0
- package/dist/HungarianConverter.js +3 -0
- package/dist/HungarianConverter.js.map +1 -0
- package/dist/IndonesianConverter.js +3 -0
- package/dist/IndonesianConverter.js.map +1 -0
- package/dist/ItalianConverter.js +3 -0
- package/dist/ItalianConverter.js.map +1 -0
- package/dist/JapaneseConverter.js +3 -0
- package/dist/JapaneseConverter.js.map +1 -0
- package/dist/KannadaConverter.js +3 -0
- package/dist/KannadaConverter.js.map +1 -0
- package/dist/KoreanConverter.js +3 -0
- package/dist/KoreanConverter.js.map +1 -0
- package/dist/LatvianConverter.js +3 -0
- package/dist/LatvianConverter.js.map +1 -0
- package/dist/LithuanianConverter.js +3 -0
- package/dist/LithuanianConverter.js.map +1 -0
- package/dist/MalayConverter.js +3 -0
- package/dist/MalayConverter.js.map +1 -0
- package/dist/MarathiConverter.js +3 -0
- package/dist/MarathiConverter.js.map +1 -0
- package/dist/NorwegianBokmalConverter.js +3 -0
- package/dist/NorwegianBokmalConverter.js.map +1 -0
- package/dist/PersianConverter.js +3 -0
- package/dist/PersianConverter.js.map +1 -0
- package/dist/PolishConverter.js +3 -0
- package/dist/PolishConverter.js.map +1 -0
- package/dist/PortugueseConverter.js +3 -0
- package/dist/PortugueseConverter.js.map +1 -0
- package/dist/PunjabiConverter.js +3 -0
- package/dist/PunjabiConverter.js.map +1 -0
- package/dist/RomanianConverter.js +3 -0
- package/dist/RomanianConverter.js.map +1 -0
- package/dist/RussianConverter.js +3 -0
- package/dist/RussianConverter.js.map +1 -0
- package/dist/SerbianCyrillicConverter.js +3 -0
- package/dist/SerbianCyrillicConverter.js.map +1 -0
- package/dist/SerbianLatinConverter.js +3 -0
- package/dist/SerbianLatinConverter.js.map +1 -0
- package/dist/SimplifiedChineseConverter.js +3 -0
- package/dist/SimplifiedChineseConverter.js.map +1 -0
- package/dist/SpanishConverter.js +3 -0
- package/dist/SpanishConverter.js.map +1 -0
- package/dist/SwahiliConverter.js +3 -0
- package/dist/SwahiliConverter.js.map +1 -0
- package/dist/SwedishConverter.js +3 -0
- package/dist/SwedishConverter.js.map +1 -0
- package/dist/TamilConverter.js +3 -0
- package/dist/TamilConverter.js.map +1 -0
- package/dist/TeluguConverter.js +3 -0
- package/dist/TeluguConverter.js.map +1 -0
- package/dist/ThaiConverter.js +3 -0
- package/dist/ThaiConverter.js.map +1 -0
- package/dist/TraditionalChineseConverter.js +3 -0
- package/dist/TraditionalChineseConverter.js.map +1 -0
- package/dist/TurkishConverter.js +3 -0
- package/dist/TurkishConverter.js.map +1 -0
- package/dist/UkrainianConverter.js +3 -0
- package/dist/UkrainianConverter.js.map +1 -0
- package/dist/UrduConverter.js +3 -0
- package/dist/UrduConverter.js.map +1 -0
- package/dist/VietnameseConverter.js +3 -0
- package/dist/VietnameseConverter.js.map +1 -0
- package/dist/n2words.js +3 -2
- package/dist/n2words.js.map +1 -1
- package/lib/classes/abstract-language.d.ts +178 -0
- package/lib/classes/abstract-language.js +192 -185
- package/lib/classes/greedy-scale-language.d.ts +109 -0
- package/lib/classes/greedy-scale-language.js +96 -90
- package/lib/classes/slavic-language.d.ts +148 -0
- package/lib/classes/slavic-language.js +136 -106
- package/lib/classes/south-asian-language.d.ts +70 -0
- package/lib/classes/south-asian-language.js +58 -65
- package/lib/classes/turkic-language.d.ts +26 -0
- package/lib/classes/turkic-language.js +22 -26
- package/lib/languages/ar.d.ts +30 -0
- package/lib/languages/ar.js +49 -133
- package/lib/languages/az.d.ts +12 -0
- package/lib/languages/az.js +7 -23
- package/lib/languages/bn.d.ts +11 -0
- package/lib/languages/bn.js +12 -7
- package/lib/languages/cs.d.ts +88 -0
- package/lib/languages/cs.js +44 -113
- package/lib/languages/da.d.ts +15 -0
- package/lib/languages/da.js +40 -87
- package/lib/languages/de.d.ts +14 -0
- package/lib/languages/de.js +34 -68
- package/lib/languages/el.d.ts +14 -0
- package/lib/languages/el.js +22 -48
- package/lib/languages/en.d.ts +16 -0
- package/lib/languages/en.js +22 -59
- package/lib/languages/es.d.ts +15 -0
- package/lib/languages/es.js +49 -81
- package/lib/languages/fa.d.ts +47 -0
- package/lib/languages/fa.js +90 -73
- package/lib/languages/fil.d.ts +16 -0
- package/lib/languages/fil.js +35 -76
- package/lib/languages/fr-BE.d.ts +11 -0
- package/lib/languages/fr-BE.js +15 -51
- package/lib/languages/fr.d.ts +15 -0
- package/lib/languages/fr.js +33 -72
- package/lib/languages/gu.d.ts +11 -0
- package/lib/languages/gu.js +10 -34
- package/lib/languages/hbo.d.ts +113 -0
- package/lib/languages/hbo.js +251 -0
- package/lib/languages/he.d.ts +80 -0
- package/lib/languages/he.js +41 -164
- package/lib/languages/hi.d.ts +11 -0
- package/lib/languages/hi.js +12 -7
- package/lib/languages/hr.d.ts +80 -0
- package/lib/languages/hr.js +51 -95
- package/lib/languages/hu.d.ts +22 -0
- package/lib/languages/hu.js +35 -53
- package/lib/languages/id.d.ts +37 -0
- package/lib/languages/id.js +29 -44
- package/lib/languages/it.d.ts +37 -0
- package/lib/languages/it.js +36 -52
- package/lib/languages/ja.d.ts +17 -0
- package/lib/languages/ja.js +22 -75
- package/lib/languages/kn.d.ts +11 -0
- package/lib/languages/kn.js +10 -39
- package/lib/languages/ko.d.ts +14 -0
- package/lib/languages/ko.js +17 -45
- package/lib/languages/lt.d.ts +70 -0
- package/lib/languages/lt.js +28 -63
- package/lib/languages/lv.d.ts +70 -0
- package/lib/languages/lv.js +35 -58
- package/lib/languages/mr.d.ts +11 -0
- package/lib/languages/mr.js +10 -34
- package/lib/languages/ms.d.ts +31 -0
- package/lib/languages/ms.js +24 -20
- package/lib/languages/nb.d.ts +12 -0
- package/lib/languages/nb.js +36 -56
- package/lib/languages/nl.d.ts +16 -0
- package/lib/languages/nl.js +58 -109
- package/lib/languages/pa.d.ts +11 -0
- package/lib/languages/{pa-Guru.js → pa.js} +12 -7
- package/lib/languages/pl.d.ts +80 -0
- package/lib/languages/pl.js +26 -105
- package/lib/languages/pt.d.ts +29 -0
- package/lib/languages/pt.js +29 -64
- package/lib/languages/ro.d.ts +158 -0
- package/lib/languages/ro.js +60 -167
- package/lib/languages/ru.d.ts +85 -0
- package/lib/languages/ru.js +17 -37
- package/lib/languages/sr-Cyrl.d.ts +80 -0
- package/lib/languages/sr-Cyrl.js +113 -0
- package/lib/languages/sr-Latn.d.ts +80 -0
- package/lib/languages/sr-Latn.js +54 -98
- package/lib/languages/sv.d.ts +14 -0
- package/lib/languages/sv.js +26 -63
- package/lib/languages/sw.d.ts +39 -0
- package/lib/languages/sw.js +26 -21
- package/lib/languages/ta.d.ts +20 -0
- package/lib/languages/ta.js +26 -26
- package/lib/languages/te.d.ts +22 -0
- package/lib/languages/te.js +28 -38
- package/lib/languages/th.d.ts +17 -0
- package/lib/languages/th.js +25 -31
- package/lib/languages/tr.d.ts +12 -0
- package/lib/languages/tr.js +11 -38
- package/lib/languages/uk.d.ts +85 -0
- package/lib/languages/uk.js +18 -44
- package/lib/languages/ur.d.ts +11 -0
- package/lib/languages/ur.js +12 -7
- package/lib/languages/vi.d.ts +72 -0
- package/lib/languages/vi.js +25 -71
- package/lib/languages/zh-Hans.d.ts +21 -0
- package/lib/languages/zh-Hans.js +33 -87
- package/lib/languages/zh-Hant.d.ts +21 -0
- package/lib/languages/zh-Hant.js +111 -0
- package/lib/n2words.d.ts +209 -0
- package/lib/n2words.js +474 -191
- package/package.json +106 -67
- package/dist/languages/ar.js +0 -2
- package/dist/languages/ar.js.map +0 -1
- package/dist/languages/az.js +0 -2
- package/dist/languages/az.js.map +0 -1
- package/dist/languages/bn.js +0 -2
- package/dist/languages/bn.js.map +0 -1
- package/dist/languages/cs.js +0 -2
- package/dist/languages/cs.js.map +0 -1
- package/dist/languages/da.js +0 -2
- package/dist/languages/da.js.map +0 -1
- package/dist/languages/de.js +0 -2
- package/dist/languages/de.js.map +0 -1
- package/dist/languages/el.js +0 -2
- package/dist/languages/el.js.map +0 -1
- package/dist/languages/en.js +0 -2
- package/dist/languages/en.js.map +0 -1
- package/dist/languages/es.js +0 -2
- package/dist/languages/es.js.map +0 -1
- package/dist/languages/fa.js +0 -2
- package/dist/languages/fa.js.map +0 -1
- package/dist/languages/fil.js +0 -2
- package/dist/languages/fil.js.map +0 -1
- package/dist/languages/fr-BE.js +0 -2
- package/dist/languages/fr-BE.js.map +0 -1
- package/dist/languages/fr.js +0 -2
- package/dist/languages/fr.js.map +0 -1
- package/dist/languages/gu.js +0 -2
- package/dist/languages/gu.js.map +0 -1
- package/dist/languages/he.js +0 -2
- package/dist/languages/he.js.map +0 -1
- package/dist/languages/hi.js +0 -2
- package/dist/languages/hi.js.map +0 -1
- package/dist/languages/hr.js +0 -2
- package/dist/languages/hr.js.map +0 -1
- package/dist/languages/hu.js +0 -2
- package/dist/languages/hu.js.map +0 -1
- package/dist/languages/id.js +0 -2
- package/dist/languages/id.js.map +0 -1
- package/dist/languages/it.js +0 -2
- package/dist/languages/it.js.map +0 -1
- package/dist/languages/ja.js +0 -2
- package/dist/languages/ja.js.map +0 -1
- package/dist/languages/kn.js +0 -2
- package/dist/languages/kn.js.map +0 -1
- package/dist/languages/ko.js +0 -2
- package/dist/languages/ko.js.map +0 -1
- package/dist/languages/lt.js +0 -2
- package/dist/languages/lt.js.map +0 -1
- package/dist/languages/lv.js +0 -2
- package/dist/languages/lv.js.map +0 -1
- package/dist/languages/mr.js +0 -2
- package/dist/languages/mr.js.map +0 -1
- package/dist/languages/ms.js +0 -2
- package/dist/languages/ms.js.map +0 -1
- package/dist/languages/nb.js +0 -2
- package/dist/languages/nb.js.map +0 -1
- package/dist/languages/nl.js +0 -2
- package/dist/languages/nl.js.map +0 -1
- package/dist/languages/pa-Guru.js +0 -2
- package/dist/languages/pa-Guru.js.map +0 -1
- package/dist/languages/pl.js +0 -2
- package/dist/languages/pl.js.map +0 -1
- package/dist/languages/pt.js +0 -2
- package/dist/languages/pt.js.map +0 -1
- package/dist/languages/ro.js +0 -2
- package/dist/languages/ro.js.map +0 -1
- package/dist/languages/ru.js +0 -2
- package/dist/languages/ru.js.map +0 -1
- package/dist/languages/sr-Latn.js +0 -2
- package/dist/languages/sr-Latn.js.map +0 -1
- package/dist/languages/sv.js +0 -2
- package/dist/languages/sv.js.map +0 -1
- package/dist/languages/sw.js +0 -2
- package/dist/languages/sw.js.map +0 -1
- package/dist/languages/ta.js +0 -2
- package/dist/languages/ta.js.map +0 -1
- package/dist/languages/te.js +0 -2
- package/dist/languages/te.js.map +0 -1
- package/dist/languages/th.js +0 -2
- package/dist/languages/th.js.map +0 -1
- package/dist/languages/tr.js +0 -2
- package/dist/languages/tr.js.map +0 -1
- package/dist/languages/uk.js +0 -2
- package/dist/languages/uk.js.map +0 -1
- package/dist/languages/ur.js +0 -2
- package/dist/languages/ur.js.map +0 -1
- package/dist/languages/vi.js +0 -2
- package/dist/languages/vi.js.map +0 -1
- package/dist/languages/zh-Hans.js +0 -2
- package/dist/languages/zh-Hans.js.map +0 -1
- package/typings/classes/abstract-language.d.ts +0 -144
- package/typings/classes/greedy-scale-language.d.ts +0 -148
- package/typings/classes/slavic-language.d.ts +0 -145
- package/typings/classes/south-asian-language.d.ts +0 -101
- package/typings/classes/turkic-language.d.ts +0 -42
- package/typings/languages/ar.d.ts +0 -93
- package/typings/languages/az.d.ts +0 -25
- package/typings/languages/bn.d.ts +0 -1
- package/typings/languages/cs.d.ts +0 -120
- package/typings/languages/da.d.ts +0 -53
- package/typings/languages/de.d.ts +0 -26
- package/typings/languages/el.d.ts +0 -11
- package/typings/languages/en.d.ts +0 -30
- package/typings/languages/es.d.ts +0 -43
- package/typings/languages/fa.d.ts +0 -81
- package/typings/languages/fil.d.ts +0 -12
- package/typings/languages/fr-BE.d.ts +0 -41
- package/typings/languages/fr.d.ts +0 -43
- package/typings/languages/gu.d.ts +0 -12
- package/typings/languages/he.d.ts +0 -197
- package/typings/languages/hi.d.ts +0 -1
- package/typings/languages/hr.d.ts +0 -110
- package/typings/languages/hu.d.ts +0 -37
- package/typings/languages/id.d.ts +0 -69
- package/typings/languages/it.d.ts +0 -51
- package/typings/languages/ja.d.ts +0 -58
- package/typings/languages/kn.d.ts +0 -11
- package/typings/languages/ko.d.ts +0 -25
- package/typings/languages/lt.d.ts +0 -110
- package/typings/languages/lv.d.ts +0 -99
- package/typings/languages/mr.d.ts +0 -12
- package/typings/languages/ms.d.ts +0 -37
- package/typings/languages/nb.d.ts +0 -27
- package/typings/languages/nl.d.ts +0 -65
- package/typings/languages/pa-Guru.d.ts +0 -1
- package/typings/languages/pl.d.ts +0 -116
- package/typings/languages/pt.d.ts +0 -39
- package/typings/languages/ro.d.ts +0 -229
- package/typings/languages/ru.d.ts +0 -108
- package/typings/languages/sr-Latn.d.ts +0 -98
- package/typings/languages/sv.d.ts +0 -30
- package/typings/languages/sw.d.ts +0 -1
- package/typings/languages/ta.d.ts +0 -1
- package/typings/languages/te.d.ts +0 -1
- package/typings/languages/th.d.ts +0 -1
- package/typings/languages/tr.d.ts +0 -46
- package/typings/languages/uk.d.ts +0 -117
- package/typings/languages/ur.d.ts +0 -1
- package/typings/languages/vi.d.ts +0 -116
- package/typings/languages/zh-Hans.d.ts +0 -57
- package/typings/n2words.d.ts +0 -177
package/lib/languages/vi.js
CHANGED
|
@@ -1,37 +1,19 @@
|
|
|
1
|
-
import AbstractLanguage from '../classes/abstract-language.js'
|
|
1
|
+
import { AbstractLanguage } from '../classes/abstract-language.js'
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Vietnamese language converter.
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
* -
|
|
8
|
-
* -
|
|
9
|
-
* -
|
|
10
|
-
* - "Lẻ" (odd/extra) used when tens place is zero but units exist
|
|
11
|
-
*
|
|
12
|
-
* Key Features:
|
|
13
|
-
* - Base number mapping for 0-19 (with special forms)
|
|
14
|
-
* - Tens mapping (hai mươi, ba mươi, etc.)
|
|
15
|
-
* - Group-based algorithm:
|
|
16
|
-
* 1. Split number into groups of 3 digits
|
|
17
|
-
* 2. For each group, build words using special pronunciation rules:
|
|
18
|
-
* - "Mốt" instead of "một" for final 1 (e.g., 21 → hai mươi mốt)
|
|
19
|
-
* - "Lăm" instead of "năm" for 15 and mid-group 5 (e.g., 15, 105)
|
|
20
|
-
* - "Lẻ" prefix when tens=0 but units>0 (e.g., 101 → một trăm lẻ một)
|
|
21
|
-
* 3. Append magnitude word (nghìn/triệu/tỷ)
|
|
22
|
-
* 4. Join all groups with spaces
|
|
23
|
-
* - Support for large numbers up to vigintillions
|
|
24
|
-
*
|
|
25
|
-
* Features:
|
|
26
|
-
* - Natural Vietnamese number flow
|
|
27
|
-
* - Proper handling of special cases (mốt, lăm)
|
|
28
|
-
* - Contextual pronunciation adjustments
|
|
6
|
+
* Supports:
|
|
7
|
+
* - Special pronunciation rules (lăm for 5, mốt for final 1)
|
|
8
|
+
* - "Lẻ" (odd/extra) when tens place is zero
|
|
9
|
+
* - Vietnamese diacritical marks
|
|
29
10
|
*/
|
|
30
11
|
export class Vietnamese extends AbstractLanguage {
|
|
31
12
|
negativeWord = 'âm'
|
|
32
13
|
decimalSeparatorWord = 'phẩy'
|
|
33
14
|
zeroWord = 'không'
|
|
34
|
-
|
|
15
|
+
|
|
16
|
+
belowTwentyWords = {
|
|
35
17
|
0: 'không',
|
|
36
18
|
1: 'một',
|
|
37
19
|
2: 'hai',
|
|
@@ -54,7 +36,7 @@ export class Vietnamese extends AbstractLanguage {
|
|
|
54
36
|
19: 'mười chín'
|
|
55
37
|
}
|
|
56
38
|
|
|
57
|
-
|
|
39
|
+
twentiesWords = {
|
|
58
40
|
20: 'hai mươi',
|
|
59
41
|
30: 'ba mươi',
|
|
60
42
|
40: 'bốn mươi',
|
|
@@ -65,7 +47,7 @@ export class Vietnamese extends AbstractLanguage {
|
|
|
65
47
|
90: 'chín mươi'
|
|
66
48
|
}
|
|
67
49
|
|
|
68
|
-
|
|
50
|
+
scaleWords = {
|
|
69
51
|
1: 'nghìn', // 10^1
|
|
70
52
|
2: 'triệu', // 10^2
|
|
71
53
|
3: 'tỷ', // 10^3
|
|
@@ -88,20 +70,15 @@ export class Vietnamese extends AbstractLanguage {
|
|
|
88
70
|
20: 'Vigintillion'
|
|
89
71
|
}
|
|
90
72
|
|
|
91
|
-
/**
|
|
92
|
-
* Convert numbers less than 100 to Vietnamese words.
|
|
93
|
-
*
|
|
94
|
-
* @param {number} number The number to convert (0-99).
|
|
95
|
-
* @returns {string} The Vietnamese representation.
|
|
96
|
-
*/
|
|
73
|
+
/** Convert numbers less than 100 to Vietnamese words. */
|
|
97
74
|
convertLess100 (number) {
|
|
98
75
|
const unitsPart = number % 10
|
|
99
76
|
const tensPart = number - unitsPart
|
|
100
|
-
const tensPartText = this.
|
|
77
|
+
const tensPartText = this.twentiesWords[tensPart]
|
|
101
78
|
if (unitsPart === 0) {
|
|
102
79
|
return tensPartText
|
|
103
80
|
}
|
|
104
|
-
const unitsPartText = this.
|
|
81
|
+
const unitsPartText = this.belowTwentyWords[unitsPart]
|
|
105
82
|
let suffix = unitsPartText
|
|
106
83
|
if (unitsPart === 1) {
|
|
107
84
|
suffix = 'mốt'
|
|
@@ -112,18 +89,13 @@ export class Vietnamese extends AbstractLanguage {
|
|
|
112
89
|
return tensPartText + ' ' + suffix
|
|
113
90
|
}
|
|
114
91
|
|
|
115
|
-
/**
|
|
116
|
-
* Convert numbers less than 1000 to Vietnamese words.
|
|
117
|
-
*
|
|
118
|
-
* @param {number} number The number to convert (0-999).
|
|
119
|
-
* @returns {string} The Vietnamese representation.
|
|
120
|
-
*/
|
|
92
|
+
/** Convert numbers less than 1000 to Vietnamese words. */
|
|
121
93
|
convertLess1000 (number) {
|
|
122
94
|
const words = []
|
|
123
95
|
const tensUnitsPart = number % 100
|
|
124
96
|
const hundredsPart = number - tensUnitsPart
|
|
125
97
|
if (hundredsPart > 0) {
|
|
126
|
-
words.push(this.
|
|
98
|
+
words.push(this.belowTwentyWords[hundredsPart / 100], 'trăm')
|
|
127
99
|
}
|
|
128
100
|
if (tensUnitsPart > 0 && tensUnitsPart < 10) {
|
|
129
101
|
if (words.length > 0) {
|
|
@@ -132,21 +104,16 @@ export class Vietnamese extends AbstractLanguage {
|
|
|
132
104
|
if (tensUnitsPart === 5) {
|
|
133
105
|
words.push('năm')
|
|
134
106
|
} else {
|
|
135
|
-
words.push(this.
|
|
107
|
+
words.push(this.belowTwentyWords[tensUnitsPart])
|
|
136
108
|
}
|
|
137
109
|
}
|
|
138
110
|
if (tensUnitsPart >= 10) {
|
|
139
|
-
words.push(this.
|
|
111
|
+
words.push(this.integerToWords(tensUnitsPart))
|
|
140
112
|
}
|
|
141
113
|
return words.join(' ')
|
|
142
114
|
}
|
|
143
115
|
|
|
144
|
-
/**
|
|
145
|
-
* Convert numbers greater than 1000 to Vietnamese words.
|
|
146
|
-
*
|
|
147
|
-
* @param {bigint} number The number to convert (>= 1000).
|
|
148
|
-
* @returns {string} The Vietnamese representation.
|
|
149
|
-
*/
|
|
116
|
+
/** Convert numbers greater than 1000 to Vietnamese words. */
|
|
150
117
|
convertMore1000 (number) {
|
|
151
118
|
const words = []
|
|
152
119
|
let division = number / 1000n
|
|
@@ -156,38 +123,25 @@ export class Vietnamese extends AbstractLanguage {
|
|
|
156
123
|
power = power + 1
|
|
157
124
|
}
|
|
158
125
|
const r = number - (division * BigInt(Math.pow(1000, power)))
|
|
159
|
-
words.push(this.
|
|
126
|
+
words.push(this.integerToWords(division), this.scaleWords[power])
|
|
160
127
|
if (r > 0n) {
|
|
161
128
|
if (r <= 99n) {
|
|
162
129
|
words.push('lẻ')
|
|
163
130
|
}
|
|
164
|
-
words.push(this.
|
|
131
|
+
words.push(this.integerToWords(r))
|
|
165
132
|
}
|
|
166
133
|
return words.join(' ')
|
|
167
134
|
}
|
|
168
135
|
|
|
169
|
-
|
|
170
|
-
if (
|
|
171
|
-
return this.
|
|
136
|
+
integerToWords (integerPart) {
|
|
137
|
+
if (integerPart < 20n) {
|
|
138
|
+
return this.belowTwentyWords[Number(integerPart)]
|
|
172
139
|
} else {
|
|
173
|
-
if (
|
|
174
|
-
return this.convertLess100(Number(
|
|
140
|
+
if (integerPart < 100n) {
|
|
141
|
+
return this.convertLess100(Number(integerPart))
|
|
175
142
|
} else {
|
|
176
|
-
return (
|
|
143
|
+
return (integerPart < 1000n ? this.convertLess1000(Number(integerPart)) : this.convertMore1000(integerPart))
|
|
177
144
|
}
|
|
178
145
|
}
|
|
179
146
|
}
|
|
180
147
|
}
|
|
181
|
-
|
|
182
|
-
/**
|
|
183
|
-
* Converts a number to Vietnamese cardinal (written) form.
|
|
184
|
-
*
|
|
185
|
-
* @param {number|string|bigint} value The number to convert.
|
|
186
|
-
* @param {Object} [options={}] Configuration options.
|
|
187
|
-
* @returns {string} The number expressed in Vietnamese words.
|
|
188
|
-
* @throws {TypeError} If value is NaN or invalid type.
|
|
189
|
-
* @throws {Error} If value is an invalid number string.
|
|
190
|
-
*/
|
|
191
|
-
export default function convertToWords (value, options = {}) {
|
|
192
|
-
return new Vietnamese(options).convertToWords(value)
|
|
193
|
-
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Simplified Chinese language converter.
|
|
3
|
+
*
|
|
4
|
+
* Supports:
|
|
5
|
+
* - Simplified Chinese characters (简体中文)
|
|
6
|
+
* - No word separators (concatenated format)
|
|
7
|
+
* - Optional formal (financial) vs common numerals
|
|
8
|
+
*/
|
|
9
|
+
export class SimplifiedChinese extends GreedyScaleLanguage {
|
|
10
|
+
constructor(options?: {});
|
|
11
|
+
scaleWords: (string | bigint)[][];
|
|
12
|
+
/** Combines two word-sets according to Chinese grammar rules. */
|
|
13
|
+
combineWordSets(preceding: any, following: any): any;
|
|
14
|
+
/** Returns the number of digits in a number. */
|
|
15
|
+
digit(number_: any): any;
|
|
16
|
+
/** Counts the number of zero digits in a number. */
|
|
17
|
+
zeroDigit(number_: any): number;
|
|
18
|
+
/** Converts decimal digits to words by reading each digit individually. */
|
|
19
|
+
decimalDigitsToWords(decimalString: any): string[];
|
|
20
|
+
}
|
|
21
|
+
import { GreedyScaleLanguage } from '../classes/greedy-scale-language.js';
|
package/lib/languages/zh-Hans.js
CHANGED
|
@@ -1,37 +1,28 @@
|
|
|
1
|
-
import GreedyScaleLanguage from '../classes/greedy-scale-language.js'
|
|
1
|
+
import { GreedyScaleLanguage } from '../classes/greedy-scale-language.js'
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
5
|
-
* @property {boolean} [formal=true] Use formal/financial numerals (壹贰叁) vs. common numerals (一二三).
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Chinese language converter.
|
|
4
|
+
* Simplified Chinese language converter.
|
|
10
5
|
*
|
|
11
|
-
*
|
|
12
|
-
* -
|
|
13
|
-
* -
|
|
14
|
-
* -
|
|
15
|
-
* - Supports both formal (financial) and common (everyday) styles
|
|
6
|
+
* Supports:
|
|
7
|
+
* - Simplified Chinese characters (简体中文)
|
|
8
|
+
* - No word separators (concatenated format)
|
|
9
|
+
* - Optional formal (financial) vs common numerals
|
|
16
10
|
*/
|
|
17
|
-
export class
|
|
11
|
+
export class SimplifiedChinese extends GreedyScaleLanguage {
|
|
18
12
|
negativeWord = '负'
|
|
19
13
|
decimalSeparatorWord = '点'
|
|
20
14
|
zeroWord = '零'
|
|
21
15
|
wordSeparator = ''
|
|
22
16
|
|
|
23
|
-
|
|
24
|
-
* Initializes the Chinese converter.
|
|
25
|
-
*
|
|
26
|
-
* @param {ChineseOptions} [options={}] Configuration options.
|
|
27
|
-
*/
|
|
28
|
-
constructor ({ formal = true } = {}) {
|
|
17
|
+
constructor (options = {}) {
|
|
29
18
|
super()
|
|
30
19
|
|
|
31
|
-
this.
|
|
20
|
+
this.setOptions({
|
|
21
|
+
formal: true
|
|
22
|
+
}, options)
|
|
32
23
|
|
|
33
|
-
if (this.formal) {
|
|
34
|
-
this.
|
|
24
|
+
if (this.options.formal) {
|
|
25
|
+
this.scaleWords = [
|
|
35
26
|
[1_000_000_000_000n, '万'],
|
|
36
27
|
[100_000_000n, '亿'],
|
|
37
28
|
[10_000n, '万'],
|
|
@@ -50,7 +41,7 @@ export class Chinese extends GreedyScaleLanguage {
|
|
|
50
41
|
[0n, '零']
|
|
51
42
|
]
|
|
52
43
|
} else {
|
|
53
|
-
this.
|
|
44
|
+
this.scaleWords = [
|
|
54
45
|
[1_000_000_000_000n, '万'],
|
|
55
46
|
[100_000_000n, '亿'],
|
|
56
47
|
[10_000n, '万'],
|
|
@@ -71,95 +62,50 @@ export class Chinese extends GreedyScaleLanguage {
|
|
|
71
62
|
}
|
|
72
63
|
}
|
|
73
64
|
|
|
74
|
-
/**
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
* - Inserts '零' (zero) when positional values skip magnitude levels
|
|
81
|
-
* - Multiplies when right > left, adds otherwise
|
|
82
|
-
*
|
|
83
|
-
* @param {Object} leftPair The left operand as `{ word: number }`.
|
|
84
|
-
* @param {Object} rightPair The right operand as `{ word: number }`.
|
|
85
|
-
* @returns {Object} Merged pair with combined word and resulting number.
|
|
86
|
-
*/
|
|
87
|
-
mergeScales (leftPair, rightPair) {
|
|
88
|
-
const leftWord = Object.keys(leftPair)[0]
|
|
89
|
-
const leftNumber = Object.values(leftPair)[0]
|
|
90
|
-
const rightWord = Object.keys(rightPair)[0]
|
|
91
|
-
const rightNumber = Object.values(rightPair)[0]
|
|
65
|
+
/** Combines two word-sets according to Chinese grammar rules. */
|
|
66
|
+
combineWordSets (preceding, following) {
|
|
67
|
+
const precedingWord = Object.keys(preceding)[0]
|
|
68
|
+
const precedingValue = Object.values(preceding)[0]
|
|
69
|
+
const followingWord = Object.keys(following)[0]
|
|
70
|
+
const followingValue = Object.values(following)[0]
|
|
92
71
|
|
|
93
72
|
// Implicit one: omit 1 before single digits (< 10)
|
|
94
|
-
if (
|
|
95
|
-
return
|
|
73
|
+
if (precedingValue === 1n && followingValue < 10n) {
|
|
74
|
+
return following
|
|
96
75
|
}
|
|
97
76
|
|
|
98
|
-
// Multiply when
|
|
99
|
-
if (
|
|
100
|
-
return { [`${
|
|
77
|
+
// Multiply when following > preceding (scale words like 仁, 万, 亿)
|
|
78
|
+
if (followingValue > precedingValue) {
|
|
79
|
+
return { [`${precedingWord}${followingWord}`]: precedingValue * followingValue }
|
|
101
80
|
}
|
|
102
81
|
|
|
103
82
|
// Insert "零" (zero) when position skip levels (e.g., 1003 = 千零三)
|
|
104
|
-
// zeroDigit() checks if gap exists between
|
|
105
|
-
if (this.zeroDigit(
|
|
106
|
-
return { [`${
|
|
83
|
+
// zeroDigit() checks if gap exists between preceding and following magnitude
|
|
84
|
+
if (this.zeroDigit(precedingValue) > this.digit(followingValue)) {
|
|
85
|
+
return { [`${precedingWord}${this.zeroWord}${followingWord}`]: precedingValue + followingValue }
|
|
107
86
|
}
|
|
108
87
|
|
|
109
88
|
// Default: concatenate without zero insertion
|
|
110
|
-
return { [`${
|
|
89
|
+
return { [`${precedingWord}${followingWord}`]: precedingValue + followingValue }
|
|
111
90
|
}
|
|
112
91
|
|
|
113
|
-
/**
|
|
114
|
-
* Get the number of digits in a number.
|
|
115
|
-
*
|
|
116
|
-
* @param {bigint|number} number_ The number to count digits for.
|
|
117
|
-
* @returns {number} The count of digits.
|
|
118
|
-
*/
|
|
92
|
+
/** Returns the number of digits in a number. */
|
|
119
93
|
digit (number_) {
|
|
120
94
|
return number_.toString().length
|
|
121
95
|
}
|
|
122
96
|
|
|
123
|
-
/**
|
|
124
|
-
* Count the number of zeros in a number.
|
|
125
|
-
*
|
|
126
|
-
* @param {bigint|number} number_ The number to count zeros in.
|
|
127
|
-
* @returns {number} The count of zero digits.
|
|
128
|
-
*/
|
|
97
|
+
/** Counts the number of zero digits in a number. */
|
|
129
98
|
zeroDigit (number_) {
|
|
130
99
|
return [...number_.toString()].filter(c => c === '0').length
|
|
131
100
|
}
|
|
132
101
|
|
|
133
|
-
/**
|
|
134
|
-
* Convert decimal digits to words by reading each digit individually.
|
|
135
|
-
* Overrides the default grouped behavior from AbstractLanguage.
|
|
136
|
-
*
|
|
137
|
-
* @param {string} decimalString The decimal digits as a string.
|
|
138
|
-
* @returns {Array<string>} Array of individual digit words.
|
|
139
|
-
*/
|
|
102
|
+
/** Converts decimal digits to words by reading each digit individually. */
|
|
140
103
|
decimalDigitsToWords (decimalString) {
|
|
141
104
|
const words = []
|
|
142
105
|
for (let i = 0; i < decimalString.length; i++) {
|
|
143
106
|
const digitValue = BigInt(decimalString[i])
|
|
144
|
-
words.push(this.
|
|
107
|
+
words.push(this.integerToWords(digitValue))
|
|
145
108
|
}
|
|
146
109
|
return words
|
|
147
110
|
}
|
|
148
111
|
}
|
|
149
|
-
|
|
150
|
-
/**
|
|
151
|
-
* Converts a number to Chinese cardinal (written) form.
|
|
152
|
-
*
|
|
153
|
-
* @param {number|string|bigint} value The number to convert.
|
|
154
|
-
* @param {ChineseOptions} [options] Conversion options.
|
|
155
|
-
* @returns {string} The number expressed in Chinese words.
|
|
156
|
-
* @throws {TypeError} If value is NaN or invalid type.
|
|
157
|
-
* @throws {Error} If value is an invalid number string.
|
|
158
|
-
*
|
|
159
|
-
* @example
|
|
160
|
-
* convertToWords(42); // '肆拾贰' (formal style)
|
|
161
|
-
* convertToWords(42, { formal: false }); // '四十二' (common style)
|
|
162
|
-
*/
|
|
163
|
-
export default function convertToWords (value, options = {}) {
|
|
164
|
-
return new Chinese(options).convertToWords(value)
|
|
165
|
-
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Traditional Chinese language converter.
|
|
3
|
+
*
|
|
4
|
+
* Supports:
|
|
5
|
+
* - Traditional Chinese characters (繁體中文)
|
|
6
|
+
* - No word separators (concatenated format)
|
|
7
|
+
* - Optional formal (financial) vs common numerals
|
|
8
|
+
*/
|
|
9
|
+
export class TraditionalChinese extends GreedyScaleLanguage {
|
|
10
|
+
constructor(options?: {});
|
|
11
|
+
scaleWords: (string | bigint)[][];
|
|
12
|
+
/** Combines two word-sets with Traditional Chinese grammar rules and zero insertion. */
|
|
13
|
+
combineWordSets(preceding: any, following: any): any;
|
|
14
|
+
/** Returns the number of digits in a number. */
|
|
15
|
+
digit(number_: any): any;
|
|
16
|
+
/** Counts the number of zero digits in a number. */
|
|
17
|
+
zeroDigit(number_: any): number;
|
|
18
|
+
/** Converts decimal digits to words by reading each digit individually. */
|
|
19
|
+
decimalDigitsToWords(decimalString: any): string[];
|
|
20
|
+
}
|
|
21
|
+
import { GreedyScaleLanguage } from '../classes/greedy-scale-language.js';
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { GreedyScaleLanguage } from '../classes/greedy-scale-language.js'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Traditional Chinese language converter.
|
|
5
|
+
*
|
|
6
|
+
* Supports:
|
|
7
|
+
* - Traditional Chinese characters (繁體中文)
|
|
8
|
+
* - No word separators (concatenated format)
|
|
9
|
+
* - Optional formal (financial) vs common numerals
|
|
10
|
+
*/
|
|
11
|
+
export class TraditionalChinese extends GreedyScaleLanguage {
|
|
12
|
+
negativeWord = '負'
|
|
13
|
+
decimalSeparatorWord = '點'
|
|
14
|
+
zeroWord = '零'
|
|
15
|
+
wordSeparator = ''
|
|
16
|
+
|
|
17
|
+
constructor (options = {}) {
|
|
18
|
+
super()
|
|
19
|
+
|
|
20
|
+
this.setOptions({
|
|
21
|
+
formal: true
|
|
22
|
+
}, options)
|
|
23
|
+
|
|
24
|
+
if (this.options.formal) {
|
|
25
|
+
this.scaleWords = [
|
|
26
|
+
[1_000_000_000_000n, '萬'],
|
|
27
|
+
[100_000_000n, '億'],
|
|
28
|
+
[10_000n, '萬'],
|
|
29
|
+
[1000n, '仟'],
|
|
30
|
+
[100n, '佰'],
|
|
31
|
+
[10n, '拾'],
|
|
32
|
+
[9n, '玖'],
|
|
33
|
+
[8n, '捌'],
|
|
34
|
+
[7n, '柒'],
|
|
35
|
+
[6n, '陸'],
|
|
36
|
+
[5n, '伍'],
|
|
37
|
+
[4n, '肆'],
|
|
38
|
+
[3n, '參'],
|
|
39
|
+
[2n, '貳'],
|
|
40
|
+
[1n, '壹'],
|
|
41
|
+
[0n, '零']
|
|
42
|
+
]
|
|
43
|
+
} else {
|
|
44
|
+
this.scaleWords = [
|
|
45
|
+
[1_000_000_000_000n, '萬'],
|
|
46
|
+
[100_000_000n, '億'],
|
|
47
|
+
[10_000n, '萬'],
|
|
48
|
+
[1000n, '千'],
|
|
49
|
+
[100n, '百'],
|
|
50
|
+
[10n, '十'],
|
|
51
|
+
[9n, '九'],
|
|
52
|
+
[8n, '八'],
|
|
53
|
+
[7n, '七'],
|
|
54
|
+
[6n, '六'],
|
|
55
|
+
[5n, '五'],
|
|
56
|
+
[4n, '四'],
|
|
57
|
+
[3n, '三'],
|
|
58
|
+
[2n, '二'],
|
|
59
|
+
[1n, '一'],
|
|
60
|
+
[0n, '零']
|
|
61
|
+
]
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/** Combines two word-sets with Traditional Chinese grammar rules and zero insertion. */
|
|
66
|
+
combineWordSets (preceding, following) {
|
|
67
|
+
const precedingWord = Object.keys(preceding)[0]
|
|
68
|
+
const precedingValue = Object.values(preceding)[0]
|
|
69
|
+
const followingWord = Object.keys(following)[0]
|
|
70
|
+
const followingValue = Object.values(following)[0]
|
|
71
|
+
|
|
72
|
+
// Implicit one: omit 1 before single digits (< 10)
|
|
73
|
+
if (precedingValue === 1n && followingValue < 10n) {
|
|
74
|
+
return following
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Multiply when following > preceding (scale words like 千, 萬, 億)
|
|
78
|
+
if (followingValue > precedingValue) {
|
|
79
|
+
return { [`${precedingWord}${followingWord}`]: precedingValue * followingValue }
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Insert "零" (zero) when position skip levels (e.g., 1003 = 千零三)
|
|
83
|
+
// zeroDigit() checks if gap exists between preceding and following magnitude
|
|
84
|
+
if (this.zeroDigit(precedingValue) > this.digit(followingValue)) {
|
|
85
|
+
return { [`${precedingWord}${this.zeroWord}${followingWord}`]: precedingValue + followingValue }
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Default: concatenate without zero insertion
|
|
89
|
+
return { [`${precedingWord}${followingWord}`]: precedingValue + followingValue }
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/** Returns the number of digits in a number. */
|
|
93
|
+
digit (number_) {
|
|
94
|
+
return number_.toString().length
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/** Counts the number of zero digits in a number. */
|
|
98
|
+
zeroDigit (number_) {
|
|
99
|
+
return [...number_.toString()].filter(c => c === '0').length
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/** Converts decimal digits to words by reading each digit individually. */
|
|
103
|
+
decimalDigitsToWords (decimalString) {
|
|
104
|
+
const words = []
|
|
105
|
+
for (let i = 0; i < decimalString.length; i++) {
|
|
106
|
+
const digitValue = BigInt(decimalString[i])
|
|
107
|
+
words.push(this.integerToWords(digitValue))
|
|
108
|
+
}
|
|
109
|
+
return words
|
|
110
|
+
}
|
|
111
|
+
}
|